aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--addons/audioencoder.kodi.builtin.aac/addon.xml6
-rw-r--r--addons/audioencoder.kodi.builtin.aac/resources/language/resource.language.be_by/strings.po12
-rw-r--r--addons/audioencoder.kodi.builtin.wma/addon.xml2
-rw-r--r--addons/resource.language.en_gb/resources/strings.po17
-rw-r--r--addons/screensaver.xbmc.builtin.dim/addon.xml14
-rw-r--r--addons/skin.estouchy/addon.xml2
-rw-r--r--addons/skin.estouchy/language/resource.language.es_es/strings.po4
-rw-r--r--addons/skin.estouchy/media/flagging/aspectratio/1.00.pngbin0 -> 1076 bytes
-rw-r--r--addons/skin.estouchy/media/flagging/aspectratio/1.19.pngbin0 -> 1049 bytes
-rw-r--r--addons/skin.estouchy/media/flagging/aspectratio/2.00.pngbin0 -> 1205 bytes
-rw-r--r--addons/skin.estuary/addon.xml24
-rw-r--r--addons/skin.estuary/language/resource.language.es_es/strings.po8
-rw-r--r--addons/skin.estuary/media/flags/aspectratio/1.00.pngbin0 -> 1076 bytes
-rw-r--r--addons/skin.estuary/media/flags/aspectratio/1.19.pngbin0 -> 1049 bytes
-rw-r--r--addons/skin.estuary/media/flags/aspectratio/2.00.pngbin0 -> 1205 bytes
-rw-r--r--addons/skin.estuary/xml/Home.xml16
-rw-r--r--cmake/modules/FindCrossGUID.cmake3
-rw-r--r--cmake/modules/FindDav1d.cmake5
-rw-r--r--cmake/modules/FindFFMPEG.cmake5
-rw-r--r--cmake/modules/FindFlatBuffers.cmake3
-rw-r--r--cmake/modules/FindFmt.cmake3
-rw-r--r--cmake/modules/FindFstrcmp.cmake3
-rw-r--r--cmake/modules/FindGtest.cmake3
-rw-r--r--cmake/modules/FindLibDvd.cmake107
-rw-r--r--cmake/modules/FindRapidJSON.cmake3
-rw-r--r--cmake/modules/FindSpdlog.cmake3
-rw-r--r--cmake/modules/FindUdfread.cmake5
-rw-r--r--cmake/scripts/common/ModuleHelpers.cmake13
-rw-r--r--project/BuildDependencies/scripts/0_package.target-win10-arm.list2
-rw-r--r--project/BuildDependencies/scripts/0_package.target-win10-win32.list2
-rw-r--r--project/BuildDependencies/scripts/0_package.target-win10-x64.list2
-rw-r--r--project/BuildDependencies/scripts/0_package.target-win32.list2
-rw-r--r--project/BuildDependencies/scripts/0_package.target-x64.list2
-rw-r--r--system/settings/linux.xml12
-rw-r--r--tools/android/packaging/xbmc/res/values-be-rby/strings.xml3
-rw-r--r--tools/buildsteps/windows/patches/0001-ffmpeg-windows-configure-detect-openssl.patch2
-rw-r--r--tools/buildsteps/windows/patches/0003-ffmpeg-windows-configure-allow-building-static.patch4
-rw-r--r--tools/buildsteps/windows/patches/0004-ffmpeg-windows-configure-detect-libdav1d.patch2
-rw-r--r--tools/depends/README.md4
-rw-r--r--tools/depends/configure.ac4
-rw-r--r--tools/depends/target/Toolchain_binaddons.cmake.in4
-rw-r--r--tools/depends/target/crossguid/CROSSGUID-VERSION1
-rw-r--r--tools/depends/target/dav1d/DAV1D-VERSION1
-rw-r--r--tools/depends/target/ffmpeg/FFMPEG-VERSION3
-rw-r--r--tools/depends/target/flatbuffers/FLATBUFFERS-VERSION1
-rw-r--r--tools/depends/target/googletest/GOOGLETEST-VERSION1
-rw-r--r--tools/depends/target/libdvdcss/DVDCSS-VERSION4
-rw-r--r--tools/depends/target/libdvdcss/LIBDVDCSS-VERSION5
-rw-r--r--tools/depends/target/libdvdcss/Makefile4
-rw-r--r--tools/depends/target/libdvdnav/DVDNAV-VERSION4
-rw-r--r--tools/depends/target/libdvdnav/LIBDVDNAV-VERSION5
-rw-r--r--tools/depends/target/libdvdnav/Makefile4
-rw-r--r--tools/depends/target/libdvdread/DVDREAD-VERSION4
-rw-r--r--tools/depends/target/libdvdread/LIBDVDREAD-VERSION5
-rw-r--r--tools/depends/target/libdvdread/Makefile4
-rw-r--r--tools/depends/target/libfmt/LIBFMT-VERSION1
-rw-r--r--tools/depends/target/libfstrcmp/LIBFSTRCMP-VERSION1
-rw-r--r--tools/depends/target/libspdlog/LIBSPDLOG-VERSION1
-rw-r--r--tools/depends/target/libudfread/LIBUDFREAD-VERSION1
-rw-r--r--tools/depends/target/rapidjson/RAPIDJSON-VERSION1
-rw-r--r--xbmc/Application.cpp26
-rw-r--r--xbmc/Autorun.cpp7
-rw-r--r--xbmc/ContextMenuItem.cpp2
-rw-r--r--xbmc/ContextMenuManager.cpp2
-rw-r--r--xbmc/GUIInfoManager.cpp3
-rw-r--r--xbmc/LangInfo.cpp7
-rw-r--r--xbmc/addons/AddonInstaller.cpp78
-rw-r--r--xbmc/addons/AddonInstaller.h34
-rw-r--r--xbmc/addons/AddonManager.cpp60
-rw-r--r--xbmc/addons/AddonManager.h16
-rw-r--r--xbmc/addons/AddonRepos.cpp11
-rw-r--r--xbmc/addons/AddonRepos.h8
-rw-r--r--xbmc/addons/AddonStatusHandler.cpp3
-rw-r--r--xbmc/addons/AddonSystemSettings.cpp10
-rw-r--r--xbmc/addons/ContextMenus.cpp6
-rw-r--r--xbmc/addons/FontResource.cpp2
-rw-r--r--xbmc/addons/LanguageResource.cpp8
-rw-r--r--xbmc/addons/Scraper.cpp2
-rw-r--r--xbmc/addons/Service.cpp2
-rw-r--r--xbmc/addons/Skin.cpp3
-rw-r--r--xbmc/addons/addoninfo/AddonInfo.cpp2
-rw-r--r--xbmc/addons/gui/GUIDialogAddonInfo.cpp35
-rw-r--r--xbmc/addons/gui/GUIDialogAddonInfo.h14
-rw-r--r--xbmc/addons/gui/GUIWindowAddonBrowser.cpp16
-rw-r--r--xbmc/addons/interfaces/AddonBase.cpp2
-rw-r--r--xbmc/addons/interfaces/General.cpp2
-rw-r--r--xbmc/addons/interfaces/gui/dialogs/YesNo.cpp10
-rw-r--r--xbmc/cdrip/EncoderFFmpeg.cpp2
-rw-r--r--xbmc/cores/AudioEngine/Sinks/AESinkAUDIOTRACK.cpp66
-rw-r--r--xbmc/cores/RetroPlayer/RetroPlayer.cpp6
-rw-r--r--xbmc/cores/VideoPlayer/DVDCodecs/Video/DVDVideoCodecFFmpeg.cpp14
-rw-r--r--xbmc/cores/VideoPlayer/DVDCodecs/Video/DXVA.cpp15
-rw-r--r--xbmc/cores/VideoPlayer/DVDCodecs/Video/VAAPI.cpp47
-rw-r--r--xbmc/cores/VideoPlayer/DVDCodecs/Video/VAAPI.h1
-rw-r--r--xbmc/cores/VideoPlayer/DVDDemuxers/DVDDemux.h1
-rw-r--r--xbmc/cores/VideoPlayer/DVDDemuxers/DVDDemuxClient.cpp2
-rw-r--r--xbmc/cores/VideoPlayer/DVDDemuxers/DVDDemuxFFmpeg.cpp10
-rw-r--r--xbmc/cores/VideoPlayer/DVDStreamInfo.cpp39
-rw-r--r--xbmc/cores/VideoPlayer/DVDStreamInfo.h1
-rw-r--r--xbmc/cores/VideoPlayer/VideoPlayerVideo.cpp5
-rw-r--r--xbmc/dbwrappers/Database.cpp2
-rw-r--r--xbmc/dbwrappers/Database.h2
-rw-r--r--xbmc/filesystem/AddonsDirectory.cpp6
-rw-r--r--xbmc/filesystem/PluginDirectory.cpp12
-rw-r--r--xbmc/filesystem/ResourceFile.cpp3
-rw-r--r--xbmc/filesystem/StackDirectory.cpp10
-rw-r--r--xbmc/games/addons/GameClient.cpp2
-rw-r--r--xbmc/games/addons/GameClientProperties.cpp4
-rw-r--r--xbmc/games/controllers/ControllerManager.cpp2
-rw-r--r--xbmc/games/controllers/windows/ControllerInstaller.cpp2
-rw-r--r--xbmc/games/controllers/windows/GUIControllerWindow.cpp3
-rw-r--r--xbmc/games/controllers/windows/GUIPortWindow.cpp3
-rw-r--r--xbmc/games/dialogs/GUIDialogSelectGameClient.cpp2
-rw-r--r--xbmc/games/dialogs/osd/DialogGameAdvancedSettings.cpp3
-rw-r--r--xbmc/guilib/GUIAudioManager.cpp2
-rw-r--r--xbmc/guilib/GUIBaseContainer.cpp62
-rw-r--r--xbmc/guilib/GUIBaseContainer.h11
-rw-r--r--xbmc/guilib/GUIButtonControl.cpp2
-rw-r--r--xbmc/guilib/GUIControlFactory.cpp3
-rw-r--r--xbmc/guilib/GUIControlGroup.h2
-rw-r--r--xbmc/guilib/GUIControlLookup.cpp4
-rw-r--r--xbmc/guilib/GUIControlLookup.h3
-rw-r--r--xbmc/guilib/GUIDialog.cpp11
-rw-r--r--xbmc/guilib/GUIListContainer.cpp4
-rw-r--r--xbmc/guilib/GUIListContainer.h5
-rw-r--r--xbmc/guilib/GUIListGroup.h2
-rw-r--r--xbmc/guilib/GUIListItem.h2
-rw-r--r--xbmc/guilib/GUIListItemLayout.cpp21
-rw-r--r--xbmc/guilib/GUIListItemLayout.h5
-rw-r--r--xbmc/guilib/GUIStaticItem.cpp9
-rw-r--r--xbmc/guilib/GUIStaticItem.h1
-rw-r--r--xbmc/guilib/guiinfo/AddonsGUIInfo.cpp4
-rw-r--r--xbmc/guilib/guiinfo/VisualisationGUIInfo.cpp2
-rw-r--r--xbmc/input/joysticks/dialogs/GUIDialogNewJoystick.cpp2
-rw-r--r--xbmc/interfaces/builtins/AddonBuiltins.cpp39
-rw-r--r--xbmc/interfaces/builtins/LibraryBuiltins.cpp18
-rw-r--r--xbmc/interfaces/json-rpc/AddonsOperations.cpp8
-rw-r--r--xbmc/interfaces/json-rpc/GUIOperations.cpp2
-rw-r--r--xbmc/interfaces/legacy/Addon.cpp2
-rw-r--r--xbmc/interfaces/legacy/Control.cpp4
-rw-r--r--xbmc/interfaces/legacy/Settings.h2
-rw-r--r--xbmc/interfaces/python/PythonInvoker.cpp2
-rw-r--r--xbmc/listproviders/DirectoryProvider.cpp22
-rw-r--r--xbmc/listproviders/DirectoryProvider.h3
-rw-r--r--xbmc/listproviders/IListProvider.cpp14
-rw-r--r--xbmc/listproviders/IListProvider.h13
-rw-r--r--xbmc/listproviders/MultiProvider.cpp19
-rw-r--r--xbmc/listproviders/MultiProvider.h7
-rw-r--r--xbmc/listproviders/StaticProvider.cpp25
-rw-r--r--xbmc/listproviders/StaticProvider.h3
-rw-r--r--xbmc/messaging/helpers/DialogHelper.cpp20
-rw-r--r--xbmc/messaging/helpers/DialogHelper.h10
-rw-r--r--xbmc/music/MusicDatabase.cpp4
-rw-r--r--xbmc/music/dialogs/GUIDialogInfoProviderSettings.cpp4
-rw-r--r--xbmc/music/windows/GUIWindowMusicBase.cpp8
-rw-r--r--xbmc/network/NetworkServices.cpp13
-rw-r--r--xbmc/network/httprequesthandler/HTTPWebinterfaceHandler.cpp2
-rw-r--r--xbmc/network/upnp/UPnPPlayer.cpp3
-rw-r--r--xbmc/peripherals/Peripherals.cpp2
-rw-r--r--xbmc/peripherals/bus/virtual/PeripheralBusAddon.cpp3
-rw-r--r--xbmc/platform/android/CPUInfoAndroid.cpp46
-rw-r--r--xbmc/platform/android/CPUInfoAndroid.h10
-rw-r--r--xbmc/platform/darwin/tvos/XBMCController.mm1
-rw-r--r--xbmc/platform/win32/WIN32Util.cpp76
-rw-r--r--xbmc/platform/win32/WIN32Util.h10
-rw-r--r--xbmc/pvr/PVRDatabase.cpp85
-rw-r--r--xbmc/pvr/PVRDatabase.h21
-rw-r--r--xbmc/pvr/PVRManager.cpp302
-rw-r--r--xbmc/pvr/PVRManager.h118
-rw-r--r--xbmc/pvr/addons/PVRClient.cpp57
-rw-r--r--xbmc/pvr/addons/PVRClients.cpp214
-rw-r--r--xbmc/pvr/addons/PVRClients.h64
-rw-r--r--xbmc/pvr/channels/PVRChannelGroup.cpp47
-rw-r--r--xbmc/pvr/channels/PVRChannelGroup.h16
-rw-r--r--xbmc/pvr/channels/PVRChannelGroupInternal.cpp15
-rw-r--r--xbmc/pvr/channels/PVRChannelGroupInternal.h12
-rw-r--r--xbmc/pvr/channels/PVRChannelGroups.cpp66
-rw-r--r--xbmc/pvr/channels/PVRChannelGroups.h21
-rw-r--r--xbmc/pvr/channels/PVRChannelGroupsContainer.cpp35
-rw-r--r--xbmc/pvr/channels/PVRChannelGroupsContainer.h33
-rw-r--r--xbmc/pvr/dialogs/GUIDialogPVRChannelManager.cpp6
-rw-r--r--xbmc/pvr/dialogs/GUIDialogPVRRecordingSettings.cpp2
-rw-r--r--xbmc/pvr/epg/EpgContainer.cpp7
-rw-r--r--xbmc/pvr/epg/EpgContainer.h2
-rw-r--r--xbmc/pvr/filesystem/PVRGUIDirectory.cpp3
-rw-r--r--xbmc/pvr/guilib/GUIEPGGridContainer.cpp4
-rw-r--r--xbmc/pvr/guilib/PVRGUIActionListener.cpp2
-rw-r--r--xbmc/pvr/guilib/PVRGUIActions.cpp20
-rw-r--r--xbmc/pvr/guilib/PVRGUIProgressHandler.cpp115
-rw-r--r--xbmc/pvr/guilib/PVRGUIProgressHandler.h5
-rw-r--r--xbmc/pvr/providers/PVRProviders.cpp29
-rw-r--r--xbmc/pvr/providers/PVRProviders.h21
-rw-r--r--xbmc/pvr/recordings/PVRRecordings.cpp39
-rw-r--r--xbmc/pvr/recordings/PVRRecordings.h21
-rw-r--r--xbmc/pvr/timers/PVRTimers.cpp51
-rw-r--r--xbmc/pvr/timers/PVRTimers.h37
-rw-r--r--xbmc/pvr/windows/GUIWindowPVRGuide.cpp4
-rw-r--r--xbmc/rendering/dx/DeviceResources.cpp41
-rw-r--r--xbmc/rendering/dx/DeviceResources.h5
-rw-r--r--xbmc/rendering/dx/DirectXHelper.h26
-rw-r--r--xbmc/rendering/dx/RenderSystemDX.h7
-rw-r--r--xbmc/settings/DisplaySettings.cpp8
-rw-r--r--xbmc/settings/MediaSettings.cpp4
-rw-r--r--xbmc/settings/SettingConditions.cpp5
-rw-r--r--xbmc/settings/dialogs/GUIDialogContentSettings.cpp4
-rw-r--r--xbmc/settings/dialogs/GUIDialogLibExportSettings.cpp2
-rw-r--r--xbmc/settings/windows/GUIControlSettings.cpp2
-rw-r--r--xbmc/utils/RssManager.cpp6
-rw-r--r--xbmc/utils/StreamDetails.cpp10
-rw-r--r--xbmc/video/VideoDatabase.cpp6
-rw-r--r--xbmc/video/VideoInfoScanner.cpp3
-rw-r--r--xbmc/video/dialogs/GUIDialogSubtitles.cpp2
-rw-r--r--xbmc/view/GUIViewState.cpp2
-rw-r--r--xbmc/weather/WeatherJob.cpp2
-rw-r--r--xbmc/weather/WeatherManager.cpp2
-rw-r--r--xbmc/windows/GUIMediaWindow.cpp4
-rw-r--r--xbmc/windows/GUIWindowScreensaverDim.cpp2
217 files changed, 2006 insertions, 1156 deletions
diff --git a/addons/audioencoder.kodi.builtin.aac/addon.xml b/addons/audioencoder.kodi.builtin.aac/addon.xml
index 3515649aa4..14e5007382 100644
--- a/addons/audioencoder.kodi.builtin.aac/addon.xml
+++ b/addons/audioencoder.kodi.builtin.aac/addon.xml
@@ -13,6 +13,7 @@
<assets>
<icon>icon.png</icon>
</assets>
+ <summary lang="be_BY">Кадавальнік AAC Audio</summary>
<summary lang="bs_BA">AAC Audio Enkoder</summary>
<summary lang="da_DK">AAC Lydindkoder</summary>
<summary lang="de_DE">AAC Audio Encoder</summary>
@@ -35,8 +36,9 @@
<summary lang="sv_SE">AAC Ljud Encoder</summary>
<summary lang="tr_TR">AAC Ses Kodlayıcı</summary>
<summary lang="zh_CN">AAC 音频编码器</summary>
+ <description lang="be_BY">AAC - набор кодакаў, распрацаваны для забеспячэння сціскання, лепшага за MP3, і ёсць палепшанымі версіямі аўдыё MPEG.</description>
<description lang="bs_BA">AAC je skupina kodeka dizajnirana da pruži bolje sabijanje od MP3-a, te su poboljšane verzije MPEG audia.</description>
- <description lang="da_DK">AAC er et sæt codecs designet til at give bedre komprimering end MP3'er og er forbedrede versioner af MPEG-lyd.</description>
+ <description lang="da_DK">AAC er et sæt codecs designet til at give bedre komprimering end MP3&#x27;er og er forbedrede versioner af MPEG-lyd.</description>
<description lang="de_DE">AAC ist eine Sammlung von Codecs mit einer besseren Komprimierung als MP3. Sie sind verbesserte Versionen von MPEG-Audio.</description>
<description lang="en_AU">AAC is a set of codecs designed to provide better compression than MP3s, and are improved versions of MPEG audio.</description>
<description lang="en_GB">AAC is a set of codecs designed to provide better compression than MP3s, and are improved versions of MPEG audio.</description>
@@ -54,7 +56,7 @@
<description lang="pl_PL">AAC to zestaw kodeków zaprojektowanych w celu zapewnienia lepszej kompresji niż pliki MP3, są ulepszonymi wersjami audio MPEG.</description>
<description lang="pt_BR">AAC é um conjunto de codecs projetado para fornecer melhor compactação do que MP3s e são versões aprimoradas de áudio MPEG.</description>
<description lang="ru_RU">AAC - это набор кодеков, разработанных для обеспечения лучшего сжатия, чем MP3, и являющихся улучшенными версиями аудио MPEG.</description>
- <description lang="tr_TR">AAC, MP3'lerden daha iyi sıkıştırma sağlamak üzere tasarlanmış bir dizi codec bileşenleridir ve MPEG sesinin geliştirilmiş sürümleridir.</description>
+ <description lang="tr_TR">AAC, MP3&#x27;lerden daha iyi sıkıştırma sağlamak üzere tasarlanmış bir dizi codec bileşenleridir ve MPEG sesinin geliştirilmiş sürümleridir.</description>
<description lang="zh_CN">AAC 是一组编解码器,旨在提供比 MP3 更好的压缩,是 MPEG 音频的改进版本。</description>
</extension>
</addon>
diff --git a/addons/audioencoder.kodi.builtin.aac/resources/language/resource.language.be_by/strings.po b/addons/audioencoder.kodi.builtin.aac/resources/language/resource.language.be_by/strings.po
index feee8518bf..a8bc3920c0 100644
--- a/addons/audioencoder.kodi.builtin.aac/resources/language/resource.language.be_by/strings.po
+++ b/addons/audioencoder.kodi.builtin.aac/resources/language/resource.language.be_by/strings.po
@@ -7,23 +7,23 @@ msgstr ""
"Project-Id-Version: KODI Main\n"
"Report-Msgid-Bugs-To: translations@kodi.tv\n"
"POT-Creation-Date: YEAR-MO-DA HO:MI+ZONE\n"
-"PO-Revision-Date: 2021-08-21 08:38+0000\n"
-"Last-Translator: Christian Gade <gade@kodi.tv>\n"
+"PO-Revision-Date: 2022-01-27 10:09+0000\n"
+"Last-Translator: Antikruk <zmicerturok@gmail.com>\n"
"Language-Team: Belarusian <https://kodi.weblate.cloud/projects/kodi-core/audioencoder-kodi-builtin-aac/be_by/>\n"
"Language: be_by\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"Plural-Forms: nplurals=3; plural=n%10==1 && n%100!=11 ? 0 : n%10>=2 && n%10<=4 && (n%100<10 || n%100>=20) ? 1 : 2;\n"
-"X-Generator: Weblate 4.7.2\n"
+"X-Generator: Weblate 4.10.1\n"
msgctxt "Addon Summary"
msgid "AAC Audio Encoder"
-msgstr ""
+msgstr "Кадавальнік AAC Audio"
msgctxt "Addon Description"
msgid "AAC is a set of codecs designed to provide better compression than MP3s, and are improved versions of MPEG audio."
-msgstr ""
+msgstr "AAC - набор кодакаў, распрацаваны для забеспячэння сціскання, лепшага за MP3, і ёсць палепшанымі версіямі аўдыё MPEG."
#. Bitrate to use on for compression
#: resources/settings.xml
@@ -35,7 +35,7 @@ msgstr "Бітрэйт"
#: resources/settings.xml
msgctxt "#30001"
msgid "Select which bitrate to use for the AAC audio encoder for audio compression."
-msgstr ""
+msgstr "Абярыце бітрэйт, які трэба выкарыстоўваць для кадавальніка AAC пры сцісканні гуку."
#. Value format for with bitrate edited field
#: resources/settings.xml
diff --git a/addons/audioencoder.kodi.builtin.wma/addon.xml b/addons/audioencoder.kodi.builtin.wma/addon.xml
index 653e43ec51..4d319964c8 100644
--- a/addons/audioencoder.kodi.builtin.wma/addon.xml
+++ b/addons/audioencoder.kodi.builtin.wma/addon.xml
@@ -54,7 +54,7 @@
<description lang="pl_PL">Windows Media Audio, stratny format audio firmy Microsoft.</description>
<description lang="pt_BR">Windows Media Audio, o formato de áudio com perdas da Microsoft.</description>
<description lang="ru_RU">Windows Media Audio, звуковой формат с потерями от Microsoft.</description>
- <description lang="tr_TR">Windows Media Audio, Microsoft'un kayıplı ses biçimi.</description>
+ <description lang="tr_TR">Windows Media Audio, Microsoft&#x27;un kayıplı ses biçimi.</description>
<description lang="zh_CN">Windows Media Audio,Microsoft 的有损压缩音频格式。</description>
</extension>
</addon>
diff --git a/addons/resource.language.en_gb/resources/strings.po b/addons/resource.language.en_gb/resources/strings.po
index 2b91aa9675..40c0773c28 100644
--- a/addons/resource.language.en_gb/resources/strings.po
+++ b/addons/resource.language.en_gb/resources/strings.po
@@ -7356,6 +7356,17 @@ msgctxt "#13467"
msgid "Unlimited / 1080 (>30Hz)"
msgstr ""
+#: system/settings/settings.xml
+msgctxt "#13468"
+msgid "Use AV1 VAAPI"
+msgstr ""
+
+#. Description of setting with label #13468 "Use AV1 VAAPI"
+#: system/settings/settings.xml
+msgctxt "#13469"
+msgid "Enable this option to use hardware acceleration for the AV1 codec. If disabled the CPU will be used instead."
+msgstr ""
+
#empty strings from id 13468 to 13504
#: system/settings/settings.xml
@@ -10686,11 +10697,7 @@ msgctxt "#19238"
msgid "Loading recordings from clients"
msgstr ""
-#. label 'starting background tasks' for progress dialog text
-#: xbmc/pvr/PVRManager.cpp
-msgctxt "#19239"
-msgid "Starting background threads"
-msgstr ""
+#empty string with id 19239
#. label for pvr settings client priorities control and client priorities dialog heading.
#: system/settings/settings.xml
diff --git a/addons/screensaver.xbmc.builtin.dim/addon.xml b/addons/screensaver.xbmc.builtin.dim/addon.xml
index c970e7662e..b192f69e34 100644
--- a/addons/screensaver.xbmc.builtin.dim/addon.xml
+++ b/addons/screensaver.xbmc.builtin.dim/addon.xml
@@ -16,7 +16,7 @@
<summary lang="bg_BG">Скрийнсейвър, който затъмнява екрана</summary>
<summary lang="ca_ES">Estalvi de pantalla que enfosqueix la pantalla</summary>
<summary lang="cs_CZ">Spořič obrazovky, který ztmaví vaši obrazovku</summary>
- <summary lang="cy_GB">Arbedwr sgrin sy'n pylu eich sgrin</summary>
+ <summary lang="cy_GB">Arbedwr sgrin sy&#x27;n pylu eich sgrin</summary>
<summary lang="da_DK">Pauseskærm som dæmper din skærm</summary>
<summary lang="de_DE">Bildschirmschoner zum Abdunkeln des Bildschirmes</summary>
<summary lang="el_GR">Προφύλαξη οθόνης που σκιάζει την οθόνη σας</summary>
@@ -32,7 +32,7 @@
<summary lang="fa_IR">محافظ صفحه‌ای که صفحه‌تان را تاریک می‌کند</summary>
<summary lang="fi_FI">Näytönsäästäjä, joka himmentää näytön</summary>
<summary lang="fr_CA">Un économiseur d’écran qui baisse la luminosité de votre écran</summary>
- <summary lang="fr_FR">Un économiseur qui assombrit l'écran</summary>
+ <summary lang="fr_FR">Un économiseur qui assombrit l&#x27;écran</summary>
<summary lang="gl_ES">O protector de pantalla atenúa a súa pantalla</summary>
<summary lang="he_IL">שומר מסך אשר מעמעם את המסך</summary>
<summary lang="hr_HR">Čuvar zaslona koji zatamnjuje vaš zaslon</summary>
@@ -69,14 +69,14 @@
<summary lang="vi_VN">Trình bảo vệ màn hình này làm mờ màn hình của bạn</summary>
<summary lang="zh_CN">淡出屏幕保护程序</summary>
<summary lang="zh_TW">讓螢幕變暗的螢幕保護程式</summary>
- <description lang="af_ZA">Die Verdof sluimerskerm is 'n eenvoudige sluimerskerm wat jou skerm verdof (uit vaag) tot 'n stelbare waarde tussen 20 en 100%</description>
+ <description lang="af_ZA">Die Verdof sluimerskerm is &#x27;n eenvoudige sluimerskerm wat jou skerm verdof (uit vaag) tot &#x27;n stelbare waarde tussen 20 en 100%</description>
<description lang="am_ET">የ መመልከቻ ማዳኛ ማደብዘዣ የ እርስዎን መመልከቻ ያፈዘዋል (ማፍዘዣ) የ እርስዎን መመልከቻ ዋጋ በ 20 እና በ 100% መካከል</description>
<description lang="ar_SA">Dim عبارة عن شاشة توقف تمكن من تظليم (صورة خافتة) الشاشة إلى قيمة قابلة للتحديد بين 20 و 100%</description>
<description lang="be_BY">Dim - просты ахоўнік экрана, які будзе паступова зацямняць экран. Значэнне зацямнення можа змяняцца ад 20 да 100%.</description>
<description lang="bg_BG">Скрийнсейвърът &quot;Dim&quot; затъмнява екрана, до стойност, която Вие определяте предварително (между 20 и 100%).</description>
- <description lang="ca_ES">L'estalvi de pantalla Dim és un estalvi de pantalla simple que enfosquirà (fos en negre) la seva pantalla a un valor que es pot configurar entre 20 i 100%.</description>
+ <description lang="ca_ES">L&#x27;estalvi de pantalla Dim és un estalvi de pantalla simple que enfosquirà (fos en negre) la seva pantalla a un valor que es pot configurar entre 20 i 100%.</description>
<description lang="cs_CZ">Spořič obrazovky Dim je jednoduchý spořič obrazovky, který ztmaví (posupně) vaši obrazovku podle nastavitelné hodnoty mezi 20 a 100 %.</description>
- <description lang="cy_GB">Mae arbedwr sgrin Dim yn arbedwr sgrin syml sy'n pylu (tywyllu) eich sgrin i werth gosodadwy rhwyg 20 a 100%.</description>
+ <description lang="cy_GB">Mae arbedwr sgrin Dim yn arbedwr sgrin syml sy&#x27;n pylu (tywyllu) eich sgrin i werth gosodadwy rhwyg 20 a 100%.</description>
<description lang="da_DK">Dæmpningspauseskærmen er en simpel pauseskærm, der dæmper (nedtoner) din skærm til en valgfri værdi mellem 20 og 100%.</description>
<description lang="de_DE">Der Dimmer-Bildschirmschoner ist ein einfacher Bildschirmschoner, welcher den Bildschirm auf einen benutzerdefinierten Wert zwischen 20 und 100% abdunkelt.</description>
<description lang="el_GR">Η προφύλαξη οθόνης Dim είναι μία απλή προφύλαξη η οποία σκιάζει την οθόνη σας σε μία τιμή που μπορεί να ρυθμιστεί μεταξύ 20 και 100%.</description>
@@ -92,7 +92,7 @@
<description lang="fa_IR">محافظ صفحهٔ تاریک‌کننده، محافظ صفحه‌ای ساده است که نور صفحه‌تان را (به صورت تدریجی) تا سطح تعریف شده‌ای بین ۲۰ تا ۱۰۰٪ کم خواهد کرد.</description>
<description lang="fi_FI">Dim on yksinkertainen näytönsäästäjä joka himmentää ruudun valitulle tasolle välillä 20-100%.</description>
<description lang="fr_CA">L’économiseur Dim est un économiseur d’écran simple qui abaissera la luminosité de votre écran à une valeur réglable entre 20 à 100 %.</description>
- <description lang="fr_FR">L'économiseur Dim est un simple économiseur qui assombrira l'écran. L'assombrissement est paramétrable de 20 à 100 %.</description>
+ <description lang="fr_FR">L&#x27;économiseur Dim est un simple économiseur qui assombrira l&#x27;écran. L&#x27;assombrissement est paramétrable de 20 à 100 %.</description>
<description lang="gl_ES">Este protector de pantalla atenuará a súa pantalla nun valor configurábel entre o 20% e o 100%.</description>
<description lang="he_IL">שומר המסך Dim הוא שומר מסך פשוט אשר מעמעם את המסך לערך מוגדר בין 20% ל־100%.</description>
<description lang="hr_HR">Dim čuvar zaslona je jednostavan čuvar zaslona koji će zatamniti (postepeno isčeznuti) vaš zaslon na odabranu vrijednost između 20 i 100% .</description>
@@ -106,7 +106,7 @@
<description lang="lv_LV">Aptumsuma ekrānsaudzētājs ir vienkāršs ekrānsaudzētājs, kas aptumšo (padara tumšāku) jūsu ekrānu līdz uzstādāmai robežai starp 20 un 100%.</description>
<description lang="mk_MK">ДИМ Заштитата на екран е едноставно стемнување на екранот, може да се одбере вредност помеѓу 20 и 100%</description>
<description lang="ms_MY">Penyelamat skrin malap adapah penyelamat skrin ringkas yang memalapkan (lenyapkan) skrin anda kepada nilai boleh ditetap diantara 20 hingga 100%.</description>
- <description lang="mt_MT">L-iskrinsejver Dim huwa skrinsejver sempliċi li jbaxxilek (bil-mod) il-qawwa tal-iskrin sa valur li tista' tagħżel bejn 20 u 100%.</description>
+ <description lang="mt_MT">L-iskrinsejver Dim huwa skrinsejver sempliċi li jbaxxilek (bil-mod) il-qawwa tal-iskrin sa valur li tista&#x27; tagħżel bejn 20 u 100%.</description>
<description lang="my_MM">Dim screensaver သည် ရိုးရှင်းသော Screensaver တစ်ခုဖြစ်သည်။ ၎င်းသည် သင်၏ စခရင် ကို ၂၀% မှ ၁၀၀% အတွင်း မှေးမှိန်သွားအောင်ပြုလုပ်လိမ့်မည်</description>
<description lang="nb_NO">Dim er en enkel skjermsparer som dimmer skjermen din til en justerbar verdi mellom 20-100%</description>
<description lang="nl_NL">De Dim-schermbeveiliging is een eenvoudige schermbeveiliging die je scherm geleidelijk dimt. Je kunt een waarde van 20 tot 100% instellen.</description>
diff --git a/addons/skin.estouchy/addon.xml b/addons/skin.estouchy/addon.xml
index 7ceacd1f80..fee4bc8068 100644
--- a/addons/skin.estouchy/addon.xml
+++ b/addons/skin.estouchy/addon.xml
@@ -84,7 +84,7 @@
<description lang="ar_SA">مظهر للواجهة مصمم للأجهزة التي تعمل باللمس مثل الجوالات الذكية والأجهزة اللوحية</description>
<description lang="be_BY">Абалонка распрацаваная для выкарыстання на сэнсарных прыладах, такіх як планшэты і смартфоны</description>
<description lang="bg_BG">Обликът е разработен за ползване на устройства със сензорен екран, като таблети и телефони.</description>
- <description lang="ca_ES">Aparença dissenyada perquè s'utilitzi en dispositius amb pantalla tàctil com taules i telèfons intel·ligents</description>
+ <description lang="ca_ES">Aparença dissenyada perquè s&#x27;utilitzi en dispositius amb pantalla tàctil com taules i telèfons intel·ligents</description>
<description lang="cs_CZ">Vzhled navržený pro použití na zařízeních s dotykovou obrazovkou, jako jsou tablety a chytré telefony</description>
<description lang="da_DK">Skin der er designet til brug på berøringsfølsomme enheder som f.eks. tablets og smartphones</description>
<description lang="de_DE">Dieser Skin wurde für die Verwendung mit Touchscreen-Geräten, wie Tablets und Handys, entworfen</description>
diff --git a/addons/skin.estouchy/language/resource.language.es_es/strings.po b/addons/skin.estouchy/language/resource.language.es_es/strings.po
index cb7aa1021f..552ae2fe19 100644
--- a/addons/skin.estouchy/language/resource.language.es_es/strings.po
+++ b/addons/skin.estouchy/language/resource.language.es_es/strings.po
@@ -7,7 +7,7 @@ msgstr ""
"Project-Id-Version: KODI Main\n"
"Report-Msgid-Bugs-To: translations@kodi.tv\n"
"POT-Creation-Date: YEAR-MO-DA HO:MI+ZONE\n"
-"PO-Revision-Date: 2022-01-03 13:36+0000\n"
+"PO-Revision-Date: 2022-01-26 11:59+0000\n"
"Last-Translator: Alfonso Cachero <alfonso.cachero@gmail.com>\n"
"Language-Team: Spanish (Spain) <https://kodi.weblate.cloud/projects/kodi-add-ons-skins/skin-estouchy/es_es/>\n"
"Language: es_es\n"
@@ -236,7 +236,7 @@ msgstr "Cambiar la skin - Seleccionar idioma y zona - Cambiar opciones de listad
msgctxt "#31405"
msgid "Configure & manage media sharing services · Configure & manage the weather service"
-msgstr "Configurar y gestionar los servicios para compartir contenido · Configurar y gestionar el servicio del Tiempo"
+msgstr "Configurar y gestionar los servicios para compartir contenido · Configurar y gestionar el servicio meteorológico"
msgctxt "#31406"
msgid "Configure display · Configure audio · Configure internet access · Configure power saving· Configure logging"
diff --git a/addons/skin.estouchy/media/flagging/aspectratio/1.00.png b/addons/skin.estouchy/media/flagging/aspectratio/1.00.png
new file mode 100644
index 0000000000..eb41c15f7f
--- /dev/null
+++ b/addons/skin.estouchy/media/flagging/aspectratio/1.00.png
Binary files differ
diff --git a/addons/skin.estouchy/media/flagging/aspectratio/1.19.png b/addons/skin.estouchy/media/flagging/aspectratio/1.19.png
new file mode 100644
index 0000000000..80289ae466
--- /dev/null
+++ b/addons/skin.estouchy/media/flagging/aspectratio/1.19.png
Binary files differ
diff --git a/addons/skin.estouchy/media/flagging/aspectratio/2.00.png b/addons/skin.estouchy/media/flagging/aspectratio/2.00.png
new file mode 100644
index 0000000000..cd8ff2569f
--- /dev/null
+++ b/addons/skin.estouchy/media/flagging/aspectratio/2.00.png
Binary files differ
diff --git a/addons/skin.estuary/addon.xml b/addons/skin.estuary/addon.xml
index 9d5f80e46e..675cf67e43 100644
--- a/addons/skin.estuary/addon.xml
+++ b/addons/skin.estuary/addon.xml
@@ -39,9 +39,9 @@
<summary lang="da_DK">Estuary skin af phil65 (Kodis standard brugerflade)</summary>
<summary lang="de_DE">Estuary Skin von phil65. (Kodi-Standardskin)</summary>
<summary lang="el_GR">Το κέλυφος Estuary από τον phil65 και τον Pier. (προεπιλεγμένο κέλυφος του Kodi)</summary>
- <summary lang="en_GB">Estuary skin by phil65. (Kodi's default skin)</summary>
- <summary lang="en_NZ">Estuary skin by phil65 and Piers. (Kodi's default skin)</summary>
- <summary lang="en_US">Estuary skin by phil65 and Piers. (Kodi's default skin)</summary>
+ <summary lang="en_GB">Estuary skin by phil65. (Kodi&#x27;s default skin)</summary>
+ <summary lang="en_NZ">Estuary skin by phil65 and Piers. (Kodi&#x27;s default skin)</summary>
+ <summary lang="en_US">Estuary skin by phil65 and Piers. (Kodi&#x27;s default skin)</summary>
<summary lang="es_AR">Skin Estuary por phil65 (skin por defecto de Kodi)</summary>
<summary lang="es_ES">Skin Estuary, creado por phil65 and Piers (skin por defecto de Kodi).</summary>
<summary lang="es_MX">Máscara Estuary por phil65 y Piers. (La máscara predeterminada de Kodi)</summary>
@@ -50,7 +50,7 @@
<summary lang="fa_IR">پوستهٔ اسچوری به دست phil65. (پوستهٔ پیش‌گزیدهٔ کودی)</summary>
<summary lang="fi_FI">Estuary on phil65:n luoma Kodin oletusulkoasu</summary>
<summary lang="fr_CA">Habillage Estuary par phil65 et Piers (habillage par défaut de Kodi).</summary>
- <summary lang="fr_FR">Estuary, un habillage par phil65 et Piers (habillage d'origine de Kodi)</summary>
+ <summary lang="fr_FR">Estuary, un habillage par phil65 et Piers (habillage d&#x27;origine de Kodi)</summary>
<summary lang="gl_ES">Pel Estuary por phil65 and Piers. (Pel predefinida do Kodi)</summary>
<summary lang="he_IL">מעטפת Estuary של phil65 (ברירת המחדל של קודי)</summary>
<summary lang="hr_HR">Estuary presvlaka autora phil65 i Piersa. (uobičajena Kodi presvlaka)</summary>
@@ -62,10 +62,10 @@
<summary lang="ko_KR">phil65가 만든 Estuary 스킨. (Kodi 기본 스킨)</summary>
<summary lang="lt_LT">Estuary teminė išvaizda, kurią sukūrė phil65 ir Piers. (Numatytoji Kodi teminė išvaizda)</summary>
<summary lang="lv_LV">Estuary apvalks no phil65. (Kodi noklusējuma apvalks)</summary>
- <summary lang="mk_MK">Estuary skin by phil65. (Kodi's default skin)</summary>
+ <summary lang="mk_MK">Estuary skin by phil65. (Kodi&#x27;s default skin)</summary>
<summary lang="ms_MY">Kulit Estuary oleh phil65 dan rakan-rakan. (Kulit lalai Kodi)</summary>
<summary lang="nb_NO">Esturay-drakt av phil65 og Piers. (Kodis forvalgte drakt)</summary>
- <summary lang="nl_NL">Estuary skin door phil65 en Piers. (Kodi's standaardskin)</summary>
+ <summary lang="nl_NL">Estuary skin door phil65 en Piers. (Kodi&#x27;s standaardskin)</summary>
<summary lang="pl_PL">Skóra Eustary autorstwa phil65. (domyślna skóra Kodi)</summary>
<summary lang="pt_BR">Skin Estuary por phil65 e Piers. (Skin padrão do Kodi)</summary>
<summary lang="pt_PT">Visual Estuary de phil65 e Piers. (Visual por omissão do Kodi)</summary>
@@ -74,10 +74,10 @@
<summary lang="sk_SK">Vzhľad Estuary, vytvorili phil65. (predvolený vzhľad pre Kodi)</summary>
<summary lang="sr_RS">Маска Estuary аутора phil65 и Piers. (Подразумевана Коди маска)</summary>
<summary lang="sr_RS@latin">Maska Estuary autora phil65 i Piers. (Podrazumevana Kodi maska)</summary>
- <summary lang="sv_SE">Estuary, ett skal av phil65. (Kodi's standardskal)</summary>
+ <summary lang="sv_SE">Estuary, ett skal av phil65. (Kodi&#x27;s standardskal)</summary>
<summary lang="szl">Skōra Estuary ôd phil65 i Piers. (Wychodnŏ skōra Kodi)</summary>
<summary lang="th_TH">สกิน Estuary โดย phil65 และ Piers (หน้าตาเริ่มต้นของKodi)</summary>
- <summary lang="tr_TR">Estuary dış görünümü. phil65 (Kodi'nin varsayılan dış görünümü)</summary>
+ <summary lang="tr_TR">Estuary dış görünümü. phil65 (Kodi&#x27;nin varsayılan dış görünümü)</summary>
<summary lang="uk_UA">Обкладинка Estuary від phil65 і Piers. (стандартна обкладинка Kodi)</summary>
<summary lang="vi_VN">Giao diện Estuary của phil65. (Giao diện mặc định của Kodi)</summary>
<summary lang="zh_CN">phil65 开发的 Estuary 皮肤(Kodi 的默认皮肤)。</summary>
@@ -86,7 +86,7 @@
<description lang="ar_SA">Estuary هو المظهر الافتراضي ل كودي الإصدار 17.0 و أعلى. يطمح بأن يكون سهل الاستخدام والفهم لمستخدمين كودي الجدد.</description>
<description lang="be_BY">Estuary - прадвызначаная абалонка для Kodi 17.0 і пазнейшых версій. Яна будзе простай і зразумелай для карыстальнікаў, якія не мелі досведу працы з Kodi.</description>
<description lang="bg_BG">Estuary е стандартният облик на Kodi 17 и по-новите версии. Целта е да се улеснят хората, които се сблъскват за първи път с Kodi.</description>
- <description lang="ca_ES">Estuary és l'aparença predeterminada de Kodi 17.0 i posteriors. Per als usuaris per primera vegada de Kodi, intenta ser fàcil d'entendre i d'utilitzar.</description>
+ <description lang="ca_ES">Estuary és l&#x27;aparença predeterminada de Kodi 17.0 i posteriors. Per als usuaris per primera vegada de Kodi, intenta ser fàcil d&#x27;entendre i d&#x27;utilitzar.</description>
<description lang="cs_CZ">Estuary je výchozí vzhled pro Kodi 17.0 a vyšší. Snaží se být jednoduše pochopitelný a použitelný pro nové uživatele Kodi.</description>
<description lang="da_DK">Estuary er standardbrugerfladen for Kodi 17.0 og højere. Det forenkler førstegangsbrugen af Kodi ved at gøre det nemmere at forstå og bruge.</description>
<description lang="de_DE">Estuary ist der Standardskin für Kodi 17.0 und höher. Ziel war es, einen einfach zu bedienenden Skin für neue Kodi-Benutzer zu entwickeln.</description>
@@ -102,7 +102,7 @@
<description lang="fa_IR">اسچوری پوستهٔ پیش‌گزیدهٔ کودی ۱۷٫۰ و بالاتر است. این پوسته تلاش می‌کند درک و استفاده‌اش برای کاربرانی که نخستین بار با کودی کار می‌کنند، ساده باشد.</description>
<description lang="fi_FI">Estuary on oletusulkoasu Kodin versiosta 17.0 lähtien. Se pyrkii olemaan helppo ymmärtää ja käyttää Kodin ensikäyttäjille.</description>
<description lang="fr_CA">Estuary est l’habillage par défaut pour Kodi 17.0 et ultérieure. Il s’efforce d’être facile à comprendre et à utiliser pour les utilisateurs débutants de Kodi.</description>
- <description lang="fr_FR">Estuary est l'habillage d'origine pour Kodi 17.0 et supérieur. Il est facile à comprendre et à utiliser pour les utilisateurs novices de Kodi.</description>
+ <description lang="fr_FR">Estuary est l&#x27;habillage d&#x27;origine pour Kodi 17.0 et supérieur. Il est facile à comprendre et à utiliser pour les utilisateurs novices de Kodi.</description>
<description lang="gl_ES">Estuary é a pel predefinida para Kodi 17.0 e superior. Esta tenta ser doada de entender e usar polos usuarios recen chegados a Kodi.</description>
<description lang="he_IL">Estuary היא מעטפת ברירת המחדל של קודי מגרסאות 17.0 ומעלה. מטרת מעטפת זו היא להיות פשוטה לשימוש ולהכרה ראשונית על ידי משתמשים חדשים.</description>
<description lang="hr_HR">Estuary je uobičajena presvlaka za Kodi 17.0 i novije inačice. To je pokušaj da se novim korisnicima olakša prvo korištenje i kasnija upotreba Kodija.</description>
@@ -136,7 +136,7 @@
<disclaimer lang="ar_SA">Estuary هو المظهر الافتراضي ل كودي, إزالته قد تسبب بعض المشاكل</disclaimer>
<disclaimer lang="be_BY">Estuary - прадвызначаная абалонка для Kodi. Яе выдаленне можа прывесці да праблем</disclaimer>
<disclaimer lang="bg_BG">Estuary е стандартният облик на Kodi. Премахването му може да предизвика проблеми</disclaimer>
- <disclaimer lang="ca_ES">Estuary és l'aparença predeterminada de Kodi, si s'elimina pot causar problemes.</disclaimer>
+ <disclaimer lang="ca_ES">Estuary és l&#x27;aparença predeterminada de Kodi, si s&#x27;elimina pot causar problemes.</disclaimer>
<disclaimer lang="cs_CZ">Estuary je výchozí vzhled pro Kodi, jeho odebrání může způsobit problémy</disclaimer>
<disclaimer lang="cy_GB">Estuary yw croen diofyn Kodi. Efallai bydd ei dynnu yn achosi problemau</disclaimer>
<disclaimer lang="da_DK">Estuary er standard brugerfladen. Fjernes det kan der opstå problemer.</disclaimer>
@@ -153,7 +153,7 @@
<disclaimer lang="fa_IR">اسچوری پوستهٔ پیش‌گزیدهٔ کودی است. ممکن است برداشتنش موجب مشکلاتی شود</disclaimer>
<disclaimer lang="fi_FI">Estuary on Kodin oletusulkoasu, sen poisto voi aiheuttaa ongelmia</disclaimer>
<disclaimer lang="fr_CA">Estuary est l’habillage par défaut de Kodi, le supprimer peut créer des problèmes</disclaimer>
- <disclaimer lang="fr_FR">Estuary est l'habillage d'origine de Kodi, le retirer peut créer des problèmes</disclaimer>
+ <disclaimer lang="fr_FR">Estuary est l&#x27;habillage d&#x27;origine de Kodi, le retirer peut créer des problèmes</disclaimer>
<disclaimer lang="gl_ES">Estuary é a pel predefinida para Kodi e eliminala pode causar problemas.</disclaimer>
<disclaimer lang="he_IL">Estuary היא מעטפת ברירת המחדל של קודי, הסרתה עלולה לגרום לתקלות</disclaimer>
<disclaimer lang="hr_HR">Estuary je uobičajena presvlaka za Kodi, njegovim uklanjanjem može uzrokovati poteškoće</disclaimer>
diff --git a/addons/skin.estuary/language/resource.language.es_es/strings.po b/addons/skin.estuary/language/resource.language.es_es/strings.po
index c7989441fd..e082190ce0 100644
--- a/addons/skin.estuary/language/resource.language.es_es/strings.po
+++ b/addons/skin.estuary/language/resource.language.es_es/strings.po
@@ -7,7 +7,7 @@ msgstr ""
"Project-Id-Version: KODI Main\n"
"Report-Msgid-Bugs-To: translations@kodi.tv\n"
"POT-Creation-Date: YEAR-MO-DA HO:MI+ZONE\n"
-"PO-Revision-Date: 2022-01-03 13:36+0000\n"
+"PO-Revision-Date: 2022-01-26 11:59+0000\n"
"Last-Translator: Alfonso Cachero <alfonso.cachero@gmail.com>\n"
"Language-Team: Spanish (Spain) <https://kodi.weblate.cloud/projects/kodi-add-ons-skins/skin-estuary/es_es/>\n"
"Language: es_es\n"
@@ -263,7 +263,7 @@ msgstr "Elementos del menú principal"
msgctxt "#31062"
msgid "Choose weather fanart pack"
-msgstr "Elegir pack de fanart para el tiempo"
+msgstr "Elegir pack de fanart para la meteorología"
msgctxt "#31063"
msgid "Sections"
@@ -440,11 +440,11 @@ msgstr "No tiene instalado ningún add-on aún. Visite nuestro navegador de add-
msgctxt "#31120"
msgid "You did not set up a weather provider yet. In order to view weather information, choose a weather provider and set up your location."
-msgstr "No ha configurado aún un proveedor de Tiempo. Para poder consultar el Tiempo, elija un proveedor y establezca su ubicación."
+msgstr "No ha configurado aún un proveedor de meteorología. Para poder consultar la meteorología, elija un proveedor y establezca su ubicación."
msgctxt "#31121"
msgid "Set weather provider"
-msgstr "Establecer proveedor de Tiempo"
+msgstr "Establecer proveedor de meteorología"
msgctxt "#31122"
msgid "Unwatched TV Shows"
diff --git a/addons/skin.estuary/media/flags/aspectratio/1.00.png b/addons/skin.estuary/media/flags/aspectratio/1.00.png
new file mode 100644
index 0000000000..eb41c15f7f
--- /dev/null
+++ b/addons/skin.estuary/media/flags/aspectratio/1.00.png
Binary files differ
diff --git a/addons/skin.estuary/media/flags/aspectratio/1.19.png b/addons/skin.estuary/media/flags/aspectratio/1.19.png
new file mode 100644
index 0000000000..80289ae466
--- /dev/null
+++ b/addons/skin.estuary/media/flags/aspectratio/1.19.png
Binary files differ
diff --git a/addons/skin.estuary/media/flags/aspectratio/2.00.png b/addons/skin.estuary/media/flags/aspectratio/2.00.png
new file mode 100644
index 0000000000..cd8ff2569f
--- /dev/null
+++ b/addons/skin.estuary/media/flags/aspectratio/2.00.png
Binary files differ
diff --git a/addons/skin.estuary/xml/Home.xml b/addons/skin.estuary/xml/Home.xml
index 0a88c6c496..4192e93d67 100644
--- a/addons/skin.estuary/xml/Home.xml
+++ b/addons/skin.estuary/xml/Home.xml
@@ -391,8 +391,8 @@
<param name="sortorder" value="descending"/>
<param name="widget_header" value="$LOCALIZE[31015]"/>
<param name="list_id" value="12300"/>
- <param name="label" value="$INFO[ListItem.ChannelName]"/>
- <param name="label2" value="$INFO[ListItem.Title]$INFO[ListItem.EpisodeName, (,)]"/>
+ <param name="label" value="$INFO[ListItem.Title]$INFO[ListItem.Date, (,)]"/>
+ <param name="label2" value="$VAR[SeasonEpisodeLabel]$INFO[ListItem.EpisodeName]"/>
</include>
<include content="WidgetListPVR" condition="System.HasPVRAddon">
<param name="content_path" value="pvr://timers/tv/timers/?view=hidedisabled"/>
@@ -401,8 +401,8 @@
<param name="widget_header" value="$LOCALIZE[19040]"/>
<param name="widget_target" value="tvtimers"/>
<param name="list_id" value="12400"/>
- <param name="label" value="$INFO[ListItem.Date]"/>
- <param name="label2" value="$INFO[ListItem.Title]$INFO[ListItem.EpisodeName, (,)] - $INFO[ListItem.ChannelName]"/>
+ <param name="label" value="$INFO[ListItem.Title]$INFO[ListItem.Date, (,)]"/>
+ <param name="label2" value="$VAR[SeasonEpisodeLabel]$INFO[ListItem.EpisodeName]"/>
</include>
<include content="WidgetListPVR" condition="System.HasPVRAddon">
<param name="content_path" value="pvr://channels/tv"/>
@@ -458,8 +458,8 @@
<param name="sortorder" value="descending"/>
<param name="widget_header" value="$LOCALIZE[31015]"/>
<param name="list_id" value="13300"/>
- <param name="label" value="$INFO[ListItem.ChannelName]"/>
- <param name="label2" value="$INFO[ListItem.Title]$INFO[ListItem.EpisodeName, (,)]"/>
+ <param name="label" value="$INFO[ListItem.Title]$INFO[ListItem.Date, (,)]"/>
+ <param name="label2" value="$VAR[SeasonEpisodeLabel]$INFO[ListItem.EpisodeName]"/>
</include>
<include content="WidgetListPVR" condition="System.HasPVRAddon">
<param name="content_path" value="pvr://timers/radio/timers/?view=hidedisabled"/>
@@ -468,8 +468,8 @@
<param name="widget_header" value="$LOCALIZE[19040]"/>
<param name="widget_target" value="radiotimers"/>
<param name="list_id" value="13400"/>
- <param name="label" value="$INFO[ListItem.Date]"/>
- <param name="label2" value="$INFO[ListItem.Title]$INFO[ListItem.EpisodeName, (,)] - $INFO[ListItem.ChannelName]"/>
+ <param name="label" value="$INFO[ListItem.Title]$INFO[ListItem.Date, (,)]"/>
+ <param name="label2" value="$VAR[SeasonEpisodeLabel]$INFO[ListItem.EpisodeName]"/>
</include>
<include content="WidgetListPVR" condition="System.HasPVRAddon">
<param name="content_path" value="pvr://channels/radio"/>
diff --git a/cmake/modules/FindCrossGUID.cmake b/cmake/modules/FindCrossGUID.cmake
index 01ec1a05f9..c8eff40b64 100644
--- a/cmake/modules/FindCrossGUID.cmake
+++ b/cmake/modules/FindCrossGUID.cmake
@@ -9,7 +9,7 @@ if(ENABLE_INTERNAL_CROSSGUID)
if(CROSSGUID_URL)
get_filename_component(CROSSGUID_URL "${CROSSGUID_URL}" ABSOLUTE)
else()
- set(CROSSGUID_URL http://mirrors.kodi.tv/build-deps/sources/${ARCHIVE})
+ set(CROSSGUID_URL http://mirrors.kodi.tv/build-deps/sources/${CROSSGUID_ARCHIVE})
endif()
if(VERBOSE)
message(STATUS "CROSSGUID_URL: ${CROSSGUID_URL}")
@@ -23,6 +23,7 @@ if(ENABLE_INTERNAL_CROSSGUID)
set(CROSSGUID_INCLUDE_DIR ${CMAKE_BINARY_DIR}/${CORE_BUILD_DIR}/include)
externalproject_add(crossguid
URL ${CROSSGUID_URL}
+ URL_HASH ${CROSSGUID_HASH}
DOWNLOAD_DIR ${TARBALL_DIR}
PREFIX ${CORE_BUILD_DIR}/crossguid
CMAKE_ARGS -DCMAKE_INSTALL_PREFIX=${CMAKE_BINARY_DIR}/${CORE_BUILD_DIR}
diff --git a/cmake/modules/FindDav1d.cmake b/cmake/modules/FindDav1d.cmake
index a5a21b12e5..b417a536b8 100644
--- a/cmake/modules/FindDav1d.cmake
+++ b/cmake/modules/FindDav1d.cmake
@@ -33,7 +33,7 @@ if(ENABLE_INTERNAL_DAV1D)
if(DAV1D_URL)
get_filename_component(DAV1D_URL "${DAV1D_URL}" ABSOLUTE)
else()
- set(DAV1D_URL http://mirrors.kodi.tv/build-deps/sources/${ARCHIVE})
+ set(DAV1D_URL http://mirrors.kodi.tv/build-deps/sources/${DAV1D_ARCHIVE})
endif()
if(VERBOSE)
@@ -46,7 +46,8 @@ if(ENABLE_INTERNAL_DAV1D)
externalproject_add(dav1d
URL ${DAV1D_URL}
- DOWNLOAD_NAME ${ARCHIVE}
+ URL_HASH ${DAV1D_HASH}
+ DOWNLOAD_NAME ${DAV1D_ARCHIVE}
DOWNLOAD_DIR ${TARBALL_DIR}
PREFIX ${CORE_BUILD_DIR}/dav1d
CONFIGURE_COMMAND meson
diff --git a/cmake/modules/FindFFMPEG.cmake b/cmake/modules/FindFFMPEG.cmake
index be77c51024..16c29e5044 100644
--- a/cmake/modules/FindFFMPEG.cmake
+++ b/cmake/modules/FindFFMPEG.cmake
@@ -33,7 +33,7 @@
#
# required ffmpeg library versions
-set(REQUIRED_FFMPEG_VERSION 4.4)
+set(REQUIRED_FFMPEG_VERSION 4.4.1)
set(_avcodec_ver ">=58.134.100")
set(_avfilter_ver ">=7.110.100")
set(_avformat_ver ">=58.76.100")
@@ -250,7 +250,8 @@ if(NOT FFMPEG_FOUND)
externalproject_add(ffmpeg
URL ${FFMPEG_URL}
- DOWNLOAD_NAME ${ARCHIVE}
+ URL_HASH ${FFMPEG_HASH}
+ DOWNLOAD_NAME ${FFMPEG_ARCHIVE}
DOWNLOAD_DIR ${TARBALL_DIR}
PREFIX ${CORE_BUILD_DIR}/ffmpeg
CMAKE_ARGS -DCMAKE_INSTALL_PREFIX=${CMAKE_BINARY_DIR}/${CORE_BUILD_DIR}
diff --git a/cmake/modules/FindFlatBuffers.cmake b/cmake/modules/FindFlatBuffers.cmake
index 4d7a9ba331..8397728066 100644
--- a/cmake/modules/FindFlatBuffers.cmake
+++ b/cmake/modules/FindFlatBuffers.cmake
@@ -20,7 +20,7 @@ if(ENABLE_INTERNAL_FLATBUFFERS)
if(FLATBUFFERS_URL)
get_filename_component(FLATBUFFERS_URL "${FLATBUFFERS_URL}" ABSOLUTE)
else()
- set(FLATBUFFERS_URL http://mirrors.kodi.tv/build-deps/sources/${ARCHIVE})
+ set(FLATBUFFERS_URL http://mirrors.kodi.tv/build-deps/sources/${FLATBUFFERS_ARCHIVE})
endif()
if(VERBOSE)
message(STATUS "FLATBUFFERS_URL: ${FLATBUFFERS_URL}")
@@ -31,6 +31,7 @@ if(ENABLE_INTERNAL_FLATBUFFERS)
externalproject_add(flatbuffers
URL ${FLATBUFFERS_URL}
+ URL_HASH ${FLATBUFFERS_HASH}
DOWNLOAD_DIR ${TARBALL_DIR}
PREFIX ${CORE_BUILD_DIR}/flatbuffers
CMAKE_ARGS -DCMAKE_INSTALL_PREFIX=${CMAKE_BINARY_DIR}/${CORE_BUILD_DIR}
diff --git a/cmake/modules/FindFmt.cmake b/cmake/modules/FindFmt.cmake
index d3d66820f8..53affa04e2 100644
--- a/cmake/modules/FindFmt.cmake
+++ b/cmake/modules/FindFmt.cmake
@@ -23,7 +23,7 @@ if(ENABLE_INTERNAL_FMT)
if(FMT_URL)
get_filename_component(FMT_URL "${FMT_URL}" ABSOLUTE)
else()
- set(FMT_URL http://mirrors.kodi.tv/build-deps/sources/${ARCHIVE})
+ set(FMT_URL http://mirrors.kodi.tv/build-deps/sources/${LIBFMT_ARCHIVE})
endif()
if(VERBOSE)
message(STATUS "FMT_URL: ${FMT_URL}")
@@ -37,6 +37,7 @@ if(ENABLE_INTERNAL_FMT)
set(FMT_INCLUDE_DIR ${CMAKE_BINARY_DIR}/${CORE_BUILD_DIR}/include)
externalproject_add(fmt
URL ${FMT_URL}
+ URL_HASH ${FMT_HASH}
DOWNLOAD_DIR ${TARBALL_DIR}
PREFIX ${CORE_BUILD_DIR}/fmt
CMAKE_ARGS -DCMAKE_INSTALL_PREFIX=${CMAKE_BINARY_DIR}/${CORE_BUILD_DIR}
diff --git a/cmake/modules/FindFstrcmp.cmake b/cmake/modules/FindFstrcmp.cmake
index 038331bf5c..042b9967cc 100644
--- a/cmake/modules/FindFstrcmp.cmake
+++ b/cmake/modules/FindFstrcmp.cmake
@@ -22,7 +22,7 @@ if(ENABLE_INTERNAL_FSTRCMP)
if(FSTRCMP_URL)
get_filename_component(FSTRCMP_URL "${FSTRCMP_URL}" ABSOLUTE)
else()
- set(FSTRCMP_URL http://mirrors.kodi.tv/build-deps/sources/${ARCHIVE})
+ set(FSTRCMP_URL http://mirrors.kodi.tv/build-deps/sources/${LIBFSTRCMP_ARCHIVE})
endif()
if(VERBOSE)
message(STATUS "FSTRCMPURL: ${FSTRCMP_URL}")
@@ -32,6 +32,7 @@ if(ENABLE_INTERNAL_FSTRCMP)
set(FSTRCMP_INCLUDE_DIR ${CMAKE_BINARY_DIR}/${CORE_BUILD_DIR}/include)
externalproject_add(fstrcmp
URL ${FSTRCMP_URL}
+ URL_HASH ${FSTRCMP_HASH}
DOWNLOAD_DIR ${TARBALL_DIR}
PREFIX ${CORE_BUILD_DIR}/fstrcmp
PATCH_COMMAND autoreconf -vif
diff --git a/cmake/modules/FindGtest.cmake b/cmake/modules/FindGtest.cmake
index f2b7e9fe8a..d3171d1ec2 100644
--- a/cmake/modules/FindGtest.cmake
+++ b/cmake/modules/FindGtest.cmake
@@ -26,7 +26,7 @@ if(ENABLE_INTERNAL_GTEST)
if(GTEST_URL)
get_filename_component(GTEST_URL "${GTEST_URL}" ABSOLUTE)
else()
- set(GTEST_URL http://mirrors.kodi.tv/build-deps/sources/${ARCHIVE})
+ set(GTEST_URL http://mirrors.kodi.tv/build-deps/sources/${GTEST_ARCHIVE})
endif()
if(VERBOSE)
@@ -38,6 +38,7 @@ if(ENABLE_INTERNAL_GTEST)
externalproject_add(gtest
URL ${GTEST_URL}
+ URL_HASH ${GTEST_HASH}
DOWNLOAD_DIR ${TARBALL_DIR}
PREFIX ${CORE_BUILD_DIR}/gtest
INSTALL_DIR ${CMAKE_BINARY_DIR}/${CORE_BUILD_DIR}
diff --git a/cmake/modules/FindLibDvd.cmake b/cmake/modules/FindLibDvd.cmake
index 27dfaa2980..71f2cea3b6 100644
--- a/cmake/modules/FindLibDvd.cmake
+++ b/cmake/modules/FindLibDvd.cmake
@@ -1,3 +1,28 @@
+# Generic externaproject_add call for windows platforms
+function(windows_externalprojectadd module_name)
+ string(TOUPPER ${module_name} DVDLIB)
+ string(PREPEND DVDLIB "LIB")
+ ExternalProject_Add(${module_name}
+ URL ${${DVDLIB}_URL}
+ URL_HASH ${${DVDLIB}_HASH}
+ DOWNLOAD_DIR ${TARBALL_DIR}
+ DOWNLOAD_NAME ${${DVDLIB}_ARCHIVE}
+ CMAKE_ARGS
+ ${LIBDVD_ADDITIONAL_ARGS}
+ -DCMAKE_PREFIX_PATH:PATH=${CMAKE_BINARY_DIR}/${CORE_BUILD_DIR}/libdvd
+ -DCMAKE_INSTALL_PREFIX:PATH=${CMAKE_BINARY_DIR}/${CORE_BUILD_DIR}/libdvd
+ )
+endfunction()
+
+# Generic autoreconf step
+function(addstep_autoreconf module_name)
+ ExternalProject_Add_Step(${module_name} autoreconf
+ DEPENDEES download update patch
+ DEPENDERS configure
+ COMMAND PATH=${NATIVEPREFIX}/bin:$ENV{PATH} autoreconf -vif
+ WORKING_DIRECTORY <SOURCE_DIR>)
+endfunction()
+
if(KODI_DEPENDSBUILD)
set(_dvdlibs dvdread dvdnav)
set(_handlevars LIBDVD_INCLUDE_DIRS DVDREAD_LIBRARY DVDNAV_LIBRARY)
@@ -43,20 +68,16 @@ if(KODI_DEPENDSBUILD)
mark_as_advanced(LIBDVD_INCLUDE_DIRS LIBDVD_LIBRARIES)
endif()
else()
+ include(cmake/scripts/common/ModuleHelpers.cmake)
+
set(dvdlibs libdvdread libdvdnav)
if(ENABLE_DVDCSS)
list(APPEND dvdlibs libdvdcss)
endif()
set(DEPENDS_TARGETS_DIR ${CMAKE_SOURCE_DIR}/tools/depends/target)
foreach(dvdlib ${dvdlibs})
- file(GLOB VERSION_FILE ${DEPENDS_TARGETS_DIR}/${dvdlib}/DVD*-VERSION)
- file(STRINGS ${VERSION_FILE} VER)
- string(REGEX MATCH "VERSION=[^ ]*$.*" ${dvdlib}_VER "${VER}")
- list(GET ${dvdlib}_VER 0 ${dvdlib}_VER)
- string(SUBSTRING "${${dvdlib}_VER}" 8 -1 ${dvdlib}_VER)
- string(REGEX MATCH "BASE_URL=([^ ]*)" ${dvdlib}_BASE_URL "${VER}")
- list(GET ${dvdlib}_BASE_URL 0 ${dvdlib}_BASE_URL)
- string(SUBSTRING "${${dvdlib}_BASE_URL}" 9 -1 ${dvdlib}_BASE_URL)
+
+ get_archive_name(${dvdlib})
string(TOUPPER ${dvdlib} DVDLIB)
# allow user to override the download URL with a local tarball
@@ -68,7 +89,8 @@ else()
if(${DVDLIB}_URL)
get_filename_component(${DVDLIB}_URL "${${DVDLIB}_URL}" ABSOLUTE)
else()
- set(${DVDLIB}_URL ${${dvdlib}_BASE_URL}/archive/${${dvdlib}_VER}.tar.gz)
+ # github tarball format is tagname.tar.gz where tagname is VERSION in lib VERSION file
+ set(${DVDLIB}_URL ${${DVDLIB}_BASE_URL}/archive/${${DVDLIB}_VER}.tar.gz)
endif()
if(VERBOSE)
message(STATUS "${DVDLIB}_URL: ${${DVDLIB}_URL}")
@@ -78,7 +100,10 @@ else()
set(DVDREAD_CFLAGS "${DVDREAD_CFLAGS} -I${CMAKE_BINARY_DIR}/${CORE_BUILD_DIR}/libdvd/include")
if(APPLE)
- set(CMAKE_LD_FLAGS "-framework IOKit -framework CoreFoundation")
+ string(APPEND CMAKE_EXE_LINKER_FLAGS "-framework CoreFoundation")
+ if(NOT CORE_SYSTEM_NAME STREQUAL darwin_embedded)
+ string(APPEND CMAKE_EXE_LINKER_FLAGS " -framework IOKit")
+ endif()
endif()
set(HOST_ARCH ${ARCH})
@@ -110,7 +135,8 @@ else()
if(NOT CORE_SYSTEM_NAME MATCHES windows)
set(DVDCSS_LIBRARY ${CMAKE_BINARY_DIR}/${CORE_BUILD_DIR}/libdvd/lib/libdvdcss.a)
ExternalProject_Add(dvdcss URL ${LIBDVDCSS_URL}
- DOWNLOAD_NAME libdvdcss-${libdvdcss_VER}.tar.gz
+ URL_HASH ${LIBDVDCSS_HASH}
+ DOWNLOAD_NAME ${LIBDVDCSS_ARCHIVE}
DOWNLOAD_DIR ${TARBALL_DIR}
PREFIX ${CORE_BUILD_DIR}/libdvd
CONFIGURE_COMMAND ac_cv_path_GIT= <SOURCE_DIR>/configure
@@ -124,23 +150,12 @@ else()
--libdir=<INSTALL_DIR>/lib
"CC=${CMAKE_C_COMPILER}"
"CFLAGS=${CMAKE_C_FLAGS} ${DVDREAD_CFLAGS}"
- "LDFLAGS=${CMAKE_LD_FLAGS}"
+ "LDFLAGS=${CMAKE_EXE_LINKER_FLAGS}"
BUILD_COMMAND ${MAKE_COMMAND}
BUILD_BYPRODUCTS ${DVDCSS_LIBRARY})
- ExternalProject_Add_Step(dvdcss autoreconf
- DEPENDEES download update patch
- DEPENDERS configure
- COMMAND PATH=${NATIVEPREFIX}/bin:$ENV{PATH} autoreconf -vif
- WORKING_DIRECTORY <SOURCE_DIR>)
+ addstep_autoreconf("dvdcss")
else()
- ExternalProject_Add(dvdcss
- URL ${LIBDVDCSS_URL}
- DOWNLOAD_DIR ${TARBALL_DIR}
- DOWNLOAD_NAME libdvdcss-${libdvdcss_VER}.tar.gz
- CMAKE_ARGS
- ${LIBDVD_ADDITIONAL_ARGS}
- -DCMAKE_INSTALL_PREFIX:PATH=${CMAKE_BINARY_DIR}/${CORE_BUILD_DIR}/libdvd
- )
+ windows_externalprojectadd("dvdcss")
endif()
set_target_properties(dvdcss PROPERTIES FOLDER "External Projects")
endif()
@@ -153,7 +168,8 @@ else()
if(NOT CORE_SYSTEM_NAME MATCHES windows)
set(DVDREAD_LIBRARY ${CMAKE_BINARY_DIR}/${CORE_BUILD_DIR}/libdvd/lib/libdvdread.a)
ExternalProject_Add(dvdread URL ${LIBDVDREAD_URL}
- DOWNLOAD_NAME libdvdread-${libdvdread_VER}.tar.gz
+ URL_HASH ${LIBDVDREAD_HASH}
+ DOWNLOAD_NAME ${LIBDVDREAD_ARCHIVE}
DOWNLOAD_DIR ${TARBALL_DIR}
PREFIX ${CORE_BUILD_DIR}/libdvd
CONFIGURE_COMMAND ac_cv_path_GIT= <SOURCE_DIR>/configure
@@ -166,24 +182,12 @@ else()
--libdir=<INSTALL_DIR>/lib
"CC=${CMAKE_C_COMPILER}"
"CFLAGS=${CMAKE_C_FLAGS} ${DVDREAD_CFLAGS}"
- "LDFLAGS=${CMAKE_LD_FLAGS}"
+ "LDFLAGS=${CMAKE_EXE_LINKER_FLAGS}"
BUILD_COMMAND ${MAKE_COMMAND}
BUILD_BYPRODUCTS ${DVDREAD_LIBRARY})
- ExternalProject_Add_Step(dvdread autoreconf
- DEPENDEES download update patch
- DEPENDERS configure
- COMMAND PATH=${NATIVEPREFIX}/bin:$ENV{PATH} autoreconf -vif
- WORKING_DIRECTORY <SOURCE_DIR>)
+ addstep_autoreconf("dvdread")
else()
- ExternalProject_Add(dvdread
- URL ${LIBDVDREAD_URL}
- DOWNLOAD_DIR ${TARBALL_DIR}
- DOWNLOAD_NAME libdvdread-${libdvdread_VER}.tar.gz
- CMAKE_ARGS
- ${LIBDVD_ADDITIONAL_ARGS}
- -DCMAKE_PREFIX_PATH:PATH=${CMAKE_BINARY_DIR}/${CORE_BUILD_DIR}/libdvd
- -DCMAKE_INSTALL_PREFIX:PATH=${CMAKE_BINARY_DIR}/${CORE_BUILD_DIR}/libdvd
- )
+ windows_externalprojectadd("dvdread")
endif()
if(ENABLE_DVDCSS)
add_dependencies(dvdread dvdcss)
@@ -198,7 +202,8 @@ else()
if(NOT CORE_SYSTEM_NAME MATCHES windows)
set(DVDNAV_LIBRARY ${CMAKE_BINARY_DIR}/${CORE_BUILD_DIR}/libdvd/lib/libdvdnav.a)
ExternalProject_Add(dvdnav URL ${LIBDVDNAV_URL}
- DOWNLOAD_NAME libdvdnav-${libdvdnav_VER}.tar.gz
+ URL_HASH ${LIBDVDNAV_HASH}
+ DOWNLOAD_NAME ${LIBDVDNAV_ARCHIVE}
DOWNLOAD_DIR ${TARBALL_DIR}
PREFIX ${CORE_BUILD_DIR}/libdvd
CONFIGURE_COMMAND ac_cv_path_GIT= <SOURCE_DIR>/configure
@@ -210,29 +215,17 @@ else()
--prefix=${CMAKE_BINARY_DIR}/${CORE_BUILD_DIR}/libdvd
--libdir=${CMAKE_BINARY_DIR}/${CORE_BUILD_DIR}/libdvd/lib
"CC=${CMAKE_C_COMPILER}"
- "LDFLAGS=${CMAKE_LD_FLAGS} -L${CMAKE_BINARY_DIR}/${CORE_BUILD_DIR}/libdvd/lib"
+ "LDFLAGS=${CMAKE_EXE_LINKER_FLAGS} -L${CMAKE_BINARY_DIR}/${CORE_BUILD_DIR}/libdvd/lib"
"CFLAGS=${CMAKE_C_FLAGS} ${DVDREAD_CFLAGS}"
"DVDREAD_CFLAGS=${DVDREAD_CFLAGS}"
"DVDREAD_LIBS=${CMAKE_BINARY_DIR}/${CORE_BUILD_DIR}/libdvd/lib/libdvdread.la"
"LIBS=${DVDNAV_LIBS}"
BUILD_COMMAND ${MAKE_COMMAND}
BUILD_BYPRODUCTS ${DVDNAV_LIBRARY})
- ExternalProject_Add_Step(dvdnav autoreconf
- DEPENDEES download update patch
- DEPENDERS configure
- COMMAND PATH=${NATIVEPREFIX}/bin:$ENV{PATH} autoreconf -vif
- WORKING_DIRECTORY <SOURCE_DIR>)
+ addstep_autoreconf("dvdnav")
else()
set(DVDNAV_LIBRARY ${CMAKE_BINARY_DIR}/${CORE_BUILD_DIR}/libdvd/lib/libdvdnav.lib)
- ExternalProject_Add(dvdnav
- URL ${LIBDVDNAV_URL}
- DOWNLOAD_DIR ${TARBALL_DIR}
- DOWNLOAD_NAME libdvdnav-${libdvdnav_VER}.tar.gz
- CMAKE_ARGS
- ${LIBDVD_ADDITIONAL_ARGS}
- -DCMAKE_PREFIX_PATH:PATH=${CMAKE_BINARY_DIR}/${CORE_BUILD_DIR}/libdvd
- -DCMAKE_INSTALL_PREFIX:PATH=${CMAKE_BINARY_DIR}/${CORE_BUILD_DIR}/libdvd
- )
+ windows_externalprojectadd("dvdnav")
endif()
add_dependencies(dvdnav dvdread)
set_target_properties(dvdnav PROPERTIES FOLDER "External Projects")
diff --git a/cmake/modules/FindRapidJSON.cmake b/cmake/modules/FindRapidJSON.cmake
index 699d325d19..8dcaf658e0 100644
--- a/cmake/modules/FindRapidJSON.cmake
+++ b/cmake/modules/FindRapidJSON.cmake
@@ -19,7 +19,7 @@ if(ENABLE_INTERNAL_RapidJSON)
if(RapidJSON_URL)
get_filename_component(RapidJSON_URL "${RapidJSON_URL}" ABSOLUTE)
else()
- set(RapidJSON_URL http://mirrors.kodi.tv/build-deps/sources/${ARCHIVE})
+ set(RapidJSON_URL http://mirrors.kodi.tv/build-deps/sources/${RAPIDJSON_ARCHIVE})
endif()
if(VERBOSE)
message(STATUS "RapidJSON_URL: ${RapidJSON_URL}")
@@ -33,6 +33,7 @@ if(ENABLE_INTERNAL_RapidJSON)
set(RapidJSON_INCLUDE_DIR ${CMAKE_BINARY_DIR}/${CORE_BUILD_DIR}/include)
externalproject_add(rapidjson
URL ${RapidJSON_URL}
+ URL_HASH ${RAPIDJSON_HASH}
DOWNLOAD_DIR ${TARBALL_DIR}
PREFIX ${CORE_BUILD_DIR}/rapidjson
CMAKE_ARGS -DCMAKE_INSTALL_PREFIX=${CMAKE_BINARY_DIR}/${CORE_BUILD_DIR}
diff --git a/cmake/modules/FindSpdlog.cmake b/cmake/modules/FindSpdlog.cmake
index aa57d87a78..158d5ff2fa 100644
--- a/cmake/modules/FindSpdlog.cmake
+++ b/cmake/modules/FindSpdlog.cmake
@@ -25,7 +25,7 @@ if(ENABLE_INTERNAL_SPDLOG)
if(SPDLOG_URL)
get_filename_component(SPDLOG_URL "${SPDLOG_URL}" ABSOLUTE)
else()
- set(SPDLOG_URL http://mirrors.kodi.tv/build-deps/sources/${ARCHIVE})
+ set(SPDLOG_URL http://mirrors.kodi.tv/build-deps/sources/${LIBSPDLOG_ARCHIVE})
endif()
if(VERBOSE)
message(STATUS "SPDLOG_URL: ${SPDLOG_URL}")
@@ -40,6 +40,7 @@ if(ENABLE_INTERNAL_SPDLOG)
externalproject_add(spdlog
URL ${SPDLOG_URL}
+ URL_HASH ${SPDLOG_HASH}
DOWNLOAD_DIR ${TARBALL_DIR}
PREFIX ${CORE_BUILD_DIR}/spdlog
CMAKE_ARGS -DCMAKE_INSTALL_PREFIX=${CMAKE_BINARY_DIR}/${CORE_BUILD_DIR}
diff --git a/cmake/modules/FindUdfread.cmake b/cmake/modules/FindUdfread.cmake
index 0223a190fc..61fe00d919 100644
--- a/cmake/modules/FindUdfread.cmake
+++ b/cmake/modules/FindUdfread.cmake
@@ -33,7 +33,7 @@ if(ENABLE_INTERNAL_UDFREAD)
if(UDFREAD_URL)
get_filename_component(UDFREAD_URL "${UDFREAD_URL}" ABSOLUTE)
else()
- set(UDFREAD_URL http://mirrors.kodi.tv/build-deps/sources/${ARCHIVE})
+ set(UDFREAD_URL http://mirrors.kodi.tv/build-deps/sources/${UDFREAD_ARCHIVE})
endif()
if(VERBOSE)
@@ -46,7 +46,8 @@ if(ENABLE_INTERNAL_UDFREAD)
externalproject_add(udfread
URL ${UDFREAD_URL}
- DOWNLOAD_NAME libudfread-${UDFREAD_VER}.tar.gz
+ URL_HASH ${UDFREAD_HASH}
+ DOWNLOAD_NAME ${UDFREAD_ARCHIVE}
DOWNLOAD_DIR ${TARBALL_DIR}
PREFIX ${CORE_BUILD_DIR}/libudfread
CONFIGURE_COMMAND autoreconf -vif &&
diff --git a/cmake/scripts/common/ModuleHelpers.cmake b/cmake/scripts/common/ModuleHelpers.cmake
index 6dd132fd65..03b623a0b7 100644
--- a/cmake/scripts/common/ModuleHelpers.cmake
+++ b/cmake/scripts/common/ModuleHelpers.cmake
@@ -23,6 +23,10 @@ function(get_archive_name module_name)
file(STRINGS ${${UPPER_MODULE_NAME}_FILE} ${UPPER_MODULE_NAME}_ARCHIVE REGEX "^[ \t]*ARCHIVE=")
file(STRINGS ${${UPPER_MODULE_NAME}_FILE} ${UPPER_MODULE_NAME}_BASE_URL REGEX "^[ \t]*BASE_URL=")
+ # Tarball Hash
+ file(STRINGS ${${UPPER_MODULE_NAME}_FILE} ${UPPER_MODULE_NAME}_HASH_SHA256 REGEX "^[ \t]*SHA256=")
+ file(STRINGS ${${UPPER_MODULE_NAME}_FILE} ${UPPER_MODULE_NAME}_HASH_SHA256 REGEX "^[ \t]*SHA512=")
+
string(REGEX REPLACE ".*LIBNAME=([^ \t]*).*" "\\1" ${UPPER_MODULE_NAME}_LNAME "${${UPPER_MODULE_NAME}_LNAME}")
string(REGEX REPLACE ".*VERSION=([^ \t]*).*" "\\1" ${UPPER_MODULE_NAME}_VER "${${UPPER_MODULE_NAME}_VER}")
string(REGEX REPLACE ".*ARCHIVE=([^ \t]*).*" "\\1" ${UPPER_MODULE_NAME}_ARCHIVE "${${UPPER_MODULE_NAME}_ARCHIVE}")
@@ -31,9 +35,16 @@ function(get_archive_name module_name)
string(REGEX REPLACE "\\$\\(LIBNAME\\)" "${${UPPER_MODULE_NAME}_LNAME}" ${UPPER_MODULE_NAME}_ARCHIVE "${${UPPER_MODULE_NAME}_ARCHIVE}")
string(REGEX REPLACE "\\$\\(VERSION\\)" "${${UPPER_MODULE_NAME}_VER}" ${UPPER_MODULE_NAME}_ARCHIVE "${${UPPER_MODULE_NAME}_ARCHIVE}")
- set(ARCHIVE ${${UPPER_MODULE_NAME}_ARCHIVE} PARENT_SCOPE)
+ set(${UPPER_MODULE_NAME}_ARCHIVE ${${UPPER_MODULE_NAME}_ARCHIVE} PARENT_SCOPE)
set(${UPPER_MODULE_NAME}_VER ${${UPPER_MODULE_NAME}_VER} PARENT_SCOPE)
if (${UPPER_MODULE_NAME}_BASE_URL)
set(${UPPER_MODULE_NAME}_BASE_URL ${${UPPER_MODULE_NAME}_BASE_URL} PARENT_SCOPE)
endif()
+
+ if (${UPPER_MODULE_NAME}_HASH_SHA256)
+ set(${UPPER_MODULE_NAME}_HASH ${${UPPER_MODULE_NAME}_HASH_SHA256} PARENT_SCOPE)
+ elseif(${UPPER_MODULE_NAME}_HASH_SHA512)
+ set(${UPPER_MODULE_NAME}_HASH ${${UPPER_MODULE_NAME}_HASH_SHA512} PARENT_SCOPE)
+ endif()
+
endfunction()
diff --git a/project/BuildDependencies/scripts/0_package.target-win10-arm.list b/project/BuildDependencies/scripts/0_package.target-win10-arm.list
index d099a5ab43..3f62cbbb48 100644
--- a/project/BuildDependencies/scripts/0_package.target-win10-arm.list
+++ b/project/BuildDependencies/scripts/0_package.target-win10-arm.list
@@ -8,7 +8,7 @@
;PLEASE KEEP THIS LIST IN ALPHABETICAL ORDER!
crossguid-0.2.2-win10-arm-v141-20200105.7z
curl-7.67.0-win10-arm-v141-20200105.7z
-dav1d-0.7.0-win10-arm-v142-20200529.7z
+dav1d-0.8.2-win10-arm-v142-20210314.7z
flatbuffers-1.11.0-20200105.7z
fmt-6.1.2-win10-arm-v141-20200105.7z
freetype-2.10.1-win10-arm-v141-20200105.7z
diff --git a/project/BuildDependencies/scripts/0_package.target-win10-win32.list b/project/BuildDependencies/scripts/0_package.target-win10-win32.list
index aa151dcd18..9e673128f5 100644
--- a/project/BuildDependencies/scripts/0_package.target-win10-win32.list
+++ b/project/BuildDependencies/scripts/0_package.target-win10-win32.list
@@ -8,7 +8,7 @@
;PLEASE KEEP THIS LIST IN ALPHABETICAL ORDER!
crossguid-0.2.2-win10-win32-v141-20200105.7z
curl-7.67.0-win10-win32-v141-20200105.7z
-dav1d-0.7.0-win10-win32-v142-20200529.7z
+dav1d-0.8.2-win10-win32-v142-20210314.7z
flatbuffers-1.11.0-20200105.7z
fmt-6.1.2-win10-win32-v141-20200105.7z
freetype-2.10.1-win10-win32-v141-20200105.7z
diff --git a/project/BuildDependencies/scripts/0_package.target-win10-x64.list b/project/BuildDependencies/scripts/0_package.target-win10-x64.list
index b5fc92a00d..a872f62127 100644
--- a/project/BuildDependencies/scripts/0_package.target-win10-x64.list
+++ b/project/BuildDependencies/scripts/0_package.target-win10-x64.list
@@ -8,7 +8,7 @@
;PLEASE KEEP THIS LIST IN ALPHABETICAL ORDER!
crossguid-0.2.2-win10-x64-v141-20200105.7z
curl-7.67.0-win10-x64-v141-20200105.7z
-dav1d-0.7.0-win10-x64-v142-20200529.7z
+dav1d-0.8.2-win10-x64-v142-20210314.7z
flatbuffers-1.11.0-20200105.7z
fmt-6.1.2-win10-x64-v141-20200105.7z
freetype-2.10.1-win10-x64-v141-20200105.7z
diff --git a/project/BuildDependencies/scripts/0_package.target-win32.list b/project/BuildDependencies/scripts/0_package.target-win32.list
index 63908c2b08..b39ade8103 100644
--- a/project/BuildDependencies/scripts/0_package.target-win32.list
+++ b/project/BuildDependencies/scripts/0_package.target-win32.list
@@ -8,7 +8,7 @@
;PLEASE KEEP THIS LIST IN ALPHABETICAL ORDER!
crossguid-0.2.2-win32-v141-20200105.7z
curl-7.67.0-win32-v141-20200105.7z
-dav1d-0.7.0-win32-v142-20200529.7z
+dav1d-0.8.2-win32-v142-20210314.7z
detours-64ec13-win32-v141-20200105.7z
dnssd-878.260.1-win32-v141-20200105.7z
flatbuffers-1.11.0-20200105.7z
diff --git a/project/BuildDependencies/scripts/0_package.target-x64.list b/project/BuildDependencies/scripts/0_package.target-x64.list
index 17ad6c221d..30c72eb442 100644
--- a/project/BuildDependencies/scripts/0_package.target-x64.list
+++ b/project/BuildDependencies/scripts/0_package.target-x64.list
@@ -8,7 +8,7 @@
;PLEASE KEEP THIS LIST IN ALPHABETICAL ORDER!
crossguid-0.2.2-x64-v141-20200105.7z
curl-7.67.0-x64-v141-20200105.7z
-dav1d-0.7.0-x64-v142-20200529.7z
+dav1d-0.8.2-x64-v142-20210314.7z
detours-64ec13-x64-v141-20200105.7z
dnssd-878.260.1-x64-v141-20200105.7z
flatbuffers-1.11.0-20200105.7z
diff --git a/system/settings/linux.xml b/system/settings/linux.xml
index 1f729fc60f..531974f3f4 100644
--- a/system/settings/linux.xml
+++ b/system/settings/linux.xml
@@ -137,6 +137,18 @@
<default>true</default>
<control type="toggle" />
</setting>
+ <setting id="videoplayer.usevaapiav1" type="boolean" parent="videoplayer.usevaapi" label="13468" help="13469">
+ <requirement>HAVE_LIBVA</requirement>
+ <visible>false</visible>
+ <dependencies>
+ <dependency type="enable">
+ <condition setting="videoplayer.usevaapi" operator="is">true</condition>
+ </dependency>
+ </dependencies>
+ <level>3</level>
+ <default>true</default>
+ <control type="toggle" />
+ </setting>
<setting id="videoplayer.prefervaapirender" type="boolean" parent="videoplayer.usevaapi" label="13457" help="36433">
<requirement>HAVE_LIBVA</requirement>
<visible>false</visible>
diff --git a/tools/android/packaging/xbmc/res/values-be-rby/strings.xml b/tools/android/packaging/xbmc/res/values-be-rby/strings.xml
index efe0a1d8ee..98c0e7122c 100644
--- a/tools/android/packaging/xbmc/res/values-be-rby/strings.xml
+++ b/tools/android/packaging/xbmc/res/values-be-rby/strings.xml
@@ -1,3 +1,4 @@
<?xml version="1.0" encoding="utf-8"?>
<resources>
- </resources> \ No newline at end of file
+ <string name="suggestion_channel">Прапановы</string>
+</resources> \ No newline at end of file
diff --git a/tools/buildsteps/windows/patches/0001-ffmpeg-windows-configure-detect-openssl.patch b/tools/buildsteps/windows/patches/0001-ffmpeg-windows-configure-detect-openssl.patch
index 1c17b29491..b8e5b2f7e1 100644
--- a/tools/buildsteps/windows/patches/0001-ffmpeg-windows-configure-detect-openssl.patch
+++ b/tools/buildsteps/windows/patches/0001-ffmpeg-windows-configure-detect-openssl.patch
@@ -11,7 +11,7 @@ diff --git a/configure b/configure
index d7a3f507e8..4b85e881b1 100755
--- a/configure
+++ b/configure
-@@ -6529,6 +6529,8 @@ enabled openssl && { check_pkg_config openssl openssl openssl/ssl.h OP
+@@ -6530,6 +6530,8 @@ enabled openssl && { check_pkg_config openssl openssl openssl/ssl.h OP
check_lib openssl openssl/ssl.h SSL_library_init -lssl -lcrypto ||
check_lib openssl openssl/ssl.h SSL_library_init -lssl32 -leay32 ||
check_lib openssl openssl/ssl.h SSL_library_init -lssl -lcrypto -lws2_32 -lgdi32 ||
diff --git a/tools/buildsteps/windows/patches/0003-ffmpeg-windows-configure-allow-building-static.patch b/tools/buildsteps/windows/patches/0003-ffmpeg-windows-configure-allow-building-static.patch
index f6fbd3fe3e..bbb3e0a9f6 100644
--- a/tools/buildsteps/windows/patches/0003-ffmpeg-windows-configure-allow-building-static.patch
+++ b/tools/buildsteps/windows/patches/0003-ffmpeg-windows-configure-allow-building-static.patch
@@ -11,7 +11,7 @@ diff --git a/configure b/configure
index da457705d1..e3a8f45ff4 100755
--- a/configure
+++ b/configure
-@@ -5439,6 +5439,8 @@ case $target_os in
+@@ -5440,6 +5440,8 @@ case $target_os in
enabled shared && ! enabled small && test_cmd $windres --version && enable gnu_windres
enabled x86_32 && check_ldflags -Wl,--large-address-aware
shlibdir_default="$bindir_default"
@@ -20,7 +20,7 @@ index da457705d1..e3a8f45ff4 100755
SLIBPREF=""
SLIBSUF=".dll"
SLIBNAME_WITH_VERSION='$(SLIBPREF)$(FULLNAME)-$(LIBVERSION)$(SLIBSUF)'
-@@ -5488,6 +5490,8 @@ case $target_os in
+@@ -5489,6 +5491,8 @@ case $target_os in
fi
enabled x86_32 && check_ldflags -LARGEADDRESSAWARE
shlibdir_default="$bindir_default"
diff --git a/tools/buildsteps/windows/patches/0004-ffmpeg-windows-configure-detect-libdav1d.patch b/tools/buildsteps/windows/patches/0004-ffmpeg-windows-configure-detect-libdav1d.patch
index d949b57854..617c87a8b0 100644
--- a/tools/buildsteps/windows/patches/0004-ffmpeg-windows-configure-detect-libdav1d.patch
+++ b/tools/buildsteps/windows/patches/0004-ffmpeg-windows-configure-detect-libdav1d.patch
@@ -11,7 +11,7 @@ diff --git a/configure b/configure
index e3a8f45ff4..983d7e1078 100755
--- a/configure
+++ b/configure
-@@ -6357,7 +6357,7 @@ enabled libcelt && require libcelt celt/celt.h celt_decode -lcelt0 &&
+@@ -6358,7 +6358,7 @@ enabled libcelt && require libcelt celt/celt.h celt_decode -lcelt0 &&
die "ERROR: libcelt must be installed and version must be >= 0.11.0."; }
enabled libcaca && require_pkg_config libcaca caca caca.h caca_create_canvas
enabled libcodec2 && require libcodec2 codec2/codec2.h codec2_create -lcodec2
diff --git a/tools/depends/README.md b/tools/depends/README.md
index 2e5db17886..64fb3f0aa1 100644
--- a/tools/depends/README.md
+++ b/tools/depends/README.md
@@ -48,9 +48,9 @@ Paths below are examples. If you want to build Kodi, follow our **[build guides]
### Linux
**ARM (codesourcery/lenaro/etc)**
-`./configure --with-toolchain=/opt/toolchains/my-example-toolchain/ --prefix=/opt/xbmc-deps --host=arm-linux-gnueabi`
+`./configure --with-toolchain=/opt/toolchains/my-example-toolchain/ --prefix=/opt/xbmc-deps --host=arm-linux-gnueabi --with-rendersystem=gles`
**Native**
-`./configure --with-toolchain=/usr --prefix=/opt/xbmc-deps --host=x86_64-linux-gnu`
+`./configure --with-toolchain=/usr --prefix=/opt/xbmc-deps --host=x86_64-linux-gnu --with-rendersystem=gl`
Cross compiling is a PITA.
diff --git a/tools/depends/configure.ac b/tools/depends/configure.ac
index 0a741a187c..341fe395de 100644
--- a/tools/depends/configure.ac
+++ b/tools/depends/configure.ac
@@ -504,9 +504,9 @@ if test -z $use_tarballs; then
use_tarballs=$prefix/xbmc-tarballs
fi
-if test -n "$app_rendersystem"; then
+if test "$platform_os" == "linux"; then
if test "$app_rendersystem" != "gl" && test "$app_rendersystem" != "gles"; then
- AC_MSG_ERROR(Rendersystem must be gl or gles)
+ AC_MSG_ERROR(Rendersystem is required for linux - must be gl or gles)
fi
fi
diff --git a/tools/depends/target/Toolchain_binaddons.cmake.in b/tools/depends/target/Toolchain_binaddons.cmake.in
index bc2521b9ce..6b9ce80620 100644
--- a/tools/depends/target/Toolchain_binaddons.cmake.in
+++ b/tools/depends/target/Toolchain_binaddons.cmake.in
@@ -83,11 +83,11 @@ set(CMAKE_CXX_FLAGS_RELEASE "@platform_cxxflags_release@ @platform_includes@")
set(CMAKE_C_FLAGS_DEBUG "@platform_cflags_debug@ @platform_includes@")
set(CMAKE_CXX_FLAGS_DEBUG "@platform_cxxflags_debug@ @platform_includes@")
set(CMAKE_CPP_FLAGS "@platform_cflags@ @platform_includes@")
-set(CMAKE_LD_FLAGS "@platform_ldflags@")
+set(CMAKE_EXE_LINKER_FLAGS "@platform_ldflags@")
set(ENV{CFLAGS} ${CMAKE_C_FLAGS})
set(ENV{CXXFLAGS} ${CMAKE_CXX_FLAGS})
set(ENV{CPPFLAGS} ${CMAKE_CPP_FLAGS})
-set(ENV{LDFLAGS} ${CMAKE_LD_FLAGS})
+set(ENV{LDFLAGS} ${CMAKE_EXE_LINKER_FLAGS})
# search for programs in the build host directories
set(CMAKE_FIND_ROOT_PATH_MODE_PROGRAM NEVER)
# for libraries and headers in the target directories
diff --git a/tools/depends/target/crossguid/CROSSGUID-VERSION b/tools/depends/target/crossguid/CROSSGUID-VERSION
index dc16e8e0e5..ce42659a85 100644
--- a/tools/depends/target/crossguid/CROSSGUID-VERSION
+++ b/tools/depends/target/crossguid/CROSSGUID-VERSION
@@ -1,3 +1,4 @@
LIBNAME=crossguid
VERSION=8f399e8bd4
ARCHIVE=$(LIBNAME)-$(VERSION).tar.gz
+SHA512=2682d63609d3dcdfcd8136be632e45df26ad88ce93b9c49745cf728bbd2e6254a7b05c8b059ab581d532372e504206a525a52564b64d076dfdae9c965a09fd16
diff --git a/tools/depends/target/dav1d/DAV1D-VERSION b/tools/depends/target/dav1d/DAV1D-VERSION
index 2f9f91f2eb..ddaaa2af9e 100644
--- a/tools/depends/target/dav1d/DAV1D-VERSION
+++ b/tools/depends/target/dav1d/DAV1D-VERSION
@@ -1,3 +1,4 @@
LIBNAME=dav1d
VERSION=0.9.2
ARCHIVE=$(LIBNAME)-$(VERSION).tar.bz2
+SHA512=adfb822734a3fc8b73e9cf5f757bfd78fb144b00d95f1e942254c5caf1d801b05438d39571486ef37a94d2226166937fc56160a862e8d6d45c4f6d790531dc3f
diff --git a/tools/depends/target/ffmpeg/FFMPEG-VERSION b/tools/depends/target/ffmpeg/FFMPEG-VERSION
index 6a44db8f0f..2c9eda8750 100644
--- a/tools/depends/target/ffmpeg/FFMPEG-VERSION
+++ b/tools/depends/target/ffmpeg/FFMPEG-VERSION
@@ -1,4 +1,5 @@
LIBNAME=ffmpeg
BASE_URL=https://github.com/xbmc/FFmpeg
-VERSION=4.4-N-Alpha1
+VERSION=4.4.1-Nexus-Alpha1
ARCHIVE=$(LIBNAME)-$(VERSION).tar.gz
+SHA512=8beb04d577b5251e74b0d52f4d130997a8ba94bbd488c7c8309e6b45095c27807e150212888ce3a384b23dff52f8df1a7bde5407bae924ddc363f8125c0616c5
diff --git a/tools/depends/target/flatbuffers/FLATBUFFERS-VERSION b/tools/depends/target/flatbuffers/FLATBUFFERS-VERSION
index 1d983d6159..4d05761cfa 100644
--- a/tools/depends/target/flatbuffers/FLATBUFFERS-VERSION
+++ b/tools/depends/target/flatbuffers/FLATBUFFERS-VERSION
@@ -1,3 +1,4 @@
LIBNAME=flatbuffers
VERSION=2.0.0
ARCHIVE=$(LIBNAME)-$(VERSION).tar.gz
+SHA512=26a06b572c0e4c9685743bd2d2162ac7dcd74b9324624cc3f3ef5b154c0cee7c52a04b77cdc184245d2d6ae38dfdcc4fd66001c318aa8ca001d2bf1d85d66a89
diff --git a/tools/depends/target/googletest/GOOGLETEST-VERSION b/tools/depends/target/googletest/GOOGLETEST-VERSION
index af9cb9d2ae..baa73efc7f 100644
--- a/tools/depends/target/googletest/GOOGLETEST-VERSION
+++ b/tools/depends/target/googletest/GOOGLETEST-VERSION
@@ -1,3 +1,4 @@
LIBNAME=googletest
VERSION=1.10.0
ARCHIVE=$(LIBNAME)-$(VERSION).tar.gz
+SHA512=bd52abe938c3722adc2347afad52ea3a17ecc76730d8d16b065e165bc7477d762bce0997a427131866a89f1001e3f3315198204ffa5d643a9355f1f4d0d7b1a9
diff --git a/tools/depends/target/libdvdcss/DVDCSS-VERSION b/tools/depends/target/libdvdcss/DVDCSS-VERSION
deleted file mode 100644
index 43afb9b093..0000000000
--- a/tools/depends/target/libdvdcss/DVDCSS-VERSION
+++ /dev/null
@@ -1,4 +0,0 @@
-LIBNAME=libdvdcss
-BASE_URL=https://github.com/xbmc/libdvdcss
-VERSION=1.4.2-Leia-Beta-5
-
diff --git a/tools/depends/target/libdvdcss/LIBDVDCSS-VERSION b/tools/depends/target/libdvdcss/LIBDVDCSS-VERSION
new file mode 100644
index 0000000000..ea216b313c
--- /dev/null
+++ b/tools/depends/target/libdvdcss/LIBDVDCSS-VERSION
@@ -0,0 +1,5 @@
+LIBNAME=libdvdcss
+BASE_URL=https://github.com/xbmc/libdvdcss
+VERSION=1.4.2-Leia-Beta-5
+ARCHIVE=$(LIBNAME)-$(VERSION).tar.gz
+SHA512=5185dbdbeb1bd13ea9d8723f1f4ab599d6f3102f5ba1096cd085aa1cda252c045f327c719227bba8e1b742352ade5e335106c8d0c1637a5a6b93ce661620dd7e
diff --git a/tools/depends/target/libdvdcss/Makefile b/tools/depends/target/libdvdcss/Makefile
index a5026227c2..caa51bb3da 100644
--- a/tools/depends/target/libdvdcss/Makefile
+++ b/tools/depends/target/libdvdcss/Makefile
@@ -1,6 +1,6 @@
-include ../../Makefile.include
-include DVDCSS-VERSION
-DEPS= DVDCSS-VERSION Makefile
+include LIBDVDCSS-VERSION
+DEPS= LIBDVDCSS-VERSION Makefile
ifeq ($(CROSS_COMPILING), yes)
DEPS += ../../Makefile.include
diff --git a/tools/depends/target/libdvdnav/DVDNAV-VERSION b/tools/depends/target/libdvdnav/DVDNAV-VERSION
deleted file mode 100644
index 818cf066a3..0000000000
--- a/tools/depends/target/libdvdnav/DVDNAV-VERSION
+++ /dev/null
@@ -1,4 +0,0 @@
-LIBNAME=libdvdnav
-BASE_URL=https://github.com/xbmc/libdvdnav
-VERSION=6.0.0-Leia-Alpha-3
-
diff --git a/tools/depends/target/libdvdnav/LIBDVDNAV-VERSION b/tools/depends/target/libdvdnav/LIBDVDNAV-VERSION
new file mode 100644
index 0000000000..bea00de9bd
--- /dev/null
+++ b/tools/depends/target/libdvdnav/LIBDVDNAV-VERSION
@@ -0,0 +1,5 @@
+LIBNAME=libdvdnav
+BASE_URL=https://github.com/xbmc/libdvdnav
+VERSION=6.0.0-Leia-Alpha-3
+ARCHIVE=$(LIBNAME)-$(VERSION).tar.gz
+SHA512=11c93eaacd156f8fd7dec7c43d366438b201f31ad55b2870463a9e286912b6ada08882319a021fb7992190f87b909a49f2b83e0321cc17aedc29f7fe5898fa72
diff --git a/tools/depends/target/libdvdnav/Makefile b/tools/depends/target/libdvdnav/Makefile
index eada58a160..62385a3049 100644
--- a/tools/depends/target/libdvdnav/Makefile
+++ b/tools/depends/target/libdvdnav/Makefile
@@ -1,6 +1,6 @@
-include ../../Makefile.include
-include DVDNAV-VERSION
-DEPS = DVDNAV-VERSION Makefile
+include LIBDVDNAV-VERSION
+DEPS = LIBDVDNAV-VERSION Makefile
# configuration settings
config = --prefix=$(PREFIX) --disable-shared --enable-static --with-pic
diff --git a/tools/depends/target/libdvdread/DVDREAD-VERSION b/tools/depends/target/libdvdread/DVDREAD-VERSION
deleted file mode 100644
index eea4c74c74..0000000000
--- a/tools/depends/target/libdvdread/DVDREAD-VERSION
+++ /dev/null
@@ -1,4 +0,0 @@
-LIBNAME=libdvdread
-BASE_URL=https://github.com/xbmc/libdvdread
-VERSION=6.0.0-Leia-Alpha-3
-
diff --git a/tools/depends/target/libdvdread/LIBDVDREAD-VERSION b/tools/depends/target/libdvdread/LIBDVDREAD-VERSION
new file mode 100644
index 0000000000..bf60a8c850
--- /dev/null
+++ b/tools/depends/target/libdvdread/LIBDVDREAD-VERSION
@@ -0,0 +1,5 @@
+LIBNAME=libdvdread
+BASE_URL=https://github.com/xbmc/libdvdread
+VERSION=6.0.0-Leia-Alpha-3
+ARCHIVE=$(LIBNAME)-$(VERSION).tar.gz
+SHA512=b3419ba0a1a2dd70f1bb6236afdfe1c6e88c9ad4264198b289e3bba9375e077cecf7f89848c7b09debaa445327f3507101f3d157e692f7a7163b2bb52643e1e7
diff --git a/tools/depends/target/libdvdread/Makefile b/tools/depends/target/libdvdread/Makefile
index d240953fe4..2a2bf32ceb 100644
--- a/tools/depends/target/libdvdread/Makefile
+++ b/tools/depends/target/libdvdread/Makefile
@@ -1,6 +1,6 @@
-include ../../Makefile.include
-include DVDREAD-VERSION
-DEPS = DVDREAD-VERSION Makefile
+include LIBDVDREAD-VERSION
+DEPS = LIBDVDREAD-VERSION Makefile
# configuration settings
config = --prefix=$(PREFIX) --disable-shared --enable-static --with-pic --with-libdvdcss
diff --git a/tools/depends/target/libfmt/LIBFMT-VERSION b/tools/depends/target/libfmt/LIBFMT-VERSION
index f55e9c1f79..0a69a8a7e7 100644
--- a/tools/depends/target/libfmt/LIBFMT-VERSION
+++ b/tools/depends/target/libfmt/LIBFMT-VERSION
@@ -1,3 +1,4 @@
LIBNAME=fmt
VERSION=8.0.1
ARCHIVE=$(LIBNAME)-$(VERSION).tar.gz
+SHA512=643e68d5b2e0e9c83231ab2b0036596a6297b1d9ed6bd7b1172bee4ff134c8af8f09174c06c94225132c1b635b0977ea4ce783748d7bd76a9a0b5ad597456c84
diff --git a/tools/depends/target/libfstrcmp/LIBFSTRCMP-VERSION b/tools/depends/target/libfstrcmp/LIBFSTRCMP-VERSION
index 40ff7c4ab5..87b85918ae 100644
--- a/tools/depends/target/libfstrcmp/LIBFSTRCMP-VERSION
+++ b/tools/depends/target/libfstrcmp/LIBFSTRCMP-VERSION
@@ -1,3 +1,4 @@
LIBNAME=fstrcmp
VERSION=0.7.D001
ARCHIVE=$(LIBNAME)-$(VERSION).tar.gz
+SHA512=aaeb0227afd5ada5955cbe6a565254ff88d2028d677d199c00e03b7cb5de1f2c69b18e6e8b032e452350a8eda7081807b01765adbeb8476eaf803d9de6e5509c
diff --git a/tools/depends/target/libspdlog/LIBSPDLOG-VERSION b/tools/depends/target/libspdlog/LIBSPDLOG-VERSION
index 46a5037af0..afefe203d5 100644
--- a/tools/depends/target/libspdlog/LIBSPDLOG-VERSION
+++ b/tools/depends/target/libspdlog/LIBSPDLOG-VERSION
@@ -1,3 +1,4 @@
LIBNAME=spdlog
VERSION=1.9.2
ARCHIVE=$(LIBNAME)-$(VERSION).tar.gz
+SHA512=87b12a792cf2d740ef29db4b6055788a487b6d474662b878711b8a5534efea5f0d97b6ac357834500b66cc65e1ba8934446a695e9691fd5d4b95397b6871555c
diff --git a/tools/depends/target/libudfread/LIBUDFREAD-VERSION b/tools/depends/target/libudfread/LIBUDFREAD-VERSION
index 53446a22ab..b5f96528ad 100644
--- a/tools/depends/target/libudfread/LIBUDFREAD-VERSION
+++ b/tools/depends/target/libudfread/LIBUDFREAD-VERSION
@@ -1,3 +1,4 @@
LIBNAME=libudfread
VERSION=1.1.2
ARCHIVE=$(LIBNAME)-$(VERSION).tar.gz
+SHA512=340a03fe90d26a8a5c78e1e4f558a0b448a14332a661494f44af7de3e6c98cd219125e19f69d2a611ecb4870648a5d5b55d794e665eb8ec4192c0b499a0701ed
diff --git a/tools/depends/target/rapidjson/RAPIDJSON-VERSION b/tools/depends/target/rapidjson/RAPIDJSON-VERSION
index 8440f69ac0..120e868fca 100644
--- a/tools/depends/target/rapidjson/RAPIDJSON-VERSION
+++ b/tools/depends/target/rapidjson/RAPIDJSON-VERSION
@@ -1,3 +1,4 @@
LIBNAME=rapidjson
VERSION=1.1.0
ARCHIVE=$(LIBNAME)-$(VERSION).tar.gz
+SHA512=2e82a4bddcd6c4669541f5945c2d240fb1b4fdd6e239200246d3dd50ce98733f0a4f6d3daa56f865d8c88779c036099c52a9ae85d47ad263686b68a88d832dff
diff --git a/xbmc/Application.cpp b/xbmc/Application.cpp
index cc517af9ce..4386f6ff7c 100644
--- a/xbmc/Application.cpp
+++ b/xbmc/Application.cpp
@@ -909,7 +909,7 @@ void CApplication::OnSettingAction(const std::shared_ptr<const CSetting>& settin
if (CServiceBroker::GetAddonMgr().GetAddon(
CServiceBroker::GetSettingsComponent()->GetSettings()->GetString(
CSettings::SETTING_SCREENSAVER_MODE),
- addon, ADDON_SCREENSAVER, OnlyEnabled::YES))
+ addon, ADDON_SCREENSAVER, OnlyEnabled::CHOICE_YES))
CGUIDialogAddonSettings::ShowForAddon(addon);
}
else if (settingId == CSettings::SETTING_AUDIOCDS_SETTINGS)
@@ -918,7 +918,7 @@ void CApplication::OnSettingAction(const std::shared_ptr<const CSetting>& settin
if (CServiceBroker::GetAddonMgr().GetAddon(
CServiceBroker::GetSettingsComponent()->GetSettings()->GetString(
CSettings::SETTING_AUDIOCDS_ENCODER),
- addon, ADDON_AUDIOENCODER, OnlyEnabled::YES))
+ addon, ADDON_AUDIOENCODER, OnlyEnabled::CHOICE_YES))
CGUIDialogAddonSettings::ShowForAddon(addon);
}
else if (settingId == CSettings::SETTING_VIDEOSCREEN_GUICALIBRATION)
@@ -989,8 +989,8 @@ void CApplication::ReloadSkin(bool confirm/*=false*/)
user as to whether they want to keep the current skin. */
if (confirm && m_confirmSkinChange)
{
- if (HELPERS::ShowYesNoDialogText(CVariant{13123}, CVariant{13111}, CVariant{""}, CVariant{""}, 10000) !=
- DialogResponse::YES)
+ if (HELPERS::ShowYesNoDialogText(CVariant{13123}, CVariant{13111}, CVariant{""}, CVariant{""},
+ 10000) != DialogResponse::CHOICE_YES)
{
m_confirmSkinChange = false;
settings->SetString(CSettings::SETTING_LOOKANDFEEL_SKIN, oldSkin);
@@ -1057,7 +1057,7 @@ bool CApplication::LoadSkin(const std::string& skinID)
SkinPtr skin;
{
AddonPtr addon;
- if (!CServiceBroker::GetAddonMgr().GetAddon(skinID, addon, ADDON_SKIN, OnlyEnabled::YES))
+ if (!CServiceBroker::GetAddonMgr().GetAddon(skinID, addon, ADDON_SKIN, OnlyEnabled::CHOICE_YES))
return false;
skin = std::static_pointer_cast<ADDON::CSkinInfo>(addon);
}
@@ -1316,8 +1316,16 @@ bool CApplication::LoadCustomWindows()
if (StringUtils::EqualsNoCase(strType, "dialog"))
{
+ DialogModalityType modality = DialogModalityType::MODAL;
hasVisibleCondition = pRootElement->FirstChildElement("visible") != nullptr;
- pWindow = new CGUIDialog(windowId, skinFile);
+ // By default dialogs that have visible conditions are considered modeless unless explicitly
+ // set to "modal" by the skinner using the "modality" attribute in the root XML element of the window
+ if (hasVisibleCondition &&
+ (!pRootElement->Attribute("modality") ||
+ !StringUtils::EqualsNoCase(pRootElement->Attribute("modality"), "modal")))
+ modality = DialogModalityType::MODELESS;
+
+ pWindow = new CGUIDialog(windowId, skinFile, modality);
}
else if (StringUtils::EqualsNoCase(strType, "submenu"))
{
@@ -2655,7 +2663,7 @@ bool CApplication::PlayMedia(CFileItem& item, const std::string &player, int iPl
{
AddonPtr addon;
if (CServiceBroker::GetAddonMgr().GetAddon(path.GetHostName(), addon, ADDON_GAMEDLL,
- OnlyEnabled::YES))
+ OnlyEnabled::CHOICE_YES))
{
CFileItem addonItem(addon);
return PlayFile(addonItem, player, false);
@@ -3618,7 +3626,7 @@ void CApplication::ActivateScreenSaver(bool forceType /*= false */)
return;
}
else if (CServiceBroker::GetAddonMgr().GetAddon(m_screensaverIdInUse, m_pythonScreenSaver,
- ADDON_SCREENSAVER, OnlyEnabled::YES))
+ ADDON_SCREENSAVER, OnlyEnabled::CHOICE_YES))
{
std::string libPath = m_pythonScreenSaver->LibPath();
if (CScriptInvocationManager::GetInstance().HasLanguageInvoker(libPath))
@@ -4052,7 +4060,7 @@ void CApplication::ConfigureAndEnableAddons()
{
if (HELPERS::ShowYesNoDialogLines(CVariant{24039}, // Disabled add-ons
CVariant{24059}, // Would you like to enable this add-on?
- CVariant{addon->Name()}) == DialogResponse::YES)
+ CVariant{addon->Name()}) == DialogResponse::CHOICE_YES)
{
if (addon->HasSettings())
{
diff --git a/xbmc/Autorun.cpp b/xbmc/Autorun.cpp
index bc2de7965c..000dc2073a 100644
--- a/xbmc/Autorun.cpp
+++ b/xbmc/Autorun.cpp
@@ -508,9 +508,10 @@ bool CAutorun::IsEnabled() const
bool CAutorun::PlayDiscAskResume(const std::string& path)
{
- return PlayDisc(path, true, !CanResumePlayDVD(path) ||
- HELPERS::ShowYesNoDialogText(CVariant{341}, CVariant{""}, CVariant{13404}, CVariant{12021}) ==
- DialogResponse::YES);
+ return PlayDisc(path, true,
+ !CanResumePlayDVD(path) ||
+ HELPERS::ShowYesNoDialogText(CVariant{341}, CVariant{""}, CVariant{13404},
+ CVariant{12021}) == DialogResponse::CHOICE_YES);
}
bool CAutorun::CanResumePlayDVD(const std::string& path)
diff --git a/xbmc/ContextMenuItem.cpp b/xbmc/ContextMenuItem.cpp
index cf7794309b..a6c92657da 100644
--- a/xbmc/ContextMenuItem.cpp
+++ b/xbmc/ContextMenuItem.cpp
@@ -48,7 +48,7 @@ bool CContextMenuItem::Execute(const CFileItemPtr& item) const
ADDON::AddonPtr addon;
if (!CServiceBroker::GetAddonMgr().GetAddon(m_addonId, addon, ADDON::ADDON_UNKNOWN,
- ADDON::OnlyEnabled::YES))
+ ADDON::OnlyEnabled::CHOICE_YES))
return false;
bool reuseLanguageInvoker = false;
diff --git a/xbmc/ContextMenuManager.cpp b/xbmc/ContextMenuManager.cpp
index 77ebdcc885..3b8441a49d 100644
--- a/xbmc/ContextMenuManager.cpp
+++ b/xbmc/ContextMenuManager.cpp
@@ -121,7 +121,7 @@ void CContextMenuManager::OnEvent(const ADDON::AddonEvent& event)
else if (typeid(event) == typeid(AddonEvents::Enabled))
{
AddonPtr addon;
- if (m_addonMgr.GetAddon(event.id, addon, ADDON_CONTEXT_ITEM, OnlyEnabled::YES))
+ if (m_addonMgr.GetAddon(event.id, addon, ADDON_CONTEXT_ITEM, OnlyEnabled::CHOICE_YES))
{
CSingleLock lock(m_criticalSection);
auto items = std::static_pointer_cast<CContextMenuAddon>(addon)->GetItems();
diff --git a/xbmc/GUIInfoManager.cpp b/xbmc/GUIInfoManager.cpp
index c28bc0ed0d..553c91424e 100644
--- a/xbmc/GUIInfoManager.cpp
+++ b/xbmc/GUIInfoManager.cpp
@@ -5844,11 +5844,14 @@ const infomap container_str[] = {{ "property", CONTAINER_PROPERTY },
/// \anchor ListItem_VideoAspect
/// _string_,
/// @return The aspect ratio of the currently selected video. Possible values:
+/// - <b>1.00</b>
+/// - <b>1.19</b>
/// - <b>1.33</b>
/// - <b>1.37</b>
/// - <b>1.66</b>
/// - <b>1.78</b>
/// - <b>1.85</b>
+/// - <b>2.00</b>
/// - <b>2.20</b>
/// - <b>2.35</b>
/// - <b>2.40</b>
diff --git a/xbmc/LangInfo.cpp b/xbmc/LangInfo.cpp
index 24f0419cfe..20a5c3e5b5 100644
--- a/xbmc/LangInfo.cpp
+++ b/xbmc/LangInfo.cpp
@@ -662,7 +662,7 @@ LanguageResourcePtr CLangInfo::GetLanguageAddon(const std::string& locale /* = "
ADDON::AddonPtr addon;
if (CServiceBroker::GetAddonMgr().GetAddon(addonId, addon, ADDON::ADDON_RESOURCE_LANGUAGE,
- ADDON::OnlyEnabled::YES) &&
+ ADDON::OnlyEnabled::CHOICE_YES) &&
addon != NULL)
return std::dynamic_pointer_cast<ADDON::CLanguageResource>(addon);
@@ -687,7 +687,8 @@ bool CLangInfo::SetLanguage(std::string language /* = "" */, bool reloadServices
ADDON::AddonPtr addon;
// Find the chosen language add-on if it's enabled
- if (!addonMgr.GetAddon(language, addon, ADDON::ADDON_RESOURCE_LANGUAGE, ADDON::OnlyEnabled::YES))
+ if (!addonMgr.GetAddon(language, addon, ADDON::ADDON_RESOURCE_LANGUAGE,
+ ADDON::OnlyEnabled::CHOICE_YES))
{
if (!addonMgr.IsAddonInstalled(language) ||
(addonMgr.IsAddonDisabled(language) && !addonMgr.EnableAddon(language)))
@@ -701,7 +702,7 @@ bool CLangInfo::SetLanguage(std::string language /* = "" */, bool reloadServices
->GetDefault();
if (!addonMgr.GetAddon(language, addon, ADDON::ADDON_RESOURCE_LANGUAGE,
- ADDON::OnlyEnabled::NO))
+ ADDON::OnlyEnabled::CHOICE_NO))
{
CLog::Log(LOGFATAL, "CLangInfo::{}: could not find default language add-on '{}'", __func__,
language);
diff --git a/xbmc/addons/AddonInstaller.cpp b/xbmc/addons/AddonInstaller.cpp
index 4a80be261c..8756329870 100644
--- a/xbmc/addons/AddonInstaller.cpp
+++ b/xbmc/addons/AddonInstaller.cpp
@@ -160,7 +160,7 @@ bool CAddonInstaller::InstallModal(const std::string& addonID,
return false;
// we assume that addons that are enabled don't get to this routine (i.e. that GetAddon() has been called)
- if (CServiceBroker::GetAddonMgr().GetAddon(addonID, addon, ADDON_UNKNOWN, OnlyEnabled::NO))
+ if (CServiceBroker::GetAddonMgr().GetAddon(addonID, addon, ADDON_UNKNOWN, OnlyEnabled::CHOICE_NO))
return false; // addon is installed but disabled, and the user has specifically activated something that needs
// the addon - should we enable it?
@@ -171,19 +171,20 @@ bool CAddonInstaller::InstallModal(const std::string& addonID,
return false;
// if specified ask the user if he wants it installed
- if (promptForInstall == InstallModalPrompt::PROMPT)
+ if (promptForInstall == InstallModalPrompt::CHOICE_YES)
{
- if (HELPERS::ShowYesNoDialogLines(CVariant{24076}, CVariant{24100}, CVariant{addon->Name()}, CVariant{24101}) !=
- DialogResponse::YES)
+ if (HELPERS::ShowYesNoDialogLines(CVariant{24076}, CVariant{24100}, CVariant{addon->Name()},
+ CVariant{24101}) != DialogResponse::CHOICE_YES)
{
return false;
}
}
- if (!InstallOrUpdate(addonID, BackgroundJob::NO, ModalJob::YES))
+ if (!InstallOrUpdate(addonID, BackgroundJob::CHOICE_NO, ModalJob::CHOICE_YES))
return false;
- return CServiceBroker::GetAddonMgr().GetAddon(addonID, addon, ADDON_UNKNOWN, OnlyEnabled::YES);
+ return CServiceBroker::GetAddonMgr().GetAddon(addonID, addon, ADDON_UNKNOWN,
+ OnlyEnabled::CHOICE_YES);
}
@@ -196,22 +197,23 @@ bool CAddonInstaller::InstallOrUpdate(const std::string& addonID,
if (!CAddonInstallJob::GetAddon(addonID, repo, addon))
return false;
- return DoInstall(addon, repo, background, modal, AutoUpdateJob::NO, DependencyJob::NO,
- AllowCheckForUpdates::YES);
+ return DoInstall(addon, repo, background, modal, AutoUpdateJob::CHOICE_NO,
+ DependencyJob::CHOICE_NO, AllowCheckForUpdates::CHOICE_YES);
}
bool CAddonInstaller::InstallOrUpdateDependency(const ADDON::AddonPtr& dependsId,
const ADDON::RepositoryPtr& repo)
{
- return DoInstall(dependsId, repo, BackgroundJob::NO, ModalJob::NO, AutoUpdateJob::NO,
- DependencyJob::YES, AllowCheckForUpdates::YES);
+ return DoInstall(dependsId, repo, BackgroundJob::CHOICE_NO, ModalJob::CHOICE_NO,
+ AutoUpdateJob::CHOICE_NO, DependencyJob::CHOICE_YES,
+ AllowCheckForUpdates::CHOICE_YES);
}
bool CAddonInstaller::RemoveDependency(const std::shared_ptr<IAddon>& dependsId) const
{
bool removeData = CDirectory::Exists("special://profile/addon_data/" + dependsId->ID());
CAddonUnInstallJob removeDependencyJob(dependsId, removeData);
- removeDependencyJob.SetRecurseOrphaned(RecurseOrphaned::NO);
+ removeDependencyJob.SetRecurseOrphaned(RecurseOrphaned::CHOICE_NO);
return removeDependencyJob.DoWork();
}
@@ -256,11 +258,13 @@ bool CAddonInstaller::Install(const std::string& addonId,
return false;
AddonPtr repo;
- if (!CServiceBroker::GetAddonMgr().GetAddon(repoId, repo, ADDON_REPOSITORY, OnlyEnabled::YES))
+ if (!CServiceBroker::GetAddonMgr().GetAddon(repoId, repo, ADDON_REPOSITORY,
+ OnlyEnabled::CHOICE_YES))
return false;
- return DoInstall(addon, std::static_pointer_cast<CRepository>(repo), BackgroundJob::YES,
- ModalJob::NO, AutoUpdateJob::NO, DependencyJob::NO, AllowCheckForUpdates::YES);
+ return DoInstall(addon, std::static_pointer_cast<CRepository>(repo), BackgroundJob::CHOICE_YES,
+ ModalJob::CHOICE_NO, AutoUpdateJob::CHOICE_NO, DependencyJob::CHOICE_NO,
+ AllowCheckForUpdates::CHOICE_YES);
}
bool CAddonInstaller::DoInstall(const AddonPtr& addon,
@@ -277,7 +281,7 @@ bool CAddonInstaller::DoInstall(const AddonPtr& addon,
return false;
CAddonInstallJob* installJob = new CAddonInstallJob(addon, repo, autoUpdate);
- if (background == BackgroundJob::YES)
+ if (background == BackgroundJob::CHOICE_YES)
{
// Workaround: because CAddonInstallJob is blocking waiting for other jobs, it needs to be run
// with priority dedicated.
@@ -296,7 +300,7 @@ bool CAddonInstaller::DoInstall(const AddonPtr& addon,
installJob->SetAllowCheckForUpdates(allowCheckForUpdates);
bool result = false;
- if (modal == ModalJob::YES)
+ if (modal == ModalJob::CHOICE_YES)
result = installJob->DoModal();
else
result = installJob->DoWork();
@@ -336,8 +340,9 @@ bool CAddonInstaller::InstallFromZip(const std::string &path)
AddonPtr addon;
if (CServiceBroker::GetAddonMgr().LoadAddonDescription(items[0]->GetPath(), addon))
- return DoInstall(addon, RepositoryPtr(), BackgroundJob::YES, ModalJob::NO, AutoUpdateJob::NO,
- DependencyJob::NO, AllowCheckForUpdates::YES);
+ return DoInstall(addon, RepositoryPtr(), BackgroundJob::CHOICE_YES, ModalJob::CHOICE_NO,
+ AutoUpdateJob::CHOICE_NO, DependencyJob::CHOICE_NO,
+ AllowCheckForUpdates::CHOICE_YES);
if (eventLog)
eventLog->AddWithNotification(EventPtr(
@@ -381,7 +386,7 @@ bool CAddonInstaller::CheckDependencies(const AddonPtr &addon,
bool optional = it.optional;
AddonPtr dep;
bool haveInstalledAddon =
- CServiceBroker::GetAddonMgr().GetAddon(addonID, dep, ADDON_UNKNOWN, OnlyEnabled::NO);
+ CServiceBroker::GetAddonMgr().GetAddon(addonID, dep, ADDON_UNKNOWN, OnlyEnabled::CHOICE_NO);
if ((haveInstalledAddon && !dep->MeetsVersion(versionMin, version)) ||
(!haveInstalledAddon && !optional))
{
@@ -491,8 +496,8 @@ void CAddonInstaller::InstallAddons(const VECADDONS& addons,
AddonPtr toInstall;
RepositoryPtr repo;
if (CAddonInstallJob::GetAddon(addon->ID(), repo, toInstall))
- DoInstall(toInstall, repo, BackgroundJob::NO, ModalJob::NO, AutoUpdateJob::YES,
- DependencyJob::NO, allowCheckForUpdates);
+ DoInstall(toInstall, repo, BackgroundJob::CHOICE_NO, ModalJob::CHOICE_NO,
+ AutoUpdateJob::CHOICE_YES, DependencyJob::CHOICE_NO, allowCheckForUpdates);
}
if (wait)
{
@@ -534,8 +539,8 @@ CAddonInstallJob::CAddonInstallJob(const AddonPtr& addon,
: m_addon(addon), m_repo(repo), m_isAutoUpdate(isAutoUpdate)
{
AddonPtr dummy;
- m_isUpdate =
- CServiceBroker::GetAddonMgr().GetAddon(addon->ID(), dummy, ADDON_UNKNOWN, OnlyEnabled::NO);
+ m_isUpdate = CServiceBroker::GetAddonMgr().GetAddon(addon->ID(), dummy, ADDON_UNKNOWN,
+ OnlyEnabled::CHOICE_NO);
}
bool CAddonInstallJob::GetAddon(const std::string& addonID, RepositoryPtr& repo,
@@ -546,7 +551,7 @@ bool CAddonInstallJob::GetAddon(const std::string& addonID, RepositoryPtr& repo,
AddonPtr tmp;
if (!CServiceBroker::GetAddonMgr().GetAddon(addon->Origin(), tmp, ADDON_REPOSITORY,
- OnlyEnabled::YES))
+ OnlyEnabled::CHOICE_YES))
return false;
repo = std::static_pointer_cast<CRepository>(tmp);
@@ -706,7 +711,7 @@ bool CAddonInstallJob::DoWork()
if (!CServiceBroker::GetAddonMgr().LoadAddon(m_addon->ID(), m_addon->Origin(),
m_addon->Version()) ||
!CServiceBroker::GetAddonMgr().GetAddon(m_addon->ID(), m_addon, ADDON_UNKNOWN,
- OnlyEnabled::YES))
+ OnlyEnabled::CHOICE_YES))
{
CLog::Log(LOGERROR, "CAddonInstallJob[{}]: failed to reload addon", m_addon->ID());
return false;
@@ -732,7 +737,7 @@ bool CAddonInstallJob::DoWork()
// if a repository is updated during the add-on migration process, we need to skip
// calling CheckForUpdates() on the repo to prevent deadlock issues during migration
- if (m_allowCheckForUpdates == AllowCheckForUpdates::YES)
+ if (m_allowCheckForUpdates == AllowCheckForUpdates::CHOICE_YES)
{
if (m_isUpdate)
{
@@ -754,7 +759,7 @@ bool CAddonInstallJob::DoWork()
CServiceBroker::GetAddonMgr().SetAddonOrigin(m_addon->ID(), origin, m_isUpdate);
- if (m_dependsInstall == DependencyJob::YES)
+ if (m_dependsInstall == DependencyJob::CHOICE_YES)
{
CLog::Log(LOGDEBUG, "ADDONS: dependency [{}] will not be version checked and unpinned",
m_addon->ID());
@@ -837,14 +842,14 @@ bool CAddonInstallJob::DoWork()
bool notify = (CServiceBroker::GetSettingsComponent()->GetSettings()->GetBool(
CSettings::SETTING_ADDONS_NOTIFICATIONS) ||
- m_isAutoUpdate == AutoUpdateJob::NO) &&
- !IsModal() && m_dependsInstall == DependencyJob::NO;
+ m_isAutoUpdate == AutoUpdateJob::CHOICE_NO) &&
+ !IsModal() && m_dependsInstall == DependencyJob::CHOICE_NO;
auto eventLog = CServiceBroker::GetEventLog();
if (eventLog)
eventLog->Add(EventPtr(new CAddonManagementEvent(m_addon, m_isUpdate ? 24065 : 24084)), notify,
false);
- if (m_isAutoUpdate == AutoUpdateJob::YES &&
+ if (m_isAutoUpdate == AutoUpdateJob::CHOICE_YES &&
m_addon->LifecycleState() == AddonLifecycleState::BROKEN)
{
CLog::Log(LOGDEBUG, "CAddonInstallJob[{}]: auto-disabling due to being marked as broken",
@@ -965,7 +970,7 @@ bool CAddonInstallJob::Install(const std::string &installFrom, const RepositoryP
bool optional = it->optional;
AddonPtr dependency;
bool haveInstalledAddon =
- addonMgr.GetAddon(addonID, dependency, ADDON_UNKNOWN, OnlyEnabled::NO);
+ addonMgr.GetAddon(addonID, dependency, ADDON_UNKNOWN, OnlyEnabled::CHOICE_NO);
if ((haveInstalledAddon && !dependency->MeetsVersion(versionMin, version)) ||
(!haveInstalledAddon && !optional))
{
@@ -1022,8 +1027,9 @@ bool CAddonInstallJob::Install(const std::string &installFrom, const RepositoryP
if (IsModal())
{
- CAddonInstallJob dependencyJob(dependencyToInstall, repoForDep, AutoUpdateJob::NO);
- dependencyJob.SetDependsInstall(DependencyJob::YES);
+ CAddonInstallJob dependencyJob(dependencyToInstall, repoForDep,
+ AutoUpdateJob::CHOICE_NO);
+ dependencyJob.SetDependsInstall(DependencyJob::CHOICE_YES);
// pass our progress indicators to the temporary job and don't allow it to
// show progress or information updates (no progress, title or text changes)
@@ -1086,8 +1092,8 @@ void CAddonInstallJob::ReportInstallError(const std::string& addonID, const std:
if (addon != NULL)
{
AddonPtr addon2;
- bool success =
- CServiceBroker::GetAddonMgr().GetAddon(addonID, addon2, ADDON_UNKNOWN, OnlyEnabled::YES);
+ bool success = CServiceBroker::GetAddonMgr().GetAddon(addonID, addon2, ADDON_UNKNOWN,
+ OnlyEnabled::CHOICE_YES);
if (msg.empty())
{
msg = g_localizeStrings.Get(addon2 != nullptr && success ? 113 : 114);
@@ -1156,7 +1162,7 @@ bool CAddonUnInstallJob::DoWork()
ADDON::OnPostUnInstall(m_addon);
- if (m_recurseOrphaned == RecurseOrphaned::YES)
+ if (m_recurseOrphaned == RecurseOrphaned::CHOICE_YES)
{
const auto removedItems = CAddonInstaller::GetInstance().RemoveOrphanedDepsRecursively();
diff --git a/xbmc/addons/AddonInstaller.h b/xbmc/addons/AddonInstaller.h
index 4bd3bd8f27..8140e12239 100644
--- a/xbmc/addons/AddonInstaller.h
+++ b/xbmc/addons/AddonInstaller.h
@@ -28,44 +28,44 @@ class CAddonDatabase;
enum class BackgroundJob : bool
{
- YES = true,
- NO = false,
+ CHOICE_YES = true,
+ CHOICE_NO = false,
};
enum class ModalJob : bool
{
- YES = true,
- NO = false,
+ CHOICE_YES = true,
+ CHOICE_NO = false,
};
enum class AutoUpdateJob : bool
{
- YES = true,
- NO = false,
+ CHOICE_YES = true,
+ CHOICE_NO = false,
};
enum class DependencyJob : bool
{
- YES = true,
- NO = false,
+ CHOICE_YES = true,
+ CHOICE_NO = false,
};
enum class InstallModalPrompt : bool
{
- PROMPT = true,
- NO_PROMPT = false,
+ CHOICE_YES = true,
+ CHOICE_NO = false,
};
enum class AllowCheckForUpdates : bool
{
- YES = true,
- NO = false,
+ CHOICE_YES = true,
+ CHOICE_NO = false,
};
enum class RecurseOrphaned : bool
{
- YES = true,
- NO = false,
+ CHOICE_YES = true,
+ CHOICE_NO = false,
};
class CAddonInstaller : public IJobCallback
@@ -281,8 +281,8 @@ private:
ADDON::RepositoryPtr m_repo;
bool m_isUpdate;
AutoUpdateJob m_isAutoUpdate;
- DependencyJob m_dependsInstall = DependencyJob::NO;
- AllowCheckForUpdates m_allowCheckForUpdates = AllowCheckForUpdates::YES;
+ DependencyJob m_dependsInstall = DependencyJob::CHOICE_NO;
+ AllowCheckForUpdates m_allowCheckForUpdates = AllowCheckForUpdates::CHOICE_YES;
const char* m_currentType = TYPE_DOWNLOAD;
};
@@ -299,7 +299,7 @@ private:
ADDON::AddonPtr m_addon;
bool m_removeData;
- RecurseOrphaned m_recurseOrphaned = RecurseOrphaned::YES;
+ RecurseOrphaned m_recurseOrphaned = RecurseOrphaned::CHOICE_YES;
};
}; // namespace ADDON
diff --git a/xbmc/addons/AddonManager.cpp b/xbmc/addons/AddonManager.cpp
index 7c25f14658..bdccec229a 100644
--- a/xbmc/addons/AddonManager.cpp
+++ b/xbmc/addons/AddonManager.cpp
@@ -123,7 +123,7 @@ bool CAddonMgr::Init()
for (const auto& id : m_systemAddons)
{
AddonPtr addon;
- if (!GetAddon(id, addon, ADDON_UNKNOWN, OnlyEnabled::YES))
+ if (!GetAddon(id, addon, ADDON_UNKNOWN, OnlyEnabled::CHOICE_YES))
{
CLog::Log(LOGFATAL, "addon '{}' not installed or not enabled.", id);
return false;
@@ -301,7 +301,8 @@ bool CAddonMgr::HasAvailableUpdates()
std::vector<std::shared_ptr<IAddon>> CAddonMgr::GetOrphanedDependencies() const
{
std::vector<std::shared_ptr<IAddon>> allAddons;
- GetAddonsInternal(ADDON_UNKNOWN, allAddons, OnlyEnabled::YES, CheckIncompatible::YES);
+ GetAddonsInternal(ADDON_UNKNOWN, allAddons, OnlyEnabled::CHOICE_YES,
+ CheckIncompatible::CHOICE_YES);
std::vector<std::shared_ptr<IAddon>> orphanedDependencies;
for (const auto& addon : allAddons)
@@ -333,27 +334,30 @@ bool CAddonMgr::IsOrphaned(const std::shared_ptr<IAddon>& addon,
bool CAddonMgr::GetAddonsForUpdate(VECADDONS& addons) const
{
- return GetAddonsInternal(ADDON_UNKNOWN, addons, OnlyEnabled::YES, CheckIncompatible::YES);
+ return GetAddonsInternal(ADDON_UNKNOWN, addons, OnlyEnabled::CHOICE_YES,
+ CheckIncompatible::CHOICE_YES);
}
bool CAddonMgr::GetAddons(VECADDONS& addons) const
{
- return GetAddonsInternal(ADDON_UNKNOWN, addons, OnlyEnabled::YES, CheckIncompatible::NO);
+ return GetAddonsInternal(ADDON_UNKNOWN, addons, OnlyEnabled::CHOICE_YES,
+ CheckIncompatible::CHOICE_NO);
}
bool CAddonMgr::GetAddons(VECADDONS& addons, const TYPE& type)
{
- return GetAddonsInternal(type, addons, OnlyEnabled::YES, CheckIncompatible::NO);
+ return GetAddonsInternal(type, addons, OnlyEnabled::CHOICE_YES, CheckIncompatible::CHOICE_NO);
}
bool CAddonMgr::GetInstalledAddons(VECADDONS& addons)
{
- return GetAddonsInternal(ADDON_UNKNOWN, addons, OnlyEnabled::NO, CheckIncompatible::NO);
+ return GetAddonsInternal(ADDON_UNKNOWN, addons, OnlyEnabled::CHOICE_NO,
+ CheckIncompatible::CHOICE_NO);
}
bool CAddonMgr::GetInstalledAddons(VECADDONS& addons, const TYPE& type)
{
- return GetAddonsInternal(type, addons, OnlyEnabled::NO, CheckIncompatible::NO);
+ return GetAddonsInternal(type, addons, OnlyEnabled::CHOICE_NO, CheckIncompatible::CHOICE_NO);
}
bool CAddonMgr::GetDisabledAddons(VECADDONS& addons)
@@ -420,7 +424,7 @@ bool CAddonMgr::FindInstallableById(const std::string& addonId, AddonPtr& result
// check for an update if addon is installed already
- if (GetAddon(addonId, addonToUpdate, ADDON_UNKNOWN, OnlyEnabled::NO))
+ if (GetAddon(addonId, addonToUpdate, ADDON_UNKNOWN, OnlyEnabled::CHOICE_NO))
{
if (addonRepos.DoAddonUpdateCheck(addonToUpdate, result))
return true;
@@ -449,9 +453,10 @@ bool CAddonMgr::GetAddonsInternal(const TYPE& type,
if (type != ADDON_UNKNOWN && !addonInfo.second->HasType(type))
continue;
- if (onlyEnabled == OnlyEnabled::YES &&
- ((checkIncompatible == CheckIncompatible::NO && IsAddonDisabled(addonInfo.second->ID())) ||
- (checkIncompatible == CheckIncompatible::YES &&
+ if (onlyEnabled == OnlyEnabled::CHOICE_YES &&
+ ((checkIncompatible == CheckIncompatible::CHOICE_NO &&
+ IsAddonDisabled(addonInfo.second->ID())) ||
+ (checkIncompatible == CheckIncompatible::CHOICE_YES &&
IsAddonDisabledExcept(addonInfo.second->ID(), AddonDisabledReason::INCOMPATIBLE))))
continue;
@@ -497,7 +502,7 @@ std::vector<AddonInfoPtr> CAddonMgr::MigrateAddons()
CLog::Log(LOGINFO, "ADDON: waiting for add-ons to update...");
VECADDONS updates;
GetAddonUpdateCandidates(updates);
- InstallAddonUpdates(updates, true, AllowCheckForUpdates::NO);
+ InstallAddonUpdates(updates, true, AllowCheckForUpdates::CHOICE_NO);
// get addons that became incompatible and disable them
std::vector<AddonInfoPtr> incompatible;
@@ -536,7 +541,7 @@ void CAddonMgr::CheckAndInstallAddonUpdates(bool wait) const
std::lock_guard<std::mutex> lock(m_installAddonsMutex);
VECADDONS updates;
GetAddonUpdateCandidates(updates);
- InstallAddonUpdates(updates, wait, AllowCheckForUpdates::YES);
+ InstallAddonUpdates(updates, wait, AllowCheckForUpdates::CHOICE_YES);
}
bool CAddonMgr::GetAddonUpdateCandidates(VECADDONS& updates) const
@@ -617,7 +622,7 @@ bool CAddonMgr::GetAddon(const std::string& str,
addon = CAddonBuilder::Generate(addonInfo, type);
if (addon)
{
- if (onlyEnabled == OnlyEnabled::YES && IsAddonDisabled(addonInfo->ID()))
+ if (onlyEnabled == OnlyEnabled::CHOICE_YES && IsAddonDisabled(addonInfo->ID()))
return false;
// if the addon has a running instance, grab that
@@ -634,7 +639,7 @@ bool CAddonMgr::GetAddon(const std::string& str,
bool CAddonMgr::HasType(const std::string &id, const TYPE &type)
{
AddonPtr addon;
- return GetAddon(id, addon, type, OnlyEnabled::NO);
+ return GetAddon(id, addon, type, OnlyEnabled::CHOICE_NO);
}
bool CAddonMgr::FindAddon(const std::string& addonId,
@@ -713,8 +718,8 @@ bool CAddonMgr::UnloadAddon(const std::string& addonId)
AddonPtr localAddon;
// can't unload an binary addon that is in use
- if (GetAddon(addonId, localAddon, ADDON_UNKNOWN, OnlyEnabled::NO) && localAddon->IsBinary() &&
- localAddon->IsInUse())
+ if (GetAddon(addonId, localAddon, ADDON_UNKNOWN, OnlyEnabled::CHOICE_NO) &&
+ localAddon->IsBinary() && localAddon->IsInUse())
{
CLog::Log(LOGERROR, "CAddonMgr::{}: could not unload binary add-on {}, as is in use", __func__,
addonId);
@@ -738,7 +743,7 @@ bool CAddonMgr::LoadAddon(const std::string& addonId,
CSingleLock lock(m_critSection);
AddonPtr addon;
- if (GetAddon(addonId, addon, ADDON_UNKNOWN, OnlyEnabled::NO))
+ if (GetAddon(addonId, addon, ADDON_UNKNOWN, OnlyEnabled::CHOICE_NO))
{
return true;
}
@@ -749,7 +754,7 @@ bool CAddonMgr::LoadAddon(const std::string& addonId,
return false;
}
- if (!GetAddon(addonId, addon, ADDON_UNKNOWN, OnlyEnabled::NO))
+ if (!GetAddon(addonId, addon, ADDON_UNKNOWN, OnlyEnabled::CHOICE_NO))
{
CLog::Log(LOGERROR, "CAddonMgr: could not load add-on {}. No add-on with that ID is installed.",
addonId);
@@ -801,7 +806,8 @@ static void ResolveDependencies(const std::string& addonId, std::vector<std::str
return;
AddonPtr addon;
- if (!CServiceBroker::GetAddonMgr().GetAddon(addonId, addon, ADDON_UNKNOWN, OnlyEnabled::NO))
+ if (!CServiceBroker::GetAddonMgr().GetAddon(addonId, addon, ADDON_UNKNOWN,
+ OnlyEnabled::CHOICE_NO))
missing.push_back(addonId);
else
{
@@ -827,7 +833,7 @@ bool CAddonMgr::DisableAddon(const std::string& id, AddonDisabledReason disabled
//success
CLog::Log(LOGDEBUG, "CAddonMgr: {} disabled", id);
AddonPtr addon;
- if (GetAddon(id, addon, ADDON_UNKNOWN, OnlyEnabled::NO) && addon != NULL)
+ if (GetAddon(id, addon, ADDON_UNKNOWN, OnlyEnabled::CHOICE_NO) && addon != NULL)
{
auto eventLog = CServiceBroker::GetEventLog();
if (eventLog)
@@ -862,7 +868,7 @@ bool CAddonMgr::EnableSingle(const std::string& id)
return true; //already enabled
AddonPtr addon;
- if (!GetAddon(id, addon, ADDON_UNKNOWN, OnlyEnabled::NO) || addon == nullptr)
+ if (!GetAddon(id, addon, ADDON_UNKNOWN, OnlyEnabled::CHOICE_NO) || addon == nullptr)
return false;
auto eventLog = CServiceBroker::GetEventLog();
@@ -937,7 +943,7 @@ bool CAddonMgr::CanAddonBeDisabled(const std::string& ID)
AddonPtr localAddon;
// can't disable an addon that isn't installed
- if (!GetAddon(ID, localAddon, ADDON_UNKNOWN, OnlyEnabled::NO))
+ if (!GetAddon(ID, localAddon, ADDON_UNKNOWN, OnlyEnabled::CHOICE_NO))
return false;
// can't disable an addon that is in use
@@ -955,14 +961,14 @@ bool CAddonMgr::CanAddonBeEnabled(const std::string& id)
bool CAddonMgr::IsAddonInstalled(const std::string& ID)
{
AddonPtr tmp;
- return GetAddon(ID, tmp, ADDON_UNKNOWN, OnlyEnabled::NO);
+ return GetAddon(ID, tmp, ADDON_UNKNOWN, OnlyEnabled::CHOICE_NO);
}
bool CAddonMgr::IsAddonInstalled(const std::string& ID, const std::string& origin) const
{
AddonPtr tmp;
- if (GetAddon(ID, tmp, ADDON_UNKNOWN, OnlyEnabled::NO) && tmp)
+ if (GetAddon(ID, tmp, ADDON_UNKNOWN, OnlyEnabled::CHOICE_NO) && tmp)
{
if (tmp->Origin() == ORIGIN_SYSTEM)
{
@@ -982,7 +988,7 @@ bool CAddonMgr::IsAddonInstalled(const std::string& ID,
{
AddonPtr tmp;
- if (GetAddon(ID, tmp, ADDON_UNKNOWN, OnlyEnabled::NO) && tmp)
+ if (GetAddon(ID, tmp, ADDON_UNKNOWN, OnlyEnabled::CHOICE_NO) && tmp)
{
if (tmp->Origin() == ORIGIN_SYSTEM)
{
@@ -1079,7 +1085,7 @@ bool CAddonMgr::IsCompatible(const IAddon& addon) const
StringUtils::StartsWith(dependency.id, "kodi."))
{
AddonPtr addon;
- bool haveAddon = GetAddon(dependency.id, addon, ADDON_UNKNOWN, OnlyEnabled::YES);
+ bool haveAddon = GetAddon(dependency.id, addon, ADDON_UNKNOWN, OnlyEnabled::CHOICE_YES);
if (!haveAddon || !addon->MeetsVersion(dependency.versionMin, dependency.version))
return false;
}
diff --git a/xbmc/addons/AddonManager.h b/xbmc/addons/AddonManager.h
index 973981fd44..470c65d91e 100644
--- a/xbmc/addons/AddonManager.h
+++ b/xbmc/addons/AddonManager.h
@@ -28,28 +28,28 @@ namespace ADDON
enum class AllowCheckForUpdates : bool;
- enum class AddonCheckType
+ enum class AddonCheckType : bool
{
OUTDATED_ADDONS,
- AVAILABLE_UPDATES
+ AVAILABLE_UPDATES,
};
enum class OnlyEnabled : bool
{
- YES = true,
- NO = false,
+ CHOICE_YES = true,
+ CHOICE_NO = false,
};
enum class OnlyEnabledRootAddon : bool
{
- YES = true,
- NO = false,
+ CHOICE_YES = true,
+ CHOICE_NO = false,
};
enum class CheckIncompatible : bool
{
- YES = true,
- NO = false,
+ CHOICE_YES = true,
+ CHOICE_NO = false,
};
struct CAddonWithUpdate;
diff --git a/xbmc/addons/AddonRepos.cpp b/xbmc/addons/AddonRepos.cpp
index 79711b8d8a..b5757086fa 100644
--- a/xbmc/addons/AddonRepos.cpp
+++ b/xbmc/addons/AddonRepos.cpp
@@ -37,7 +37,7 @@ bool CAddonRepos::IsFromOfficialRepo(const std::shared_ptr<IAddon>& addon,
CheckAddonPath checkAddonPath)
{
auto comparator = [&](const RepoInfo& officialRepo) {
- if (checkAddonPath == CheckAddonPath::YES)
+ if (checkAddonPath == CheckAddonPath::CHOICE_YES)
{
return (addon->Origin() == officialRepo.m_repoId &&
StringUtils::StartsWithNoCase(addon->Path(), officialRepo.m_origin));
@@ -138,7 +138,7 @@ void CAddonRepos::SetupLatestVersionMaps()
{
const auto& addonToAdd = addonMapEntry.second;
- if (IsFromOfficialRepo(addonToAdd, CheckAddonPath::YES))
+ if (IsFromOfficialRepo(addonToAdd, CheckAddonPath::CHOICE_YES))
{
AddAddonIfLatest(addonToAdd, m_latestOfficialVersions);
}
@@ -239,7 +239,7 @@ bool CAddonRepos::DoAddonUpdateCheck(const std::shared_ptr<IAddon>& addon,
if (ORIGIN_SYSTEM != addon->Origin() && !hasOfficialUpdate) // not a system addon
{
// If we didn't find an official update
- if (IsFromOfficialRepo(addon, CheckAddonPath::YES)) // is an official addon
+ if (IsFromOfficialRepo(addon, CheckAddonPath::CHOICE_YES)) // is an official addon
{
if (updateMode == AddonRepoUpdateMode::ANY_REPOSITORY)
{
@@ -453,7 +453,8 @@ bool CAddonRepos::FindDependency(const std::string& dependsId,
// we got the dependency, so now get a repository-pointer to return
std::shared_ptr<IAddon> tmp;
- if (!m_addonMgr.GetAddon(dependencyToInstall->Origin(), tmp, ADDON_REPOSITORY, OnlyEnabled::YES))
+ if (!m_addonMgr.GetAddon(dependencyToInstall->Origin(), tmp, ADDON_REPOSITORY,
+ OnlyEnabled::CHOICE_YES))
return false;
repoForDep = std::static_pointer_cast<CRepository>(tmp);
@@ -497,7 +498,7 @@ void CAddonRepos::BuildCompatibleVersionsList(
{
if (m_addonMgr.IsCompatible(*addon))
{
- if (IsFromOfficialRepo(addon, CheckAddonPath::YES))
+ if (IsFromOfficialRepo(addon, CheckAddonPath::CHOICE_YES))
{
officialVersions.emplace_back(addon);
}
diff --git a/xbmc/addons/AddonRepos.h b/xbmc/addons/AddonRepos.h
index 88a055f94b..27581af750 100644
--- a/xbmc/addons/AddonRepos.h
+++ b/xbmc/addons/AddonRepos.h
@@ -21,12 +21,12 @@ class CAddonDatabase;
class CAddonMgr;
class CRepository;
class IAddon;
-enum class AddonCheckType;
+enum class AddonCheckType : bool;
enum class CheckAddonPath
{
- YES,
- NO,
+ CHOICE_YES = true,
+ CHOICE_NO = false,
};
/**
@@ -104,7 +104,7 @@ public:
* is matching
* \note if this function is called on locally installed add-ons, for instance when populating
* 'My add-ons', the local installation path is returned as origin.
- * thus parameter CheckAddonPath::NO needs to be passed in such cases
+ * thus parameter CheckAddonPath::CHOICE_NO needs to be passed in such cases
* \param addon pointer to addon to be checked
* \param checkAddonPath also check origin path
* \return true if the repository id of a given addon is defined as official
diff --git a/xbmc/addons/AddonStatusHandler.cpp b/xbmc/addons/AddonStatusHandler.cpp
index a1a9554458..75f683e09a 100644
--- a/xbmc/addons/AddonStatusHandler.cpp
+++ b/xbmc/addons/AddonStatusHandler.cpp
@@ -44,7 +44,8 @@ CAddonStatusHandler::CAddonStatusHandler(const std::string &addonID, ADDON_STATU
{
//! @todo The status handled CAddonStatusHandler by is related to the class, not the instance
//! having CAddonMgr construct an instance makes no sense
- if (!CServiceBroker::GetAddonMgr().GetAddon(addonID, m_addon, ADDON_UNKNOWN, OnlyEnabled::YES))
+ if (!CServiceBroker::GetAddonMgr().GetAddon(addonID, m_addon, ADDON_UNKNOWN,
+ OnlyEnabled::CHOICE_YES))
return;
CLog::Log(LOGINFO,
diff --git a/xbmc/addons/AddonSystemSettings.cpp b/xbmc/addons/AddonSystemSettings.cpp
index 54c792fd90..e066830498 100644
--- a/xbmc/addons/AddonSystemSettings.cpp
+++ b/xbmc/addons/AddonSystemSettings.cpp
@@ -84,9 +84,10 @@ void CAddonSystemSettings::OnSettingChanged(const std::shared_ptr<const CSetting
{
using namespace KODI::MESSAGING::HELPERS;
- if (setting->GetId() == CSettings::SETTING_ADDONS_ALLOW_UNKNOWN_SOURCES
- && CServiceBroker::GetSettingsComponent()->GetSettings()->GetBool(CSettings::SETTING_ADDONS_ALLOW_UNKNOWN_SOURCES)
- && ShowYesNoDialogText(19098, 36618) != DialogResponse::YES)
+ if (setting->GetId() == CSettings::SETTING_ADDONS_ALLOW_UNKNOWN_SOURCES &&
+ CServiceBroker::GetSettingsComponent()->GetSettings()->GetBool(
+ CSettings::SETTING_ADDONS_ALLOW_UNKNOWN_SOURCES) &&
+ ShowYesNoDialogText(19098, 36618) != DialogResponse::CHOICE_YES)
{
CServiceBroker::GetSettingsComponent()->GetSettings()->SetBool(CSettings::SETTING_ADDONS_ALLOW_UNKNOWN_SOURCES, false);
}
@@ -98,7 +99,8 @@ bool CAddonSystemSettings::GetActive(const TYPE& type, AddonPtr& addon)
if (it != m_activeSettings.end())
{
auto settingValue = CServiceBroker::GetSettingsComponent()->GetSettings()->GetString(it->second);
- return CServiceBroker::GetAddonMgr().GetAddon(settingValue, addon, type, OnlyEnabled::YES);
+ return CServiceBroker::GetAddonMgr().GetAddon(settingValue, addon, type,
+ OnlyEnabled::CHOICE_YES);
}
return false;
}
diff --git a/xbmc/addons/ContextMenus.cpp b/xbmc/addons/ContextMenus.cpp
index 1bcfefa336..c8755b3259 100644
--- a/xbmc/addons/ContextMenus.cpp
+++ b/xbmc/addons/ContextMenus.cpp
@@ -25,7 +25,7 @@ bool CAddonSettings::IsVisible(const CFileItem& item) const
AddonPtr addon;
return item.HasAddonInfo() &&
CServiceBroker::GetAddonMgr().GetAddon(item.GetAddonInfo()->ID(), addon, ADDON_UNKNOWN,
- OnlyEnabled::NO) &&
+ OnlyEnabled::CHOICE_NO) &&
addon->HasSettings();
}
@@ -33,7 +33,7 @@ bool CAddonSettings::Execute(const CFileItemPtr& item) const
{
AddonPtr addon;
return CServiceBroker::GetAddonMgr().GetAddon(item->GetAddonInfo()->ID(), addon, ADDON_UNKNOWN,
- OnlyEnabled::NO) &&
+ OnlyEnabled::CHOICE_NO) &&
CGUIDialogAddonSettings::ShowForAddon(addon);
}
@@ -47,7 +47,7 @@ bool CCheckForUpdates::Execute(const CFileItemPtr& item) const
AddonPtr addon;
if (item->HasAddonInfo() &&
CServiceBroker::GetAddonMgr().GetAddon(item->GetAddonInfo()->ID(), addon, ADDON_REPOSITORY,
- OnlyEnabled::YES))
+ OnlyEnabled::CHOICE_YES))
{
CServiceBroker::GetRepositoryUpdater().CheckForUpdates(std::static_pointer_cast<CRepository>(addon), true);
return true;
diff --git a/xbmc/addons/FontResource.cpp b/xbmc/addons/FontResource.cpp
index 1ef8fd10f4..e39e8d3b20 100644
--- a/xbmc/addons/FontResource.cpp
+++ b/xbmc/addons/FontResource.cpp
@@ -28,7 +28,7 @@ void CFontResource::OnPostInstall(bool update, bool modal)
{
std::string skin = CServiceBroker::GetSettingsComponent()->GetSettings()->GetString(CSettings::SETTING_LOOKANDFEEL_SKIN);
const auto& deps =
- CServiceBroker::GetAddonMgr().GetDepsRecursive(skin, OnlyEnabledRootAddon::YES);
+ CServiceBroker::GetAddonMgr().GetDepsRecursive(skin, OnlyEnabledRootAddon::CHOICE_YES);
for (const auto& it : deps)
if (it.id == ID())
CApplicationMessenger::GetInstance().PostMsg(TMSG_EXECUTE_BUILT_IN, -1, -1, nullptr, "ReloadSkin");
diff --git a/xbmc/addons/LanguageResource.cpp b/xbmc/addons/LanguageResource.cpp
index b9d1c41eed..87f18b99b5 100644
--- a/xbmc/addons/LanguageResource.cpp
+++ b/xbmc/addons/LanguageResource.cpp
@@ -97,9 +97,9 @@ void CLanguageResource::OnPostInstall(bool update, bool modal)
if (!g_SkinInfo)
return;
- if (IsInUse() ||
- (!update && !modal &&
- (HELPERS::ShowYesNoDialogText(CVariant{Name()}, CVariant{24132}) == DialogResponse::YES)))
+ if (IsInUse() || (!update && !modal &&
+ (HELPERS::ShowYesNoDialogText(CVariant{Name()}, CVariant{24132}) ==
+ DialogResponse::CHOICE_YES)))
{
if (IsInUse())
g_langInfo.SetLanguage(ID());
@@ -137,7 +137,7 @@ bool CLanguageResource::FindLegacyLanguage(const std::string &locale, std::strin
AddonPtr addon;
if (!CServiceBroker::GetAddonMgr().GetAddon(addonId, addon, ADDON_RESOURCE_LANGUAGE,
- OnlyEnabled::YES))
+ OnlyEnabled::CHOICE_YES))
return false;
legacyLanguage = addon->Name();
diff --git a/xbmc/addons/Scraper.cpp b/xbmc/addons/Scraper.cpp
index 241d66ed73..e273057c5f 100644
--- a/xbmc/addons/Scraper.cpp
+++ b/xbmc/addons/Scraper.cpp
@@ -369,7 +369,7 @@ bool CScraper::Load()
bool bOptional = itr->optional;
if (CServiceBroker::GetAddonMgr().GetAddon((*itr).id, dep, ADDON::ADDON_UNKNOWN,
- ADDON::OnlyEnabled::YES))
+ ADDON::OnlyEnabled::CHOICE_YES))
{
CXBMCTinyXML doc;
if (dep->Type() == ADDON_SCRAPER_LIBRARY && doc.LoadFile(dep->LibPath()))
diff --git a/xbmc/addons/Service.cpp b/xbmc/addons/Service.cpp
index 285e76ba2f..e8d71fdce5 100644
--- a/xbmc/addons/Service.cpp
+++ b/xbmc/addons/Service.cpp
@@ -62,7 +62,7 @@ void CServiceAddonManager::Start()
void CServiceAddonManager::Start(const std::string& addonId)
{
AddonPtr addon;
- if (m_addonMgr.GetAddon(addonId, addon, ADDON_SERVICE, OnlyEnabled::YES))
+ if (m_addonMgr.GetAddon(addonId, addon, ADDON_SERVICE, OnlyEnabled::CHOICE_YES))
{
Start(addon);
}
diff --git a/xbmc/addons/Skin.cpp b/xbmc/addons/Skin.cpp
index f6923fa7f1..0752eeaf64 100644
--- a/xbmc/addons/Skin.cpp
+++ b/xbmc/addons/Skin.cpp
@@ -381,7 +381,8 @@ void CSkinInfo::OnPostInstall(bool update, bool modal)
return;
if (IsInUse() || (!update && !modal &&
- HELPERS::ShowYesNoDialogText(CVariant{Name()}, CVariant{24099}) == DialogResponse::YES))
+ HELPERS::ShowYesNoDialogText(CVariant{Name()}, CVariant{24099}) ==
+ DialogResponse::CHOICE_YES))
{
CGUIDialogKaiToast *toast = CServiceBroker::GetGUI()->GetWindowManager().GetWindow<CGUIDialogKaiToast>(WINDOW_DIALOG_KAI_TOAST);
if (toast)
diff --git a/xbmc/addons/addoninfo/AddonInfo.cpp b/xbmc/addons/addoninfo/AddonInfo.cpp
index fa9762bf6b..a110547100 100644
--- a/xbmc/addons/addoninfo/AddonInfo.cpp
+++ b/xbmc/addons/addoninfo/AddonInfo.cpp
@@ -79,7 +79,7 @@ const std::string& CAddonInfo::OriginName() const
{
ADDON::AddonPtr origin;
if (CServiceBroker::GetAddonMgr().GetAddon(m_origin, origin, ADDON::ADDON_UNKNOWN,
- ADDON::OnlyEnabled::NO))
+ ADDON::OnlyEnabled::CHOICE_NO))
m_originName = std::make_unique<std::string>(origin->Name());
else
m_originName = std::make_unique<std::string>(); // remember we tried to fetch the name
diff --git a/xbmc/addons/gui/GUIDialogAddonInfo.cpp b/xbmc/addons/gui/GUIDialogAddonInfo.cpp
index 7b1004c692..fcefb9fc3d 100644
--- a/xbmc/addons/gui/GUIDialogAddonInfo.cpp
+++ b/xbmc/addons/gui/GUIDialogAddonInfo.cpp
@@ -118,7 +118,7 @@ bool CGUIDialogAddonInfo::OnMessage(CGUIMessage& message)
}
else if (iControl == CONTROL_BTN_DEPENDENCIES)
{
- ShowDependencyList(Reactivate::YES, EntryPoint::SHOW_DEPENDENCIES);
+ ShowDependencyList(Reactivate::CHOICE_YES, EntryPoint::SHOW_DEPENDENCIES);
return true;
}
else if (iControl == CONTROL_BTN_AUTOUPDATE)
@@ -166,7 +166,7 @@ void CGUIDialogAddonInfo::OnInitWindow()
{
CGUIDialog::OnInitWindow();
BuildDependencyList();
- UpdateControls(PerformButtonFocus::YES);
+ UpdateControls(PerformButtonFocus::CHOICE_YES);
}
void CGUIDialogAddonInfo::UpdateControls(PerformButtonFocus performButtonFocus)
@@ -208,7 +208,7 @@ void CGUIDialogAddonInfo::UpdateControls(PerformButtonFocus performButtonFocus)
}
CONTROL_ENABLE_ON_CONDITION(CONTROL_BTN_INSTALL, canInstall);
- if (canInstall && performButtonFocus == PerformButtonFocus::YES)
+ if (canInstall && performButtonFocus == PerformButtonFocus::CHOICE_YES)
{
SET_CONTROL_FOCUS(CONTROL_BTN_INSTALL, 0);
}
@@ -261,7 +261,8 @@ void CGUIDialogAddonInfo::UpdateControls(PerformButtonFocus performButtonFocus)
SET_CONTROL_LABEL(CONTROL_BTN_SELECT, label);
CONTROL_ENABLE_ON_CONDITION(CONTROL_BTN_SETTINGS, isInstalled && m_localAddon->HasSettings());
- if (isInstalled && m_localAddon->HasSettings() && performButtonFocus == PerformButtonFocus::YES)
+ if (isInstalled && m_localAddon->HasSettings() &&
+ performButtonFocus == PerformButtonFocus::CHOICE_YES)
{
SET_CONTROL_FOCUS(CONTROL_BTN_SETTINGS, 0);
}
@@ -306,7 +307,7 @@ int CGUIDialogAddonInfo::AskForVersion(std::vector<std::pair<AddonVersion, std::
dialog->Add(item);
}
else if (CServiceBroker::GetAddonMgr().GetAddon(versionInfo.second, repo, ADDON_REPOSITORY,
- OnlyEnabled::YES))
+ OnlyEnabled::CHOICE_YES))
{
item.SetLabel2(repo->Name());
item.SetArt("icon", repo->Icon());
@@ -328,7 +329,7 @@ void CGUIDialogAddonInfo::OnUpdate()
Close();
if (!m_depsInstalledWithAvailable.empty() &&
- !ShowDependencyList(Reactivate::NO, EntryPoint::UPDATE))
+ !ShowDependencyList(Reactivate::CHOICE_NO, EntryPoint::UPDATE))
return;
CAddonInstaller::GetInstance().Install(addonId, version, origin);
@@ -403,7 +404,7 @@ void CGUIDialogAddonInfo::OnSelectVersion()
else
{
if (!m_depsInstalledWithAvailable.empty() &&
- !ShowDependencyList(Reactivate::NO, entryPoint))
+ !ShowDependencyList(Reactivate::CHOICE_NO, entryPoint))
return;
CAddonInstaller::GetInstance().Install(processAddonId, versions[i].first,
versions[i].second);
@@ -481,7 +482,7 @@ void CGUIDialogAddonInfo::OnInstall()
Close();
if (!m_depsInstalledWithAvailable.empty() &&
- !ShowDependencyList(Reactivate::NO, EntryPoint::INSTALL))
+ !ShowDependencyList(Reactivate::CHOICE_NO, EntryPoint::INSTALL))
return;
CAddonInstaller::GetInstance().Install(addonId, version, origin);
@@ -618,7 +619,7 @@ void CGUIDialogAddonInfo::OnEnableDisable()
CServiceBroker::GetAddonMgr().EnableAddon(m_localAddon->ID());
}
- UpdateControls(PerformButtonFocus::NO);
+ UpdateControls(PerformButtonFocus::CHOICE_NO);
}
void CGUIDialogAddonInfo::OnSettings()
@@ -680,7 +681,7 @@ bool CGUIDialogAddonInfo::ShowDependencyList(Reactivate reactivate, EntryPoint e
if (entryPoint == EntryPoint::SHOW_DEPENDENCIES ||
infoAddon->MainType() != ADDON_SCRIPT_MODULE ||
- !CAddonRepos::IsFromOfficialRepo(infoAddon, CheckAddonPath::NO))
+ !CAddonRepos::IsFromOfficialRepo(infoAddon, CheckAddonPath::CHOICE_NO))
{
item->SetLabel2(StringUtils::Format(
g_localizeStrings.Get(messageId), it.m_depInfo.versionMin.asString(),
@@ -708,11 +709,11 @@ bool CGUIDialogAddonInfo::ShowDependencyList(Reactivate reactivate, EntryPoint e
while (true)
{
pDialog->Reset();
- pDialog->SetHeading(reactivate == Reactivate::YES ? 39024 : 39020);
+ pDialog->SetHeading(reactivate == Reactivate::CHOICE_YES ? 39024 : 39020);
pDialog->SetUseDetails(true);
for (auto& it : items)
pDialog->Add(*it);
- pDialog->EnableButton(reactivate == Reactivate::NO, 186);
+ pDialog->EnableButton(reactivate == Reactivate::CHOICE_NO, 186);
pDialog->SetButtonFocus(true);
pDialog->Open();
@@ -734,7 +735,7 @@ bool CGUIDialogAddonInfo::ShowDependencyList(Reactivate reactivate, EntryPoint e
break;
}
SetItem(backup_item);
- if (reactivate == Reactivate::YES)
+ if (reactivate == Reactivate::CHOICE_YES)
Open();
return false;
@@ -814,7 +815,7 @@ bool CGUIDialogAddonInfo::SetItem(const CFileItemPtr& item)
m_item = std::make_shared<CFileItem>(*item);
m_localAddon.reset();
if (CServiceBroker::GetAddonMgr().GetAddon(item->GetAddonInfo()->ID(), m_localAddon,
- ADDON_UNKNOWN, OnlyEnabled::NO))
+ ADDON_UNKNOWN, OnlyEnabled::CHOICE_NO))
{
CLog::Log(LOGDEBUG, "{} - Addon with id {} not found locally.", __FUNCTION__,
item->GetAddonInfo()->ID());
@@ -830,7 +831,7 @@ void CGUIDialogAddonInfo::BuildDependencyList()
m_showDepDialogOnInstall = false;
m_depsInstalledWithAvailable.clear();
m_deps = CServiceBroker::GetAddonMgr().GetDepsRecursive(m_item->GetAddonInfo()->ID(),
- OnlyEnabledRootAddon::NO);
+ OnlyEnabledRootAddon::CHOICE_NO);
for (const auto& dep : m_deps)
{
@@ -839,7 +840,7 @@ void CGUIDialogAddonInfo::BuildDependencyList()
// Find add-on in local installation
if (!CServiceBroker::GetAddonMgr().GetAddon(dep.id, addonInstalled, ADDON_UNKNOWN,
- OnlyEnabled::YES))
+ OnlyEnabled::CHOICE_YES))
{
addonInstalled = nullptr;
}
@@ -859,7 +860,7 @@ void CGUIDialogAddonInfo::BuildDependencyList()
// - the dependency is not a script/module OR
// - the script/module is not available at an official repo
if (!addonAvailable || addonAvailable->MainType() != ADDON_SCRIPT_MODULE ||
- !CAddonRepos::IsFromOfficialRepo(addonAvailable, CheckAddonPath::NO))
+ !CAddonRepos::IsFromOfficialRepo(addonAvailable, CheckAddonPath::CHOICE_NO))
{
m_showDepDialogOnInstall = true;
}
diff --git a/xbmc/addons/gui/GUIDialogAddonInfo.h b/xbmc/addons/gui/GUIDialogAddonInfo.h
index 2495455f82..8738c0226c 100644
--- a/xbmc/addons/gui/GUIDialogAddonInfo.h
+++ b/xbmc/addons/gui/GUIDialogAddonInfo.h
@@ -16,19 +16,19 @@
#include <utility>
#include <vector>
-enum class Reactivate
+enum class Reactivate : bool
{
- YES,
- NO,
+ CHOICE_YES = true,
+ CHOICE_NO = false,
};
-enum class PerformButtonFocus
+enum class PerformButtonFocus : bool
{
- YES,
- NO,
+ CHOICE_YES = true,
+ CHOICE_NO = false,
};
-enum class EntryPoint
+enum class EntryPoint : int
{
INSTALL,
UPDATE,
diff --git a/xbmc/addons/gui/GUIWindowAddonBrowser.cpp b/xbmc/addons/gui/GUIWindowAddonBrowser.cpp
index 90058f990f..4e4bb6679f 100644
--- a/xbmc/addons/gui/GUIWindowAddonBrowser.cpp
+++ b/xbmc/addons/gui/GUIWindowAddonBrowser.cpp
@@ -162,7 +162,8 @@ class UpdateAddons : public IRunnable
void Run() override
{
for (const auto& addon : CServiceBroker::GetAddonMgr().GetAvailableUpdates())
- CAddonInstaller::GetInstance().InstallOrUpdate(addon->ID(), BackgroundJob::YES, ModalJob::NO);
+ CAddonInstaller::GetInstance().InstallOrUpdate(addon->ID(), BackgroundJob::CHOICE_YES,
+ ModalJob::CHOICE_NO);
}
};
@@ -172,8 +173,8 @@ class UpdateAllowedAddons : public IRunnable
{
for (const auto& addon : CServiceBroker::GetAddonMgr().GetAvailableUpdates())
if (CServiceBroker::GetAddonMgr().IsAutoUpdateable(addon->ID()))
- CAddonInstaller::GetInstance().InstallOrUpdate(addon->ID(), BackgroundJob::YES,
- ModalJob::NO);
+ CAddonInstaller::GetInstance().InstallOrUpdate(addon->ID(), BackgroundJob::CHOICE_YES,
+ ModalJob::CHOICE_NO);
}
};
@@ -196,13 +197,13 @@ void CGUIWindowAddonBrowser::InstallFromZip()
if (!CServiceBroker::GetSettingsComponent()->GetSettings()->GetBool(
CSettings::SETTING_ADDONS_ALLOW_UNKNOWN_SOURCES))
{
- if (ShowYesNoDialogText(13106, 36617, 186, 10004) == DialogResponse::YES)
+ if (ShowYesNoDialogText(13106, 36617, 186, 10004) == DialogResponse::CHOICE_YES)
CServiceBroker::GetGUI()->GetWindowManager().ActivateWindow(
WINDOW_SETTINGS_SYSTEM, CSettings::SETTING_ADDONS_ALLOW_UNKNOWN_SOURCES);
}
else
{
- if (ShowYesNoDialogText(19098, 36637) == DialogResponse::YES)
+ if (ShowYesNoDialogText(19098, 36637) == DialogResponse::CHOICE_YES)
{
// pop up filebrowser to grab an installed folder
VECSOURCES shares = *CMediaSourceSettings::GetInstance().GetSources("files");
@@ -329,7 +330,8 @@ bool CGUIWindowAddonBrowser::GetDirectory(const std::string& strDirectory, CFile
//check if it's installed
AddonPtr addon;
if (!CServiceBroker::GetAddonMgr().GetAddon(items[i]->GetProperty("Addon.ID").asString(),
- addon, ADDON_UNKNOWN, OnlyEnabled::YES))
+ addon, ADDON_UNKNOWN,
+ OnlyEnabled::CHOICE_YES))
items.Remove(i);
}
}
@@ -610,7 +612,7 @@ int CGUIWindowAddonBrowser::SelectAddonID(const std::vector<ADDON::TYPE>& types,
{
AddonPtr installedAddon;
if (!CAddonInstaller::GetInstance().InstallModal(addon->ID(), installedAddon,
- InstallModalPrompt::NO_PROMPT))
+ InstallModalPrompt::CHOICE_NO))
continue;
}
diff --git a/xbmc/addons/interfaces/AddonBase.cpp b/xbmc/addons/interfaces/AddonBase.cpp
index dd28c472a6..1f62868b16 100644
--- a/xbmc/addons/interfaces/AddonBase.cpp
+++ b/xbmc/addons/interfaces/AddonBase.cpp
@@ -313,7 +313,7 @@ bool Interface_Base::open_settings_dialog(const KODI_ADDON_BACKEND_HDL hdl)
// show settings dialog
AddonPtr addonInfo;
if (!CServiceBroker::GetAddonMgr().GetAddon(addon->ID(), addonInfo, ADDON_UNKNOWN,
- OnlyEnabled::YES))
+ OnlyEnabled::CHOICE_YES))
{
CLog::Log(LOGERROR, "Interface_Base::{} - Could not get addon information for '{}'", __func__,
addon->ID());
diff --git a/xbmc/addons/interfaces/General.cpp b/xbmc/addons/interfaces/General.cpp
index 50a38bd125..628d31c8e5 100644
--- a/xbmc/addons/interfaces/General.cpp
+++ b/xbmc/addons/interfaces/General.cpp
@@ -322,7 +322,7 @@ bool Interface_General::is_addon_avilable(void* kodiBase,
}
AddonPtr addonInfo;
- if (!CServiceBroker::GetAddonMgr().GetAddon(id, addonInfo, ADDON_UNKNOWN, OnlyEnabled::NO))
+ if (!CServiceBroker::GetAddonMgr().GetAddon(id, addonInfo, ADDON_UNKNOWN, OnlyEnabled::CHOICE_NO))
return false;
*version = strdup(addonInfo->Version().asString().c_str());
diff --git a/xbmc/addons/interfaces/gui/dialogs/YesNo.cpp b/xbmc/addons/interfaces/gui/dialogs/YesNo.cpp
index 2c635fb1f9..89dea580dd 100644
--- a/xbmc/addons/interfaces/gui/dialogs/YesNo.cpp
+++ b/xbmc/addons/interfaces/gui/dialogs/YesNo.cpp
@@ -63,8 +63,8 @@ bool Interface_GUIDialogYesNo::show_and_get_input_single_text(KODI_HANDLE kodiBa
}
DialogResponse result = HELPERS::ShowYesNoDialogText(heading, text, noLabel, yesLabel);
- *canceled = (result == DialogResponse::CANCELLED);
- return (result == DialogResponse::YES);
+ *canceled = (result == DialogResponse::CHOICE_CANCELLED);
+ return (result == DialogResponse::CHOICE_YES);
}
bool Interface_GUIDialogYesNo::show_and_get_input_line_text(KODI_HANDLE kodiBase,
@@ -95,7 +95,7 @@ bool Interface_GUIDialogYesNo::show_and_get_input_line_text(KODI_HANDLE kodiBase
}
return HELPERS::ShowYesNoDialogLines(heading, line0, line1, line2, noLabel, yesLabel) ==
- DialogResponse::YES;
+ DialogResponse::CHOICE_YES;
}
bool Interface_GUIDialogYesNo::show_and_get_input_line_button_text(KODI_HANDLE kodiBase,
@@ -129,8 +129,8 @@ bool Interface_GUIDialogYesNo::show_and_get_input_line_button_text(KODI_HANDLE k
DialogResponse result =
HELPERS::ShowYesNoDialogLines(heading, line0, line1, line2, noLabel, yesLabel);
- *canceled = (result == DialogResponse::CANCELLED);
- return (result == DialogResponse::YES);
+ *canceled = (result == DialogResponse::CHOICE_CANCELLED);
+ return (result == DialogResponse::CHOICE_YES);
}
} /* namespace ADDON */
diff --git a/xbmc/cdrip/EncoderFFmpeg.cpp b/xbmc/cdrip/EncoderFFmpeg.cpp
index c0ab4bd786..a1a1964fb0 100644
--- a/xbmc/cdrip/EncoderFFmpeg.cpp
+++ b/xbmc/cdrip/EncoderFFmpeg.cpp
@@ -43,7 +43,7 @@ bool CEncoderFFmpeg::Init()
const std::string addonId = CServiceBroker::GetSettingsComponent()->GetSettings()->GetString(
CSettings::SETTING_AUDIOCDS_ENCODER);
bool success = CServiceBroker::GetAddonMgr().GetAddon(addonId, addon, ADDON::ADDON_UNKNOWN,
- ADDON::OnlyEnabled::YES);
+ ADDON::OnlyEnabled::CHOICE_YES);
int bitrate;
if (success && addon)
{
diff --git a/xbmc/cores/AudioEngine/Sinks/AESinkAUDIOTRACK.cpp b/xbmc/cores/AudioEngine/Sinks/AESinkAUDIOTRACK.cpp
index cef7374483..6cc19ffb4e 100644
--- a/xbmc/cores/AudioEngine/Sinks/AESinkAUDIOTRACK.cpp
+++ b/xbmc/cores/AudioEngine/Sinks/AESinkAUDIOTRACK.cpp
@@ -637,8 +637,6 @@ void CAESinkAUDIOTRACK::GetDelay(AEDelayStatus& status)
gone = m_duration_written;
double delay = m_duration_written - gone;
- if (m_pause_ms > 0.0)
- delay = m_audiotrackbuffer_sec;
if (m_stampTimer.IsTimePast())
{
@@ -725,9 +723,30 @@ void CAESinkAUDIOTRACK::GetDelay(AEDelayStatus& status)
if (delay < 0.0)
delay = 0.0;
+ // the RAW hack for simulating pause bursts should not come
+ // into the way of hw delay
+ if (m_pause_ms > 0.0)
+ {
+ double difference = (m_audiotrackbuffer_sec - delay) * 1000;
+ if (usesAdvancedLogging)
+ {
+ CLog::Log(LOGINFO, "Faking Pause-Bursts in Delay - returning smoothed {} ms Original {} ms",
+ m_audiotrackbuffer_sec * 1000, delay * 1000);
+ CLog::Log(LOGINFO, "Difference: {} ms m_pause_ms {}", difference, m_pause_ms);
+ }
+ // buffer not yet reached
+ if (difference > 0.0)
+ delay = m_audiotrackbuffer_sec;
+ else
+ {
+ CLog::Log(LOGINFO, "Resetting pause bursts as buffer level was reached! (2)");
+ m_pause_ms = 0.0;
+ }
+ }
+
const double d = GetMovingAverageDelay(delay);
- // Audiotrack is caching more than we though it would
+ // Audiotrack is caching more than we thought it would
if (d > m_audiotrackbuffer_sec)
m_audiotrackbuffer_sec = d;
@@ -851,36 +870,28 @@ unsigned int CAESinkAUDIOTRACK::AddPackets(uint8_t **data, unsigned int frames,
double time_to_add_ms = 1000.0 * (CurrentHostCounter() - startTime) / CurrentHostFrequency();
if (m_passthrough && !m_info.m_wantsIECPassthrough)
{
-
// AT does not consume in a blocking way - it runs ahead and blocks
// exactly once with the last package for some 100 ms
- // help it sleeping a bit - but don't run dry -> at least 0.128 seconds of
- // audio in buffer (e.g. 4 AC3 packages)
+ double extra_sleep = 0.0;
if (time_to_add_ms < m_format.m_streamInfo.GetDuration())
+ extra_sleep = (m_format.m_streamInfo.GetDuration() - time_to_add_ms) / 2.0;
+
+ // if there is still place, just add it without blocking
+ if (m_delay < (m_audiotrackbuffer_sec - (m_format.m_streamInfo.GetDuration() / 1000.0)))
+ extra_sleep = 0;
+
+ if (m_pause_ms > 0.0)
{
- // leave enough head room for eventualities
- double extra_sleep = (m_format.m_streamInfo.GetDuration() - time_to_add_ms) / 2.0;
- // warmup
- if (m_pause_ms > 0)
- {
- m_pause_ms -= m_format.m_streamInfo.GetDuration();
- extra_sleep /= 4; // fillup after Addpause
- }
- else if (m_delay < 0.128)
+ extra_sleep = 0;
+ m_pause_ms -= m_format.m_streamInfo.GetDuration();
+ if (m_pause_ms <= 0.0)
{
- // care for underrun
- extra_sleep /= 2;
+ m_pause_ms = 0.0;
+ CLog::Log(LOGINFO, "Resetting pause bursts as buffer level was reached! (1)");
}
-
- usleep(extra_sleep * 1000);
- }
- else
- {
- if (m_pause_ms > 0)
- m_pause_ms -= time_to_add_ms;
- else
- m_pause_ms = 0;
}
+
+ usleep(extra_sleep * 1000);
}
else
{
@@ -911,9 +922,6 @@ void CAESinkAUDIOTRACK::AddPause(unsigned int millis)
// blocking, sleeping roughly and GetDelay smoothing
// In short: Shit in, shit out
usleep(millis * 1000);
- if (m_pause_ms < 0)
- m_pause_ms = 0.0;
-
m_pause_ms += millis;
}
diff --git a/xbmc/cores/RetroPlayer/RetroPlayer.cpp b/xbmc/cores/RetroPlayer/RetroPlayer.cpp
index cc98d7660c..78cd78e785 100644
--- a/xbmc/cores/RetroPlayer/RetroPlayer.cpp
+++ b/xbmc/cores/RetroPlayer/RetroPlayer.cpp
@@ -110,7 +110,7 @@ bool CRetroPlayer::OpenFile(const CFileItem& file, const CPlayerOptions& options
CLog::Log(LOGERROR, "RetroPlayer[PLAYER]: Can't play game, no game client was passed!");
}
else if (!CServiceBroker::GetAddonMgr().GetAddon(gameClientId, addon, ADDON::ADDON_GAMEDLL,
- ADDON::OnlyEnabled::YES))
+ ADDON::OnlyEnabled::CHOICE_YES))
{
CLog::Log(LOGERROR, "RetroPlayer[PLAYER]: Can't find add-on {} for game file!", gameClientId);
}
@@ -155,8 +155,8 @@ bool CRetroPlayer::OpenFile(const CFileItem& file, const CPlayerOptions& options
if (save->GameClientID() != m_gameClient->ID())
{
ADDON::AddonPtr addon;
- if (CServiceBroker::GetAddonMgr().GetAddon(save->GameClientID(), addon,
- ADDON::ADDON_UNKNOWN, ADDON::OnlyEnabled::YES))
+ if (CServiceBroker::GetAddonMgr().GetAddon(
+ save->GameClientID(), addon, ADDON::ADDON_UNKNOWN, ADDON::OnlyEnabled::CHOICE_YES))
{
// Warn the user that continuing with a different game client will
// overwrite the save
diff --git a/xbmc/cores/VideoPlayer/DVDCodecs/Video/DVDVideoCodecFFmpeg.cpp b/xbmc/cores/VideoPlayer/DVDCodecs/Video/DVDVideoCodecFFmpeg.cpp
index 795300cadb..2684df3f2f 100644
--- a/xbmc/cores/VideoPlayer/DVDCodecs/Video/DVDVideoCodecFFmpeg.cpp
+++ b/xbmc/cores/VideoPlayer/DVDCodecs/Video/DVDVideoCodecFFmpeg.cpp
@@ -326,7 +326,7 @@ bool CDVDVideoCodecFFmpeg::Open(CDVDStreamInfo &hints, CDVDCodecOptions &options
m_hints = hints;
m_options = options;
- AVCodec* pCodec;
+ AVCodec* pCodec = nullptr;
m_iOrientation = hints.orientation;
@@ -336,7 +336,16 @@ bool CDVDVideoCodecFFmpeg::Open(CDVDStreamInfo &hints, CDVDCodecOptions &options
m_processInfo.SetSwDeinterlacingMethods();
m_processInfo.SetVideoInterlaced(false);
- pCodec = avcodec_find_decoder(hints.codec);
+ // libdav1d av1 sw decoding is implemented as a separate decoder
+ // in ffmpeg which is always found first when calling `avcodec_find_decoder`.
+ // To get hwaccels we look for decoders registered for `av1`.
+ // The decoder state check is needed to succesfully fallback to sw decoding if
+ // necessary.
+ if (hints.codec == AV_CODEC_ID_AV1 && m_decoderState != STATE_HW_FAILED)
+ pCodec = avcodec_find_decoder_by_name("av1");
+
+ if (!pCodec)
+ pCodec = avcodec_find_decoder(hints.codec);
if(pCodec == NULL)
{
@@ -381,6 +390,7 @@ bool CDVDVideoCodecFFmpeg::Open(CDVDStreamInfo &hints, CDVDCodecOptions &options
m_pCodecContext->coded_height = hints.height;
m_pCodecContext->coded_width = hints.width;
m_pCodecContext->bits_per_coded_sample = hints.bitsperpixel;
+ m_pCodecContext->bits_per_raw_sample = hints.bitdepth;
if( hints.extradata && hints.extrasize > 0 )
{
diff --git a/xbmc/cores/VideoPlayer/DVDCodecs/Video/DXVA.cpp b/xbmc/cores/VideoPlayer/DVDCodecs/Video/DXVA.cpp
index a514fd0166..a9143b2397 100644
--- a/xbmc/cores/VideoPlayer/DVDCodecs/Video/DXVA.cpp
+++ b/xbmc/cores/VideoPlayer/DVDCodecs/Video/DXVA.cpp
@@ -1035,7 +1035,7 @@ static bool IsL41LimitedATI()
DXGI_ADAPTER_DESC AIdentifier = {};
DX::DeviceResources::Get()->GetAdapterDesc(&AIdentifier);
- if (AIdentifier.VendorId == PCIV_ATI)
+ if (AIdentifier.VendorId == PCIV_AMD)
{
for (unsigned idx = 0; UVDDeviceID[idx] != 0; idx++)
{
@@ -1052,7 +1052,7 @@ static bool HasVP3WidthBug(AVCodecContext* avctx)
DXGI_ADAPTER_DESC AIdentifier = {};
DX::DeviceResources::Get()->GetAdapterDesc(&AIdentifier);
- if (AIdentifier.VendorId == PCIV_nVidia &&
+ if (AIdentifier.VendorId == PCIV_NVIDIA &&
!CDVDCodecUtils::IsVP3CompatibleWidth(avctx->coded_width))
{
// Find the card in a known list of problematic VP3 hardware
@@ -1067,7 +1067,7 @@ static bool HasATIMP2Bug(AVCodecContext* avctx)
{
DXGI_ADAPTER_DESC AIdentifier = {};
DX::DeviceResources::Get()->GetAdapterDesc(&AIdentifier);
- if (AIdentifier.VendorId != PCIV_ATI)
+ if (AIdentifier.VendorId != PCIV_AMD)
return false;
// AMD/ATI card doesn't like some SD MPEG2 content
@@ -1245,7 +1245,7 @@ bool CDecoder::Open(AVCodecContext* avctx, AVCodecContext* mainctx, enum AVPixel
"DXVA: used Intel ClearVideo decoder, but no support workaround for it in libavcodec.");
#endif
}
- else if (ad.VendorId == PCIV_ATI && IsL41LimitedATI())
+ else if (ad.VendorId == PCIV_AMD && IsL41LimitedATI())
{
#ifdef FF_DXVA2_WORKAROUND_SCALING_LIST_ZIGZAG
m_avD3D11Context->workaround |= FF_DXVA2_WORKAROUND_SCALING_LIST_ZIGZAG;
@@ -1434,11 +1434,8 @@ bool CDecoder::OpenDecoder()
m_avD3D11Context->video_context = nullptr;
m_avD3D11Context->surface_count = m_refs;
- DXGI_ADAPTER_DESC AIdentifier = {};
- DX::DeviceResources::Get()->GetAdapterDesc(&AIdentifier);
-
- // use true shared buffers on Intel
- bool trueShared = m_dxvaContext->IsContextShared() && AIdentifier.VendorId == PCIV_Intel;
+ // use true shared buffers always on Intel or Nvidia/AMD with recent drivers
+ const bool trueShared = DX::DeviceResources::Get()->IsDXVA2SharedDecoderSurfaces();
if (!m_dxvaContext->CreateSurfaces(m_format, m_avD3D11Context->surface_count, m_surface_alignment,
m_avD3D11Context->surface, &m_sharedHandle, trueShared))
diff --git a/xbmc/cores/VideoPlayer/DVDCodecs/Video/VAAPI.cpp b/xbmc/cores/VideoPlayer/DVDCodecs/Video/VAAPI.cpp
index 37c7015b28..b860993072 100644
--- a/xbmc/cores/VideoPlayer/DVDCodecs/Video/VAAPI.cpp
+++ b/xbmc/cores/VideoPlayer/DVDCodecs/Video/VAAPI.cpp
@@ -54,6 +54,7 @@ using namespace std::chrono_literals;
#define NUM_RENDER_PICS 7
constexpr auto SETTING_VIDEOPLAYER_USEVAAPI = "videoplayer.usevaapi";
+constexpr auto SETTING_VIDEOPLAYER_USEVAAPIAV1 = "videoplayer.usevaapiav1";
constexpr auto SETTING_VIDEOPLAYER_USEVAAPIHEVC = "videoplayer.usevaapihevc";
constexpr auto SETTING_VIDEOPLAYER_USEVAAPIMPEG2 = "videoplayer.usevaapimpeg2";
constexpr auto SETTING_VIDEOPLAYER_USEVAAPIMPEG4 = "videoplayer.usevaapimpeg4";
@@ -532,14 +533,15 @@ bool CDecoder::Open(AVCodecContext* avctx, AVCodecContext* mainctx, const enum A
// check if user wants to decode this format with VAAPI
std::map<AVCodecID, std::string> settings_map = {
- { AV_CODEC_ID_H263, SETTING_VIDEOPLAYER_USEVAAPIMPEG4 },
- { AV_CODEC_ID_MPEG4, SETTING_VIDEOPLAYER_USEVAAPIMPEG4 },
- { AV_CODEC_ID_WMV3, SETTING_VIDEOPLAYER_USEVAAPIVC1 },
- { AV_CODEC_ID_VC1, SETTING_VIDEOPLAYER_USEVAAPIVC1 },
- { AV_CODEC_ID_MPEG2VIDEO, SETTING_VIDEOPLAYER_USEVAAPIMPEG2 },
- { AV_CODEC_ID_VP8, SETTING_VIDEOPLAYER_USEVAAPIVP8 },
- { AV_CODEC_ID_VP9, SETTING_VIDEOPLAYER_USEVAAPIVP9 },
- { AV_CODEC_ID_HEVC, SETTING_VIDEOPLAYER_USEVAAPIHEVC },
+ {AV_CODEC_ID_H263, SETTING_VIDEOPLAYER_USEVAAPIMPEG4},
+ {AV_CODEC_ID_MPEG4, SETTING_VIDEOPLAYER_USEVAAPIMPEG4},
+ {AV_CODEC_ID_WMV3, SETTING_VIDEOPLAYER_USEVAAPIVC1},
+ {AV_CODEC_ID_VC1, SETTING_VIDEOPLAYER_USEVAAPIVC1},
+ {AV_CODEC_ID_MPEG2VIDEO, SETTING_VIDEOPLAYER_USEVAAPIMPEG2},
+ {AV_CODEC_ID_VP8, SETTING_VIDEOPLAYER_USEVAAPIVP8},
+ {AV_CODEC_ID_VP9, SETTING_VIDEOPLAYER_USEVAAPIVP9},
+ {AV_CODEC_ID_HEVC, SETTING_VIDEOPLAYER_USEVAAPIHEVC},
+ {AV_CODEC_ID_AV1, SETTING_VIDEOPLAYER_USEVAAPIAV1},
};
auto entry = settings_map.find(avctx->codec_id);
@@ -585,6 +587,7 @@ bool CDecoder::Open(AVCodecContext* avctx, AVCodecContext* mainctx, const enum A
m_vaapiConfig.surfaceWidth = avctx->coded_width;
m_vaapiConfig.surfaceHeight = avctx->coded_height;
m_vaapiConfig.aspect = avctx->sample_aspect_ratio;
+ m_vaapiConfig.bitDepth = avctx->bits_per_raw_sample;
m_DisplayState = VAAPI_OPEN;
m_vaapiConfigured = false;
m_presentPicture = nullptr;
@@ -672,6 +675,20 @@ bool CDecoder::Open(AVCodecContext* avctx, AVCodecContext* mainctx, const enum A
if (!m_vaapiConfig.context->SupportsProfile(profile))
return false;
break;
+#if VA_CHECK_VERSION(1, 8, 0)
+ case AV_CODEC_ID_AV1:
+ {
+ if (avctx->profile == FF_PROFILE_AV1_MAIN)
+ profile = VAProfileAV1Profile0;
+ else if (avctx->profile == FF_PROFILE_AV1_HIGH)
+ profile = VAProfileAV1Profile1;
+ else
+ profile = VAProfileNone;
+ if (!m_vaapiConfig.context->SupportsProfile(profile))
+ return false;
+ break;
+ }
+#endif
default:
return false;
}
@@ -696,6 +713,8 @@ bool CDecoder::Open(AVCodecContext* avctx, AVCodecContext* mainctx, const enum A
m_vaapiConfig.maxReferences = 16;
else if (avctx->codec_id == AV_CODEC_ID_VP9)
m_vaapiConfig.maxReferences = 8;
+ else if (avctx->codec_id == AV_CODEC_ID_AV1)
+ m_vaapiConfig.maxReferences = 18;
else
m_vaapiConfig.maxReferences = 2;
@@ -1134,7 +1153,12 @@ bool CDecoder::ConfigVAAPI()
unsigned int format = VA_RT_FORMAT_YUV420;
std::int32_t pixelFormat = VA_FOURCC_NV12;
- if (m_vaapiConfig.profile == VAProfileHEVCMain10)
+ if ((m_vaapiConfig.profile == VAProfileHEVCMain10
+#if VA_CHECK_VERSION(1, 8, 0)
+ || m_vaapiConfig.profile == VAProfileAV1Profile0
+#endif
+ ) &&
+ m_vaapiConfig.bitDepth == 10)
{
format = VA_RT_FORMAT_YUV420_10BPP;
pixelFormat = VA_FOURCC_P010;
@@ -1256,11 +1280,12 @@ void CDecoder::Register(IVaapiWinSystem *winSystem, bool deepColor)
if (!settings)
return;
- constexpr std::array<const char*, 8> vaapiSettings = {
+ constexpr std::array<const char*, 9> vaapiSettings = {
SETTING_VIDEOPLAYER_USEVAAPI, SETTING_VIDEOPLAYER_USEVAAPIMPEG4,
SETTING_VIDEOPLAYER_USEVAAPIVC1, SETTING_VIDEOPLAYER_USEVAAPIMPEG2,
SETTING_VIDEOPLAYER_USEVAAPIVP8, SETTING_VIDEOPLAYER_USEVAAPIVP9,
- SETTING_VIDEOPLAYER_USEVAAPIHEVC, SETTING_VIDEOPLAYER_PREFERVAAPIRENDER};
+ SETTING_VIDEOPLAYER_USEVAAPIHEVC, SETTING_VIDEOPLAYER_PREFERVAAPIRENDER,
+ SETTING_VIDEOPLAYER_USEVAAPIAV1};
for (const auto vaapiSetting : vaapiSettings)
{
diff --git a/xbmc/cores/VideoPlayer/DVDCodecs/Video/VAAPI.h b/xbmc/cores/VideoPlayer/DVDCodecs/Video/VAAPI.h
index 8f966849d3..001f1bf00e 100644
--- a/xbmc/cores/VideoPlayer/DVDCodecs/Video/VAAPI.h
+++ b/xbmc/cores/VideoPlayer/DVDCodecs/Video/VAAPI.h
@@ -115,6 +115,7 @@ struct CVaapiConfig
VAConfigAttrib attrib;
CProcessInfo *processInfo;
bool driverIsMesa;
+ int bitDepth;
};
/**
diff --git a/xbmc/cores/VideoPlayer/DVDDemuxers/DVDDemux.h b/xbmc/cores/VideoPlayer/DVDDemuxers/DVDDemux.h
index 031b2cfe35..a16d2fe192 100644
--- a/xbmc/cores/VideoPlayer/DVDDemuxers/DVDDemux.h
+++ b/xbmc/cores/VideoPlayer/DVDDemuxers/DVDDemux.h
@@ -138,6 +138,7 @@ public:
int iOrientation = 0; // orientation of the video in degrees counter clockwise
int iBitsPerPixel = 0;
int iBitRate = 0;
+ int bitDepth = 0;
AVColorSpace colorSpace = AVCOL_SPC_UNSPECIFIED;
AVColorRange colorRange = AVCOL_RANGE_UNSPECIFIED;
diff --git a/xbmc/cores/VideoPlayer/DVDDemuxers/DVDDemuxClient.cpp b/xbmc/cores/VideoPlayer/DVDDemuxers/DVDDemuxClient.cpp
index 20ad677057..ad3c1c2d21 100644
--- a/xbmc/cores/VideoPlayer/DVDDemuxers/DVDDemuxClient.cpp
+++ b/xbmc/cores/VideoPlayer/DVDDemuxers/DVDDemuxClient.cpp
@@ -668,6 +668,8 @@ std::string CDVDDemuxClient::GetStreamCodecName(int iStreamId)
strName = "vp9";
else if (stream->codec == AV_CODEC_ID_HEVC)
strName = "hevc";
+ else if (stream->codec == AV_CODEC_ID_AV1)
+ strName = "av1";
}
return strName;
}
diff --git a/xbmc/cores/VideoPlayer/DVDDemuxers/DVDDemuxFFmpeg.cpp b/xbmc/cores/VideoPlayer/DVDDemuxers/DVDDemuxFFmpeg.cpp
index 7790befe56..8700c87b86 100644
--- a/xbmc/cores/VideoPlayer/DVDDemuxers/DVDDemuxFFmpeg.cpp
+++ b/xbmc/cores/VideoPlayer/DVDDemuxers/DVDDemuxFFmpeg.cpp
@@ -33,6 +33,11 @@
#include <sstream>
#include <utility>
+extern "C"
+{
+#include "libavutil/pixdesc.h"
+}
+
#ifdef HAVE_LIBBLURAY
#include "DVDInputStreams/DVDInputStreamBluray.h"
#endif
@@ -1639,6 +1644,11 @@ CDemuxStream* CDVDDemuxFFmpeg::AddStream(int streamIdx)
st->iOrientation = 0;
st->iBitsPerPixel = pStream->codecpar->bits_per_coded_sample;
st->iBitRate = static_cast<int>(pStream->codecpar->bit_rate);
+ st->bitDepth = 8;
+ const AVPixFmtDescriptor* desc =
+ av_pix_fmt_desc_get(static_cast<AVPixelFormat>(pStream->codecpar->format));
+ if (desc != nullptr && desc->comp != nullptr)
+ st->bitDepth = desc->comp[0].depth;
st->colorPrimaries = pStream->codecpar->color_primaries;
st->colorSpace = pStream->codecpar->color_space;
diff --git a/xbmc/cores/VideoPlayer/DVDStreamInfo.cpp b/xbmc/cores/VideoPlayer/DVDStreamInfo.cpp
index a30becd31f..ddf54c241b 100644
--- a/xbmc/cores/VideoPlayer/DVDStreamInfo.cpp
+++ b/xbmc/cores/VideoPlayer/DVDStreamInfo.cpp
@@ -71,6 +71,7 @@ void CDVDStreamInfo::Clear()
channellayout = 0;
orientation = 0;
+ bitdepth = 0;
}
bool CDVDStreamInfo::Equal(const CDVDStreamInfo& right, int compare)
@@ -91,22 +92,26 @@ bool CDVDStreamInfo::Equal(const CDVDStreamInfo& right, int compare)
}
// VIDEO
- if( fpsscale != right.fpsscale
- || fpsrate != right.fpsrate
- || height != right.height
- || width != right.width
- || stills != right.stills
- || level != right.level
- || profile != right.profile
- || ptsinvalid != right.ptsinvalid
- || forced_aspect != right.forced_aspect
- || bitsperpixel != right.bitsperpixel
- || vfr != right.vfr
- || colorSpace != right.colorSpace
- || colorRange != right.colorRange
- || colorPrimaries != right.colorPrimaries
- || colorTransferCharacteristic != right.colorTransferCharacteristic
- || stereo_mode != right.stereo_mode ) return false;
+ // clang-format off
+ if (fpsscale != right.fpsscale
+ || fpsrate != right.fpsrate
+ || height != right.height
+ || width != right.width
+ || stills != right.stills
+ || level != right.level
+ || profile != right.profile
+ || ptsinvalid != right.ptsinvalid
+ || forced_aspect != right.forced_aspect
+ || bitsperpixel != right.bitsperpixel
+ || bitdepth != right.bitdepth
+ || vfr != right.vfr
+ || colorSpace != right.colorSpace
+ || colorRange != right.colorRange
+ || colorPrimaries != right.colorPrimaries
+ || colorTransferCharacteristic != right.colorTransferCharacteristic
+ || stereo_mode != right.stereo_mode)
+ return false;
+ // clang-format on
if (masteringMetadata && right.masteringMetadata)
{
@@ -217,6 +222,7 @@ void CDVDStreamInfo::Assign(const CDVDStreamInfo& right, bool withextradata)
forced_aspect = right.forced_aspect;
orientation = right.orientation;
bitsperpixel = right.bitsperpixel;
+ bitdepth = right.bitdepth;
vfr = right.vfr;
codecOptions = right.codecOptions;
colorSpace = right.colorSpace;
@@ -286,6 +292,7 @@ void CDVDStreamInfo::Assign(const CDemuxStream& right, bool withextradata)
forced_aspect = stream->bForcedAspect;
orientation = stream->iOrientation;
bitsperpixel = stream->iBitsPerPixel;
+ bitdepth = stream->bitDepth;
colorSpace = stream->colorSpace;
colorRange = stream->colorRange;
colorPrimaries = stream->colorPrimaries;
diff --git a/xbmc/cores/VideoPlayer/DVDStreamInfo.h b/xbmc/cores/VideoPlayer/DVDStreamInfo.h
index 25049a3b83..840b66e980 100644
--- a/xbmc/cores/VideoPlayer/DVDStreamInfo.h
+++ b/xbmc/cores/VideoPlayer/DVDStreamInfo.h
@@ -66,6 +66,7 @@ public:
bool forced_aspect; // aspect is forced from container
int orientation; // orientation of the video in degrees counter clockwise
int bitsperpixel;
+ int bitdepth;
AVColorSpace colorSpace;
AVColorRange colorRange;
AVColorPrimaries colorPrimaries;
diff --git a/xbmc/cores/VideoPlayer/VideoPlayerVideo.cpp b/xbmc/cores/VideoPlayer/VideoPlayerVideo.cpp
index 14c562ca00..28cb58c9d5 100644
--- a/xbmc/cores/VideoPlayer/VideoPlayerVideo.cpp
+++ b/xbmc/cores/VideoPlayer/VideoPlayerVideo.cpp
@@ -105,6 +105,7 @@ bool CVideoPlayerVideo::OpenStream(CDVDStreamInfo hint)
if (hint.extrasize == 0)
{
// codecs which require extradata
+ // clang-format off
if (hint.codec == AV_CODEC_ID_NONE ||
hint.codec == AV_CODEC_ID_MPEG1VIDEO ||
hint.codec == AV_CODEC_ID_MPEG2VIDEO ||
@@ -112,7 +113,9 @@ bool CVideoPlayerVideo::OpenStream(CDVDStreamInfo hint)
hint.codec == AV_CODEC_ID_HEVC ||
hint.codec == AV_CODEC_ID_MPEG4 ||
hint.codec == AV_CODEC_ID_WMV3 ||
- hint.codec == AV_CODEC_ID_VC1)
+ hint.codec == AV_CODEC_ID_VC1 ||
+ hint.codec == AV_CODEC_ID_AV1)
+ // clang-format on
return false;
}
diff --git a/xbmc/dbwrappers/Database.cpp b/xbmc/dbwrappers/Database.cpp
index aa93955e81..d899e4f44c 100644
--- a/xbmc/dbwrappers/Database.cpp
+++ b/xbmc/dbwrappers/Database.cpp
@@ -390,7 +390,7 @@ bool CDatabase::ExecuteQuery(const std::string &strQuery)
return bReturn;
}
-bool CDatabase::ResultQuery(const std::string &strQuery)
+bool CDatabase::ResultQuery(const std::string& strQuery) const
{
bool bReturn = false;
diff --git a/xbmc/dbwrappers/Database.h b/xbmc/dbwrappers/Database.h
index a3bf01d9c1..441d6f83fd 100644
--- a/xbmc/dbwrappers/Database.h
+++ b/xbmc/dbwrappers/Database.h
@@ -178,7 +178,7 @@ public:
* @param strQuery The query to execute.
* @return True if the query was executed successfully, false otherwise.
*/
- bool ResultQuery(const std::string &strQuery);
+ bool ResultQuery(const std::string& strQuery) const;
/*!
* @brief Start a multiple execution queue. Any ExecuteQuery() function
diff --git a/xbmc/filesystem/AddonsDirectory.cpp b/xbmc/filesystem/AddonsDirectory.cpp
index e2274b7657..89a4fed92b 100644
--- a/xbmc/filesystem/AddonsDirectory.cpp
+++ b/xbmc/filesystem/AddonsDirectory.cpp
@@ -543,7 +543,7 @@ static bool Browse(const CURL& path, CFileItemList &items)
AddonPtr repoAddon;
const auto& addonMgr = CServiceBroker::GetAddonMgr();
- if (!addonMgr.GetAddon(repoId, repoAddon, ADDON_REPOSITORY, OnlyEnabled::YES))
+ if (!addonMgr.GetAddon(repoId, repoAddon, ADDON_REPOSITORY, OnlyEnabled::CHOICE_YES))
return false;
CAddonRepos addonRepos(addonMgr);
@@ -770,7 +770,7 @@ bool CAddonsDirectory::IsRepoDirectory(const CURL& url)
return url.GetHostName() == "repos" || url.GetHostName() == "all" ||
url.GetHostName() == "search" ||
CServiceBroker::GetAddonMgr().GetAddon(url.GetHostName(), tmp, ADDON_REPOSITORY,
- OnlyEnabled::YES);
+ OnlyEnabled::CHOICE_YES);
}
void CAddonsDirectory::GenerateAddonListing(const CURL& path,
@@ -819,7 +819,7 @@ void CAddonsDirectory::GenerateAddonListing(const CURL& path,
validUpdateOrigin = mapEntry->second.m_update->Origin();
}
- bool fromOfficialRepo = CAddonRepos::IsFromOfficialRepo(addon, CheckAddonPath::NO);
+ bool fromOfficialRepo = CAddonRepos::IsFromOfficialRepo(addon, CheckAddonPath::CHOICE_NO);
pItem->SetProperty("Addon.IsInstalled", installed);
pItem->SetProperty("Addon.IsEnabled", installed && !disabled);
diff --git a/xbmc/filesystem/PluginDirectory.cpp b/xbmc/filesystem/PluginDirectory.cpp
index c89932c75d..894839fc56 100644
--- a/xbmc/filesystem/PluginDirectory.cpp
+++ b/xbmc/filesystem/PluginDirectory.cpp
@@ -71,11 +71,11 @@ bool CPluginDirectory::StartScript(const std::string& strPath, bool resume)
ADDON::AddonPtr addon;
// try the plugin type first, and if not found, try an unknown type
if (!CServiceBroker::GetAddonMgr().GetAddon(url.GetHostName(), addon, ADDON_PLUGIN,
- OnlyEnabled::YES) &&
+ OnlyEnabled::CHOICE_YES) &&
!CServiceBroker::GetAddonMgr().GetAddon(url.GetHostName(), addon, ADDON_UNKNOWN,
- OnlyEnabled::YES) &&
+ OnlyEnabled::CHOICE_YES) &&
!CAddonInstaller::GetInstance().InstallModal(url.GetHostName(), addon,
- InstallModalPrompt::PROMPT))
+ InstallModalPrompt::CHOICE_YES))
{
CLog::Log(LOGERROR, "Unable to find plugin {}", url.GetHostName());
return false;
@@ -427,9 +427,9 @@ bool CPluginDirectory::RunScriptWithParams(const std::string& strPath, bool resu
AddonPtr addon;
if (!CServiceBroker::GetAddonMgr().GetAddon(url.GetHostName(), addon, ADDON_PLUGIN,
- OnlyEnabled::YES) &&
+ OnlyEnabled::CHOICE_YES) &&
!CAddonInstaller::GetInstance().InstallModal(url.GetHostName(), addon,
- InstallModalPrompt::PROMPT))
+ InstallModalPrompt::CHOICE_YES))
{
CLog::Log(LOGERROR, "Unable to find plugin {}", url.GetHostName());
return false;
@@ -512,7 +512,7 @@ bool CPluginDirectory::IsMediaLibraryScanningAllowed(const std::string& content,
return false;
AddonPtr addon;
if (!CServiceBroker::GetAddonMgr().GetAddon(url.GetHostName(), addon, ADDON_PLUGIN,
- OnlyEnabled::YES))
+ OnlyEnabled::CHOICE_YES))
{
CLog::Log(LOGERROR, "Unable to find plugin {}", url.GetHostName());
return false;
diff --git a/xbmc/filesystem/ResourceFile.cpp b/xbmc/filesystem/ResourceFile.cpp
index 65ac717093..4b0b5fd439 100644
--- a/xbmc/filesystem/ResourceFile.cpp
+++ b/xbmc/filesystem/ResourceFile.cpp
@@ -46,7 +46,8 @@ bool CResourceFile::TranslatePath(const CURL &url, std::string &translatedPath)
return false;
AddonPtr addon;
- if (!CServiceBroker::GetAddonMgr().GetAddon(addonId, addon, ADDON_UNKNOWN, OnlyEnabled::YES) ||
+ if (!CServiceBroker::GetAddonMgr().GetAddon(addonId, addon, ADDON_UNKNOWN,
+ OnlyEnabled::CHOICE_YES) ||
addon == NULL)
return false;
diff --git a/xbmc/filesystem/StackDirectory.cpp b/xbmc/filesystem/StackDirectory.cpp
index 99c081f221..a752a94648 100644
--- a/xbmc/filesystem/StackDirectory.cpp
+++ b/xbmc/filesystem/StackDirectory.cpp
@@ -147,7 +147,7 @@ namespace XFILE
std::string CStackDirectory::GetFirstStackedFile(const std::string &strPath)
{
// the stacked files are always in volume order, so just get up to the first filename
- // occurence of " , "
+ // occurrence of " , "
std::string file, folder;
size_t pos = strPath.find(" , ");
if (pos != std::string::npos)
@@ -191,7 +191,7 @@ namespace XFILE
std::string folder, file;
URIUtils::Split(items[stack[0]]->GetPath(), folder, file);
stackedPath += folder;
- // double escape any occurence of commas
+ // double escape any occurrence of commas
StringUtils::Replace(file, ",", ",,");
stackedPath += file;
for (unsigned int i = 1; i < stack.size(); ++i)
@@ -199,7 +199,7 @@ namespace XFILE
stackedPath += " , ";
file = items[stack[i]]->GetPath();
- // double escape any occurence of commas
+ // double escape any occurrence of commas
StringUtils::Replace(file, ",", ",,");
stackedPath += file;
}
@@ -214,7 +214,7 @@ namespace XFILE
std::string folder, file;
URIUtils::Split(paths[0], folder, file);
stackedPath += folder;
- // double escape any occurence of commas
+ // double escape any occurrence of commas
StringUtils::Replace(file, ",", ",,");
stackedPath += file;
for (unsigned int i = 1; i < paths.size(); ++i)
@@ -222,7 +222,7 @@ namespace XFILE
stackedPath += " , ";
file = paths[i];
- // double escape any occurence of commas
+ // double escape any occurrence of commas
StringUtils::Replace(file, ",", ",,");
stackedPath += file;
}
diff --git a/xbmc/games/addons/GameClient.cpp b/xbmc/games/addons/GameClient.cpp
index 12b4c60572..ce404c082c 100644
--- a/xbmc/games/addons/GameClient.cpp
+++ b/xbmc/games/addons/GameClient.cpp
@@ -420,7 +420,7 @@ std::string CGameClient::GetMissingResource()
{
AddonPtr addon;
const bool bInstalled = CServiceBroker::GetAddonMgr().GetAddon(
- strDependencyId, addon, ADDON_UNKNOWN, OnlyEnabled::YES);
+ strDependencyId, addon, ADDON_UNKNOWN, OnlyEnabled::CHOICE_YES);
if (!bInstalled)
{
strAddonId = strDependencyId;
diff --git a/xbmc/games/addons/GameClientProperties.cpp b/xbmc/games/addons/GameClientProperties.cpp
index 14ef38d5b2..9994b4a231 100644
--- a/xbmc/games/addons/GameClientProperties.cpp
+++ b/xbmc/games/addons/GameClientProperties.cpp
@@ -113,7 +113,7 @@ const char** CGameClientProperties::GetResourceDirectories(void)
const std::string& strAddonId = it->id;
AddonPtr addon;
if (CServiceBroker::GetAddonMgr().GetAddon(strAddonId, addon, ADDON_RESOURCE_GAMES,
- OnlyEnabled::YES))
+ OnlyEnabled::CHOICE_YES))
{
std::shared_ptr<CGameResource> resource = std::static_pointer_cast<CGameResource>(addon);
@@ -204,7 +204,7 @@ bool CGameClientProperties::GetProxyAddons(ADDON::VECADDONS& addons)
{
AddonPtr addon;
if (CServiceBroker::GetAddonMgr().GetAddon(dependency.id, addon, ADDON_UNKNOWN,
- OnlyEnabled::NO))
+ OnlyEnabled::CHOICE_NO))
{
// If add-on is disabled, ask the user to enable it
if (CServiceBroker::GetAddonMgr().IsAddonDisabled(dependency.id))
diff --git a/xbmc/games/controllers/ControllerManager.cpp b/xbmc/games/controllers/ControllerManager.cpp
index b6d64f5a46..d612020be3 100644
--- a/xbmc/games/controllers/ControllerManager.cpp
+++ b/xbmc/games/controllers/ControllerManager.cpp
@@ -26,7 +26,7 @@ ControllerPtr CControllerManager::GetController(const std::string& controllerId)
{
AddonPtr addon;
if (CServiceBroker::GetAddonMgr().GetAddon(controllerId, addon, ADDON_GAME_CONTROLLER,
- OnlyEnabled::NO))
+ OnlyEnabled::CHOICE_NO))
cachedController = LoadController(addon);
}
diff --git a/xbmc/games/controllers/windows/ControllerInstaller.cpp b/xbmc/games/controllers/windows/ControllerInstaller.cpp
index 390aad8f55..26cf854749 100644
--- a/xbmc/games/controllers/windows/ControllerInstaller.cpp
+++ b/xbmc/games/controllers/windows/ControllerInstaller.cpp
@@ -108,7 +108,7 @@ void CControllerInstaller::Process()
pProgressDialog->SetPercentage(percentage);
if (!ADDON::CAddonInstaller::GetInstance().InstallOrUpdate(
- addon->ID(), ADDON::BackgroundJob::NO, ADDON::ModalJob::NO))
+ addon->ID(), ADDON::BackgroundJob::CHOICE_NO, ADDON::ModalJob::CHOICE_NO))
{
CLog::Log(LOGERROR, "Controller installer: Failed to install {}", addon->ID());
// "Error"
diff --git a/xbmc/games/controllers/windows/GUIControllerWindow.cpp b/xbmc/games/controllers/windows/GUIControllerWindow.cpp
index a2096e271a..d2570d001e 100644
--- a/xbmc/games/controllers/windows/GUIControllerWindow.cpp
+++ b/xbmc/games/controllers/windows/GUIControllerWindow.cpp
@@ -223,7 +223,8 @@ void CGUIControllerWindow::OnInitWindow(void)
{
ADDON::AddonPtr addon;
if (CServiceBroker::GetAddonMgr().GetAddon(gameSettingsHandle->GameClientID(), addon,
- ADDON::ADDON_GAMEDLL, ADDON::OnlyEnabled::YES))
+ ADDON::ADDON_GAMEDLL,
+ ADDON::OnlyEnabled::CHOICE_YES))
gameClient = std::static_pointer_cast<CGameClient>(addon);
}
}
diff --git a/xbmc/games/controllers/windows/GUIPortWindow.cpp b/xbmc/games/controllers/windows/GUIPortWindow.cpp
index 0ba93284cd..47e7aa347b 100644
--- a/xbmc/games/controllers/windows/GUIPortWindow.cpp
+++ b/xbmc/games/controllers/windows/GUIPortWindow.cpp
@@ -119,7 +119,8 @@ void CGUIPortWindow::OnInitWindow()
{
ADDON::AddonPtr addon;
if (CServiceBroker::GetAddonMgr().GetAddon(gameSettingsHandle->GameClientID(), addon,
- ADDON::ADDON_GAMEDLL, ADDON::OnlyEnabled::YES))
+ ADDON::ADDON_GAMEDLL,
+ ADDON::OnlyEnabled::CHOICE_YES))
gameClient = std::static_pointer_cast<CGameClient>(addon);
}
}
diff --git a/xbmc/games/dialogs/GUIDialogSelectGameClient.cpp b/xbmc/games/dialogs/GUIDialogSelectGameClient.cpp
index 3b2afa458a..66a24ef773 100644
--- a/xbmc/games/dialogs/GUIDialogSelectGameClient.cpp
+++ b/xbmc/games/dialogs/GUIDialogSelectGameClient.cpp
@@ -133,7 +133,7 @@ bool CGUIDialogSelectGameClient::Install(const std::string& gameClient)
{
ADDON::AddonPtr installedAddon;
bInstalled = ADDON::CAddonInstaller::GetInstance().InstallModal(
- gameClient, installedAddon, ADDON::InstallModalPrompt::NO_PROMPT);
+ gameClient, installedAddon, ADDON::InstallModalPrompt::CHOICE_NO);
if (!bInstalled)
{
CLog::Log(LOGERROR, "Select game client dialog: Failed to install {}", gameClient);
diff --git a/xbmc/games/dialogs/osd/DialogGameAdvancedSettings.cpp b/xbmc/games/dialogs/osd/DialogGameAdvancedSettings.cpp
index 5a035c622d..dd3fc7f307 100644
--- a/xbmc/games/dialogs/osd/DialogGameAdvancedSettings.cpp
+++ b/xbmc/games/dialogs/osd/DialogGameAdvancedSettings.cpp
@@ -35,7 +35,8 @@ bool CDialogGameAdvancedSettings::OnMessage(CGUIMessage& message)
{
ADDON::AddonPtr addon;
if (CServiceBroker::GetAddonMgr().GetAddon(gameSettingsHandle->GameClientID(), addon,
- ADDON::ADDON_GAMEDLL, ADDON::OnlyEnabled::YES))
+ ADDON::ADDON_GAMEDLL,
+ ADDON::OnlyEnabled::CHOICE_YES))
{
gameSettingsHandle.reset();
CGUIDialogAddonSettings::ShowForAddon(addon);
diff --git a/xbmc/guilib/GUIAudioManager.cpp b/xbmc/guilib/GUIAudioManager.cpp
index 68dc454841..e374c2fecf 100644
--- a/xbmc/guilib/GUIAudioManager.cpp
+++ b/xbmc/guilib/GUIAudioManager.cpp
@@ -199,7 +199,7 @@ std::string GetSoundSkinPath()
ADDON::AddonPtr addon;
if (!CServiceBroker::GetAddonMgr().GetAddon(value, addon, ADDON::ADDON_RESOURCE_UISOUNDS,
- ADDON::OnlyEnabled::YES))
+ ADDON::OnlyEnabled::CHOICE_YES))
{
CLog::Log(LOGINFO, "Unknown sounds addon '{}'. Setting default sounds.", value);
setting->Reset();
diff --git a/xbmc/guilib/GUIBaseContainer.cpp b/xbmc/guilib/GUIBaseContainer.cpp
index a38c32c6e7..d39b102a45 100644
--- a/xbmc/guilib/GUIBaseContainer.cpp
+++ b/xbmc/guilib/GUIBaseContainer.cpp
@@ -48,22 +48,65 @@ CGUIBaseContainer::CGUIBaseContainer(int parentID, int controlID, float posX, fl
m_cacheItems = preloadItems;
m_scrollItemsPerFrame = 0.0f;
m_type = VIEW_TYPE_NONE;
- m_listProvider = NULL;
m_autoScrollMoveTime = 0;
m_autoScrollDelayTime = 0;
m_autoScrollIsReversed = false;
m_lastRenderTime = 0;
}
-CGUIBaseContainer::CGUIBaseContainer(const CGUIBaseContainer &) = default;
+CGUIBaseContainer::CGUIBaseContainer(const CGUIBaseContainer& other)
+ : IGUIContainer(other),
+ m_renderOffset(other.m_renderOffset),
+ m_analogScrollCount(other.m_analogScrollCount),
+ m_lastHoldTime(other.m_lastHoldTime),
+ m_orientation(other.m_orientation),
+ m_itemsPerPage(other.m_itemsPerPage),
+ m_pageControl(other.m_pageControl),
+ m_layoutCondition(other.m_layoutCondition),
+ m_focusedLayoutCondition(other.m_focusedLayoutCondition),
+ m_scroller(other.m_scroller),
+ m_listProvider(other.m_listProvider ? other.m_listProvider->Clone() : nullptr),
+ m_wasReset(other.m_wasReset),
+ m_letterOffsets(other.m_letterOffsets),
+ m_autoScrollCondition(other.m_autoScrollCondition),
+ m_autoScrollMoveTime(other.m_autoScrollMoveTime),
+ m_autoScrollDelayTime(other.m_autoScrollDelayTime),
+ m_autoScrollIsReversed(other.m_autoScrollIsReversed),
+ m_lastRenderTime(other.m_lastRenderTime),
+ m_cursor(other.m_cursor),
+ m_offset(other.m_offset),
+ m_cacheItems(other.m_cacheItems),
+ m_scrollTimer(other.m_scrollTimer),
+ m_lastScrollStartTimer(other.m_lastScrollStartTimer),
+ m_pageChangeTimer(other.m_pageChangeTimer),
+ m_clickActions(other.m_clickActions),
+ m_focusActions(other.m_focusActions),
+ m_unfocusActions(other.m_unfocusActions),
+ m_matchTimer(other.m_matchTimer),
+ m_match(other.m_match),
+ m_scrollItemsPerFrame(other.m_scrollItemsPerFrame),
+ m_gestureActive(other.m_gestureActive),
+ m_waitForScrollEnd(other.m_waitForScrollEnd),
+ m_lastScrollValue(other.m_lastScrollValue)
+{
+ // Initialize CGUIControl
+ m_bInvalidated = true;
+
+ for (const auto& item : other.m_items)
+ m_items.emplace_back(std::make_shared<CGUIListItem>(*item));
+
+ for (const auto& layout : other.m_layouts)
+ m_layouts.emplace_back(layout, this);
+
+ for (const auto& focusedLayout : other.m_focusedLayouts)
+ m_focusedLayouts.emplace_back(focusedLayout, this);
+}
CGUIBaseContainer::~CGUIBaseContainer(void)
{
// release the container from items
for (const auto& item : m_items)
item->FreeMemory();
-
- delete m_listProvider;
}
void CGUIBaseContainer::DoProcess(unsigned int currentTime, CDirtyRegionList &dirtyregions)
@@ -165,7 +208,7 @@ void CGUIBaseContainer::ProcessItem(float posX, float posY, CGUIListItemPtr& ite
{
if (!item->GetFocusedLayout())
{
- item->SetFocusedLayout(CGUIListItemLayoutPtr(new CGUIListItemLayout(*m_focusedLayout, this)));
+ item->SetFocusedLayout(std::make_unique<CGUIListItemLayout>(*m_focusedLayout, this));
}
if (item->GetFocusedLayout())
{
@@ -191,8 +234,7 @@ void CGUIBaseContainer::ProcessItem(float posX, float posY, CGUIListItemPtr& ite
item->GetFocusedLayout()->SetFocusedItem(0); // focus is not set
if (!item->GetLayout())
{
- CGUIListItemLayoutPtr layout(new CGUIListItemLayout(*m_layout));
- layout->SetParentControl(this);
+ CGUIListItemLayoutPtr layout = std::make_unique<CGUIListItemLayout>(*m_layout, this);
item->SetLayout(std::move(layout));
}
if (item->GetFocusedLayout())
@@ -1213,16 +1255,14 @@ void CGUIBaseContainer::LoadLayout(TiXmlElement *layout)
void CGUIBaseContainer::LoadListProvider(TiXmlElement *content, int defaultItem, bool defaultAlways)
{
- delete m_listProvider;
m_listProvider = IListProvider::Create(content, GetParentID());
if (m_listProvider)
m_listProvider->SetDefaultItem(defaultItem, defaultAlways);
}
-void CGUIBaseContainer::SetListProvider(IListProvider *provider)
+void CGUIBaseContainer::SetListProvider(std::unique_ptr<IListProvider> provider)
{
- delete m_listProvider;
- m_listProvider = provider;
+ m_listProvider = std::move(provider);
UpdateListProvider(true);
}
diff --git a/xbmc/guilib/GUIBaseContainer.h b/xbmc/guilib/GUIBaseContainer.h
index 4237421335..2ca35f0026 100644
--- a/xbmc/guilib/GUIBaseContainer.h
+++ b/xbmc/guilib/GUIBaseContainer.h
@@ -18,6 +18,7 @@
#include "utils/Stopwatch.h"
#include <list>
+#include <memory>
#include <utility>
#include <vector>
@@ -34,7 +35,7 @@ class CGUIBaseContainer : public IGUIContainer
{
public:
CGUIBaseContainer(int parentID, int controlID, float posX, float posY, float width, float height, ORIENTATION orientation, const CScroller& scroller, int preloadItems);
- CGUIBaseContainer(const CGUIBaseContainer &);
+ explicit CGUIBaseContainer(const CGUIBaseContainer& other);
~CGUIBaseContainer(void) override;
bool OnAction(const CAction &action) override;
@@ -75,7 +76,7 @@ public:
/*! \brief Set the list provider for this container (for python).
\param provider the list provider to use for this container.
*/
- void SetListProvider(IListProvider *provider);
+ void SetListProvider(std::unique_ptr<IListProvider> provider);
/*! \brief Set the offset of the first item in the container from the container's position
Useful for lists/panels where the focused item may be larger than the non-focused items and thus
@@ -147,8 +148,8 @@ protected:
std::list<CGUIListItemLayout> m_layouts;
std::list<CGUIListItemLayout> m_focusedLayouts;
- CGUIListItemLayout *m_layout;
- CGUIListItemLayout *m_focusedLayout;
+ CGUIListItemLayout* m_layout{nullptr};
+ CGUIListItemLayout* m_focusedLayout{nullptr};
bool m_layoutCondition = false;
bool m_focusedLayoutCondition = false;
@@ -158,7 +159,7 @@ protected:
CScroller m_scroller;
- IListProvider *m_listProvider;
+ std::unique_ptr<IListProvider> m_listProvider;
bool m_wasReset; // true if we've received a Reset message until we've rendered once. Allows
// us to make sure we don't tell the infomanager that we've been moving when
diff --git a/xbmc/guilib/GUIButtonControl.cpp b/xbmc/guilib/GUIButtonControl.cpp
index ec16e34d67..0e7f757edc 100644
--- a/xbmc/guilib/GUIButtonControl.cpp
+++ b/xbmc/guilib/GUIButtonControl.cpp
@@ -176,7 +176,7 @@ void CGUIButtonControl::ProcessText(unsigned int currentTime)
// auto-width - adjust hitrect
if (m_minWidth && m_width != renderWidth)
{
- CRect rect(m_posX, m_posY, renderWidth, m_height);
+ CRect rect{m_posX, m_posY, m_posX + renderWidth, m_posY + m_height};
SetHitRect(rect, m_hitColor);
}
diff --git a/xbmc/guilib/GUIControlFactory.cpp b/xbmc/guilib/GUIControlFactory.cpp
index 9ce6711330..7119b9de13 100644
--- a/xbmc/guilib/GUIControlFactory.cpp
+++ b/xbmc/guilib/GUIControlFactory.cpp
@@ -1129,7 +1129,8 @@ CGUIControl* CGUIControlFactory::Create(int parentID, const CRect &rect, TiXmlEl
break;
case CGUIControl::GUICONTROL_LABEL:
{
- const GUIINFO::CGUIInfoLabel &content = (infoLabels.size()) ? infoLabels[0] : GUIINFO::CGUIInfoLabel("");
+ static const GUIINFO::CGUIInfoLabel empty;
+ const GUIINFO::CGUIInfoLabel& content = !infoLabels.empty() ? infoLabels[0] : empty;
if (insideContainer)
{ // inside lists we use CGUIListLabel
control = new CGUIListLabel(parentID, id, posX, posY, width, height, labelInfo, content, scrollValue);
diff --git a/xbmc/guilib/GUIControlGroup.h b/xbmc/guilib/GUIControlGroup.h
index 57e8ac97f0..5f4a761374 100644
--- a/xbmc/guilib/GUIControlGroup.h
+++ b/xbmc/guilib/GUIControlGroup.h
@@ -26,7 +26,7 @@ class CGUIControlGroup : public CGUIControlLookup
public:
CGUIControlGroup();
CGUIControlGroup(int parentID, int controlID, float posX, float posY, float width, float height);
- CGUIControlGroup(const CGUIControlGroup &from);
+ explicit CGUIControlGroup(const CGUIControlGroup& from);
~CGUIControlGroup(void) override;
CGUIControlGroup* Clone() const override { return new CGUIControlGroup(*this); }
diff --git a/xbmc/guilib/GUIControlLookup.cpp b/xbmc/guilib/GUIControlLookup.cpp
index 33548a1ce5..8c572bb331 100644
--- a/xbmc/guilib/GUIControlLookup.cpp
+++ b/xbmc/guilib/GUIControlLookup.cpp
@@ -8,6 +8,10 @@
#include "GUIControlLookup.h"
+CGUIControlLookup::CGUIControlLookup(const CGUIControlLookup& from) : CGUIControl(from)
+{
+}
+
CGUIControl *CGUIControlLookup::GetControl(int iControl, std::vector<CGUIControl*> *idCollector)
{
if (idCollector)
diff --git a/xbmc/guilib/GUIControlLookup.h b/xbmc/guilib/GUIControlLookup.h
index 0118305a54..01175e4b90 100644
--- a/xbmc/guilib/GUIControlLookup.h
+++ b/xbmc/guilib/GUIControlLookup.h
@@ -16,8 +16,7 @@ public:
CGUIControlLookup() = default;
CGUIControlLookup(int parentID, int controlID, float posX, float posY, float width, float height)
: CGUIControl(parentID, controlID, posX, posY, width, height) {}
- CGUIControlLookup(const CGUIControlLookup &from)
- : CGUIControl(from) {}
+ explicit CGUIControlLookup(const CGUIControlLookup& from);
~CGUIControlLookup(void) override = default;
CGUIControl *GetControl(int id, std::vector<CGUIControl*> *idCollector = nullptr) override;
diff --git a/xbmc/guilib/GUIDialog.cpp b/xbmc/guilib/GUIDialog.cpp
index 56ec5f008b..3205f27901 100644
--- a/xbmc/guilib/GUIDialog.cpp
+++ b/xbmc/guilib/GUIDialog.cpp
@@ -38,16 +38,7 @@ CGUIDialog::~CGUIDialog(void) = default;
bool CGUIDialog::Load(TiXmlElement* pRootElement)
{
- bool retVal = CGUIWindow::Load(pRootElement);
-
- if (retVal && IsCustom())
- {
- // custom dialog's modality type is modeless if visible condition is specified.
- if (m_visibleCondition)
- m_modalityType = DialogModalityType::MODELESS;
- }
-
- return retVal;
+ return CGUIWindow::Load(pRootElement);
}
void CGUIDialog::OnWindowLoaded()
diff --git a/xbmc/guilib/GUIListContainer.cpp b/xbmc/guilib/GUIListContainer.cpp
index 158cd769ca..b078263aa6 100644
--- a/xbmc/guilib/GUIListContainer.cpp
+++ b/xbmc/guilib/GUIListContainer.cpp
@@ -20,6 +20,10 @@ CGUIListContainer::CGUIListContainer(int parentID, int controlID, float posX, fl
m_type = VIEW_TYPE_LIST;
}
+CGUIListContainer::CGUIListContainer(const CGUIListContainer& other) : CGUIBaseContainer(other)
+{
+}
+
CGUIListContainer::~CGUIListContainer(void) = default;
bool CGUIListContainer::OnAction(const CAction &action)
diff --git a/xbmc/guilib/GUIListContainer.h b/xbmc/guilib/GUIListContainer.h
index 3032cf6e1f..d16aa65bea 100644
--- a/xbmc/guilib/GUIListContainer.h
+++ b/xbmc/guilib/GUIListContainer.h
@@ -26,12 +26,13 @@ class CGUIListContainer : public CGUIBaseContainer
{
public:
CGUIListContainer(int parentID, int controlID, float posX, float posY, float width, float height, ORIENTATION orientation, const CScroller& scroller, int preloadItems);
-//#ifdef GUILIB_PYTHON_COMPATIBILITY
+ explicit CGUIListContainer(const CGUIListContainer& other);
+ //#ifdef GUILIB_PYTHON_COMPATIBILITY
CGUIListContainer(int parentID, int controlID, float posX, float posY, float width, float height,
const CLabelInfo& labelInfo, const CLabelInfo& labelInfo2,
const CTextureInfo& textureButton, const CTextureInfo& textureButtonFocus,
float textureHeight, float itemWidth, float itemHeight, float spaceBetweenItems);
-//#endif
+ //#endif
~CGUIListContainer(void) override;
CGUIListContainer* Clone() const override { return new CGUIListContainer(*this); }
diff --git a/xbmc/guilib/GUIListGroup.h b/xbmc/guilib/GUIListGroup.h
index 5316df2b8b..548cdec23e 100644
--- a/xbmc/guilib/GUIListGroup.h
+++ b/xbmc/guilib/GUIListGroup.h
@@ -23,7 +23,7 @@ class CGUIListGroup final : public CGUIControlGroup
{
public:
CGUIListGroup(int parentID, int controlID, float posX, float posY, float width, float height);
- CGUIListGroup(const CGUIListGroup &right);
+ explicit CGUIListGroup(const CGUIListGroup& right);
~CGUIListGroup(void) override;
CGUIListGroup* Clone() const override { return new CGUIListGroup(*this); }
diff --git a/xbmc/guilib/GUIListItem.h b/xbmc/guilib/GUIListItem.h
index df53e3f333..7c2d0dd6d2 100644
--- a/xbmc/guilib/GUIListItem.h
+++ b/xbmc/guilib/GUIListItem.h
@@ -48,7 +48,7 @@ public:
/// @}
CGUIListItem(void);
- CGUIListItem(const CGUIListItem& item);
+ explicit CGUIListItem(const CGUIListItem& item);
explicit CGUIListItem(const std::string& strLabel);
virtual ~CGUIListItem(void);
virtual CGUIListItem* Clone() const { return new CGUIListItem(*this); }
diff --git a/xbmc/guilib/GUIListItemLayout.cpp b/xbmc/guilib/GUIListItemLayout.cpp
index e6bd96e46b..a8b51f2ce4 100644
--- a/xbmc/guilib/GUIListItemLayout.cpp
+++ b/xbmc/guilib/GUIListItemLayout.cpp
@@ -28,6 +28,11 @@ CGUIListItemLayout::CGUIListItemLayout()
}
CGUIListItemLayout::CGUIListItemLayout(const CGUIListItemLayout& from)
+ : CGUIListItemLayout(from, nullptr)
+{
+}
+
+CGUIListItemLayout::CGUIListItemLayout(const CGUIListItemLayout& from, CGUIControl* control)
: m_group(from.m_group),
m_width(from.m_width),
m_height(from.m_height),
@@ -37,20 +42,12 @@ CGUIListItemLayout::CGUIListItemLayout(const CGUIListItemLayout& from)
m_isPlaying(from.m_isPlaying),
m_infoUpdateMillis(from.m_infoUpdateMillis)
{
+ m_group.SetParentControl(control);
m_infoUpdateTimeout.Set(m_infoUpdateMillis);
-}
-CGUIListItemLayout::CGUIListItemLayout(const CGUIListItemLayout &from, CGUIControl *control)
-: m_group(from.m_group), m_isPlaying(from.m_isPlaying)
-{
- m_width = from.m_width;
- m_height = from.m_height;
- m_focused = from.m_focused;
- m_condition = from.m_condition;
- m_infoUpdateMillis = from.m_infoUpdateMillis;
- m_infoUpdateTimeout.Set(m_infoUpdateMillis);
- m_invalidated = true;
- m_group.SetParentControl(control);
+ // m_group was just created, cloned controls with resources must be allocated
+ // before use
+ m_group.AllocResources();
}
bool CGUIListItemLayout::IsAnimating(ANIMATION_TYPE animType)
diff --git a/xbmc/guilib/GUIListItemLayout.h b/xbmc/guilib/GUIListItemLayout.h
index a15e2c9531..6a84b6573a 100644
--- a/xbmc/guilib/GUIListItemLayout.h
+++ b/xbmc/guilib/GUIListItemLayout.h
@@ -21,8 +21,8 @@ class CGUIListItemLayout final
{
public:
CGUIListItemLayout();
- CGUIListItemLayout(const CGUIListItemLayout& from);
- CGUIListItemLayout(const CGUIListItemLayout &from, CGUIControl *control);
+ explicit CGUIListItemLayout(const CGUIListItemLayout& from);
+ explicit CGUIListItemLayout(const CGUIListItemLayout& from, CGUIControl* control);
void LoadLayout(TiXmlElement *layout, int context, bool focused, float maxWidth, float maxHeight);
void Process(CGUIListItem *item, int parentID, unsigned int currentTime, CDirtyRegionList &dirtyregions);
void Render(CGUIListItem *item, int parentID);
@@ -51,7 +51,6 @@ public:
bool CheckCondition();
protected:
void LoadControl(TiXmlElement *child, CGUIControlGroup *group);
- void Update(CFileItem *item);
CGUIListGroup m_group;
diff --git a/xbmc/guilib/GUIStaticItem.cpp b/xbmc/guilib/GUIStaticItem.cpp
index f251c0bb5c..f7105671eb 100644
--- a/xbmc/guilib/GUIStaticItem.cpp
+++ b/xbmc/guilib/GUIStaticItem.cpp
@@ -64,6 +64,15 @@ CGUIStaticItem::CGUIStaticItem(const CFileItem &item)
m_visState = false;
}
+CGUIStaticItem::CGUIStaticItem(const CGUIStaticItem& other)
+ : CFileItem(other),
+ m_info(other.m_info),
+ m_visCondition(other.m_visCondition),
+ m_visState(other.m_visState),
+ m_clickActions(other.m_clickActions)
+{
+}
+
void CGUIStaticItem::UpdateProperties(int contextWindow)
{
for (const auto& i : m_info)
diff --git a/xbmc/guilib/GUIStaticItem.h b/xbmc/guilib/GUIStaticItem.h
index 4d4ff8cb44..a68f7394e5 100644
--- a/xbmc/guilib/GUIStaticItem.h
+++ b/xbmc/guilib/GUIStaticItem.h
@@ -51,6 +51,7 @@ public:
*/
CGUIStaticItem(const TiXmlElement *element, int contextWindow);
explicit CGUIStaticItem(const CFileItem &item); // for python
+ explicit CGUIStaticItem(const CGUIStaticItem& other);
~CGUIStaticItem() override = default;
CGUIListItem* Clone() const override { return new CGUIStaticItem(*this); }
diff --git a/xbmc/guilib/guiinfo/AddonsGUIInfo.cpp b/xbmc/guilib/guiinfo/AddonsGUIInfo.cpp
index 999d746cd8..174b0c1e6a 100644
--- a/xbmc/guilib/guiinfo/AddonsGUIInfo.cpp
+++ b/xbmc/guilib/guiinfo/AddonsGUIInfo.cpp
@@ -155,7 +155,7 @@ bool CAddonsGUIInfo::GetLabel(std::string& value, const CFileItem *item, int con
if (!info.GetData3().empty())
{
bool success = CServiceBroker::GetAddonMgr().GetAddon(
- info.GetData3(), addon, ADDON::ADDON_UNKNOWN, ADDON::OnlyEnabled::YES);
+ info.GetData3(), addon, ADDON::ADDON_UNKNOWN, ADDON::OnlyEnabled::CHOICE_YES);
if (!success || !addon)
break;
@@ -205,7 +205,7 @@ bool CAddonsGUIInfo::GetBool(bool& value, const CGUIListItem *gitem, int context
value = false;
ADDON::AddonPtr addon;
if (CServiceBroker::GetAddonMgr().GetAddon(info.GetData3(), addon, ADDON::ADDON_UNKNOWN,
- ADDON::OnlyEnabled::YES))
+ ADDON::OnlyEnabled::CHOICE_YES))
value = !CServiceBroker::GetAddonMgr().IsAddonDisabled(info.GetData3());
return true;
}
diff --git a/xbmc/guilib/guiinfo/VisualisationGUIInfo.cpp b/xbmc/guilib/guiinfo/VisualisationGUIInfo.cpp
index 8400ad9860..2fe972255d 100644
--- a/xbmc/guilib/guiinfo/VisualisationGUIInfo.cpp
+++ b/xbmc/guilib/guiinfo/VisualisationGUIInfo.cpp
@@ -55,7 +55,7 @@ bool CVisualisationGUIInfo::GetLabel(std::string& value, const CFileItem *item,
ADDON::AddonPtr addon;
value = CServiceBroker::GetSettingsComponent()->GetSettings()->GetString(CSettings::SETTING_MUSICPLAYER_VISUALISATION);
if (CServiceBroker::GetAddonMgr().GetAddon(value, addon, ADDON::ADDON_UNKNOWN,
- ADDON::OnlyEnabled::YES) &&
+ ADDON::OnlyEnabled::CHOICE_YES) &&
addon)
{
value = addon->Name();
diff --git a/xbmc/input/joysticks/dialogs/GUIDialogNewJoystick.cpp b/xbmc/input/joysticks/dialogs/GUIDialogNewJoystick.cpp
index 8ac8adee11..b66ce89af4 100644
--- a/xbmc/input/joysticks/dialogs/GUIDialogNewJoystick.cpp
+++ b/xbmc/input/joysticks/dialogs/GUIDialogNewJoystick.cpp
@@ -47,7 +47,7 @@ void CGUIDialogNewJoystick::Process()
// "New controller detected"
// "A new controller has been detected. Configuration can be done at any time in "Settings ->
// System Settings -> Input". Would you like to configure it now?"
- if (ShowYesNoDialogText(CVariant{35011}, CVariant{35012}) == DialogResponse::YES)
+ if (ShowYesNoDialogText(CVariant{35011}, CVariant{35012}) == DialogResponse::CHOICE_YES)
{
CServiceBroker::GetGUI()->GetWindowManager().ActivateWindow(WINDOW_DIALOG_GAME_CONTROLLERS);
}
diff --git a/xbmc/interfaces/builtins/AddonBuiltins.cpp b/xbmc/interfaces/builtins/AddonBuiltins.cpp
index 177a5aa4dd..aba6a748d1 100644
--- a/xbmc/interfaces/builtins/AddonBuiltins.cpp
+++ b/xbmc/interfaces/builtins/AddonBuiltins.cpp
@@ -53,7 +53,7 @@ static int InstallAddon(const std::vector<std::string>& params)
const std::string& addonid = params[0];
AddonPtr addon;
- CAddonInstaller::GetInstance().InstallModal(addonid, addon, InstallModalPrompt::PROMPT);
+ CAddonInstaller::GetInstance().InstallModal(addonid, addon, InstallModalPrompt::CHOICE_YES);
return 0;
}
@@ -70,11 +70,12 @@ static int EnableAddon(const std::vector<std::string>& params)
return -1;
AddonPtr addon;
- if (!CServiceBroker::GetAddonMgr().GetAddon(addonid, addon, ADDON_UNKNOWN, OnlyEnabled::NO))
+ if (!CServiceBroker::GetAddonMgr().GetAddon(addonid, addon, ADDON_UNKNOWN,
+ OnlyEnabled::CHOICE_NO))
return -1;
auto response = HELPERS::ShowYesNoDialogLines(CVariant{24076}, CVariant{24135}, CVariant{addon->Name()}, CVariant{24136});
- if (response == DialogResponse::YES)
+ if (response == DialogResponse::CHOICE_YES)
CServiceBroker::GetAddonMgr().EnableAddon(addonid);
return 0;
@@ -117,7 +118,8 @@ static int RunAddon(const std::vector<std::string>& params)
const std::string& addonid = params[0];
AddonPtr addon;
- if (CServiceBroker::GetAddonMgr().GetAddon(addonid, addon, ADDON_PLUGIN, OnlyEnabled::YES))
+ if (CServiceBroker::GetAddonMgr().GetAddon(addonid, addon, ADDON_PLUGIN,
+ OnlyEnabled::CHOICE_YES))
{
PluginPtr plugin = std::dynamic_pointer_cast<CPluginSource>(addon);
std::string urlParameters;
@@ -160,13 +162,13 @@ static int RunAddon(const std::vector<std::string>& params)
CBuiltins::GetInstance().Execute(cmd);
}
else if (CServiceBroker::GetAddonMgr().GetAddon(addonid, addon, ADDON_SCRIPT,
- OnlyEnabled::YES) ||
+ OnlyEnabled::CHOICE_YES) ||
CServiceBroker::GetAddonMgr().GetAddon(addonid, addon, ADDON_SCRIPT_WEATHER,
- OnlyEnabled::YES) ||
+ OnlyEnabled::CHOICE_YES) ||
CServiceBroker::GetAddonMgr().GetAddon(addonid, addon, ADDON_SCRIPT_LYRICS,
- OnlyEnabled::YES) ||
+ OnlyEnabled::CHOICE_YES) ||
CServiceBroker::GetAddonMgr().GetAddon(addonid, addon, ADDON_SCRIPT_LIBRARY,
- OnlyEnabled::YES))
+ OnlyEnabled::CHOICE_YES))
{
// Pass the script name (addonid) and all the parameters
// (params[1] ... params[x]) separated by a comma to RunScript
@@ -174,7 +176,7 @@ static int RunAddon(const std::vector<std::string>& params)
StringUtils::Format("RunScript({})", StringUtils::Join(params, ",")));
}
else if (CServiceBroker::GetAddonMgr().GetAddon(addonid, addon, ADDON_GAMEDLL,
- OnlyEnabled::YES))
+ OnlyEnabled::CHOICE_YES))
{
CFileItem item;
@@ -236,17 +238,18 @@ static int RunScript(const std::vector<std::string>& params)
AddonPtr addon;
std::string scriptpath;
// Test to see if the param is an addon ID
- if (CServiceBroker::GetAddonMgr().GetAddon(params[0], addon, ADDON_UNKNOWN, OnlyEnabled::YES))
+ if (CServiceBroker::GetAddonMgr().GetAddon(params[0], addon, ADDON_UNKNOWN,
+ OnlyEnabled::CHOICE_YES))
{
//Get the correct extension point to run
if (CServiceBroker::GetAddonMgr().GetAddon(params[0], addon, ADDON_SCRIPT,
- OnlyEnabled::YES) ||
+ OnlyEnabled::CHOICE_YES) ||
CServiceBroker::GetAddonMgr().GetAddon(params[0], addon, ADDON_SCRIPT_WEATHER,
- OnlyEnabled::YES) ||
+ OnlyEnabled::CHOICE_YES) ||
CServiceBroker::GetAddonMgr().GetAddon(params[0], addon, ADDON_SCRIPT_LYRICS,
- OnlyEnabled::YES) ||
+ OnlyEnabled::CHOICE_YES) ||
CServiceBroker::GetAddonMgr().GetAddon(params[0], addon, ADDON_SCRIPT_LIBRARY,
- OnlyEnabled::YES))
+ OnlyEnabled::CHOICE_YES))
{
scriptpath = addon->LibPath();
}
@@ -254,7 +257,7 @@ static int RunScript(const std::vector<std::string>& params)
{
// Run a random extension point (old behaviour).
if (CServiceBroker::GetAddonMgr().GetAddon(params[0], addon, ADDON_UNKNOWN,
- OnlyEnabled::YES))
+ OnlyEnabled::CHOICE_YES))
{
scriptpath = addon->LibPath();
CLog::Log(LOGWARNING,
@@ -330,7 +333,8 @@ static int SetDefaultAddon(const std::vector<std::string>& params)
static int AddonSettings(const std::vector<std::string>& params)
{
AddonPtr addon;
- if (CServiceBroker::GetAddonMgr().GetAddon(params[0], addon, ADDON_UNKNOWN, OnlyEnabled::YES))
+ if (CServiceBroker::GetAddonMgr().GetAddon(params[0], addon, ADDON_UNKNOWN,
+ OnlyEnabled::CHOICE_YES))
CGUIDialogAddonSettings::ShowForAddon(addon);
return 0;
@@ -358,7 +362,8 @@ static int StopScript(const std::vector<std::string>& params)
std::string scriptpath(params[0]);
// Test to see if the param is an addon ID
AddonPtr script;
- if (CServiceBroker::GetAddonMgr().GetAddon(params[0], script, ADDON_UNKNOWN, OnlyEnabled::YES))
+ if (CServiceBroker::GetAddonMgr().GetAddon(params[0], script, ADDON_UNKNOWN,
+ OnlyEnabled::CHOICE_YES))
scriptpath = script->LibPath();
CScriptInvocationManager::GetInstance().Stop(scriptpath);
diff --git a/xbmc/interfaces/builtins/LibraryBuiltins.cpp b/xbmc/interfaces/builtins/LibraryBuiltins.cpp
index 75c931440e..7d11ce83d9 100644
--- a/xbmc/interfaces/builtins/LibraryBuiltins.cpp
+++ b/xbmc/interfaces/builtins/LibraryBuiltins.cpp
@@ -135,8 +135,8 @@ static int ExportLibrary(const std::vector<std::string>& params)
else
{
HELPERS::DialogResponse result = HELPERS::ShowYesNoDialogText(CVariant{iHeading}, CVariant{20426}, CVariant{20428}, CVariant{20429});
- cancelled = result == HELPERS::DialogResponse::CANCELLED;
- singleFile = result != HELPERS::DialogResponse::YES;
+ cancelled = result == HELPERS::DialogResponse::CHOICE_CANCELLED;
+ singleFile = result != HELPERS::DialogResponse::CHOICE_YES;
}
if (cancelled)
@@ -149,8 +149,8 @@ static int ExportLibrary(const std::vector<std::string>& params)
else
{
HELPERS::DialogResponse result = HELPERS::ShowYesNoDialogText(CVariant{iHeading}, CVariant{20430});
- cancelled = result == HELPERS::DialogResponse::CANCELLED;
- thumbs = result == HELPERS::DialogResponse::YES;
+ cancelled = result == HELPERS::DialogResponse::CHOICE_CANCELLED;
+ thumbs = result == HELPERS::DialogResponse::CHOICE_YES;
}
}
@@ -164,7 +164,7 @@ static int ExportLibrary(const std::vector<std::string>& params)
if (movieSetsInfoPath.empty())
{
auto result = HELPERS::ShowYesNoDialogText(CVariant{iHeading}, CVariant{36301});
- cancelled = result != HELPERS::DialogResponse::YES;
+ cancelled = result != HELPERS::DialogResponse::CHOICE_YES;
}
}
@@ -178,8 +178,8 @@ static int ExportLibrary(const std::vector<std::string>& params)
else
{
HELPERS::DialogResponse result = HELPERS::ShowYesNoDialogText(CVariant{iHeading}, CVariant{20436});
- cancelled = result == HELPERS::DialogResponse::CANCELLED;
- actorThumbs = result == HELPERS::DialogResponse::YES;
+ cancelled = result == HELPERS::DialogResponse::CHOICE_CANCELLED;
+ actorThumbs = result == HELPERS::DialogResponse::CHOICE_YES;
}
}
@@ -193,8 +193,8 @@ static int ExportLibrary(const std::vector<std::string>& params)
else
{
HELPERS::DialogResponse result = HELPERS::ShowYesNoDialogText(CVariant{iHeading}, CVariant{20431});
- cancelled = result == HELPERS::DialogResponse::CANCELLED;
- overwrite = result == HELPERS::DialogResponse::YES;
+ cancelled = result == HELPERS::DialogResponse::CHOICE_CANCELLED;
+ overwrite = result == HELPERS::DialogResponse::CHOICE_YES;
}
}
diff --git a/xbmc/interfaces/json-rpc/AddonsOperations.cpp b/xbmc/interfaces/json-rpc/AddonsOperations.cpp
index e08ba34d63..0cb5cff6e3 100644
--- a/xbmc/interfaces/json-rpc/AddonsOperations.cpp
+++ b/xbmc/interfaces/json-rpc/AddonsOperations.cpp
@@ -131,7 +131,8 @@ JSONRPC_STATUS CAddonsOperations::GetAddonDetails(const std::string &method, ITr
{
std::string id = parameterObject["addonid"].asString();
AddonPtr addon;
- if (!CServiceBroker::GetAddonMgr().GetAddon(id, addon, ADDON::ADDON_UNKNOWN, OnlyEnabled::NO) ||
+ if (!CServiceBroker::GetAddonMgr().GetAddon(id, addon, ADDON::ADDON_UNKNOWN,
+ OnlyEnabled::CHOICE_NO) ||
addon.get() == NULL || addon->Type() <= ADDON_UNKNOWN || addon->Type() >= ADDON_MAX)
return InvalidParams;
@@ -145,7 +146,8 @@ JSONRPC_STATUS CAddonsOperations::SetAddonEnabled(const std::string &method, ITr
{
std::string id = parameterObject["addonid"].asString();
AddonPtr addon;
- if (!CServiceBroker::GetAddonMgr().GetAddon(id, addon, ADDON::ADDON_UNKNOWN, OnlyEnabled::NO) ||
+ if (!CServiceBroker::GetAddonMgr().GetAddon(id, addon, ADDON::ADDON_UNKNOWN,
+ OnlyEnabled::CHOICE_NO) ||
addon == nullptr || addon->Type() <= ADDON_UNKNOWN || addon->Type() >= ADDON_MAX)
return InvalidParams;
@@ -175,7 +177,7 @@ JSONRPC_STATUS CAddonsOperations::ExecuteAddon(const std::string &method, ITrans
{
std::string id = parameterObject["addonid"].asString();
AddonPtr addon;
- if (!CServiceBroker::GetAddonMgr().GetAddon(id, addon, ADDON_UNKNOWN, OnlyEnabled::YES) ||
+ if (!CServiceBroker::GetAddonMgr().GetAddon(id, addon, ADDON_UNKNOWN, OnlyEnabled::CHOICE_YES) ||
addon.get() == NULL || addon->Type() < ADDON_VIZ || addon->Type() >= ADDON_MAX)
return InvalidParams;
diff --git a/xbmc/interfaces/json-rpc/GUIOperations.cpp b/xbmc/interfaces/json-rpc/GUIOperations.cpp
index 407489323d..e873c92e3a 100644
--- a/xbmc/interfaces/json-rpc/GUIOperations.cpp
+++ b/xbmc/interfaces/json-rpc/GUIOperations.cpp
@@ -136,7 +136,7 @@ JSONRPC_STATUS CGUIOperations::GetPropertyValue(const std::string &property, CVa
{
std::string skinId = CServiceBroker::GetSettingsComponent()->GetSettings()->GetString(CSettings::SETTING_LOOKANDFEEL_SKIN);
AddonPtr addon;
- if (!CServiceBroker::GetAddonMgr().GetAddon(skinId, addon, ADDON_SKIN, OnlyEnabled::YES))
+ if (!CServiceBroker::GetAddonMgr().GetAddon(skinId, addon, ADDON_SKIN, OnlyEnabled::CHOICE_YES))
return InternalError;
result["id"] = skinId;
diff --git a/xbmc/interfaces/legacy/Addon.cpp b/xbmc/interfaces/legacy/Addon.cpp
index 71b9712eb4..bf39d4cbee 100644
--- a/xbmc/interfaces/legacy/Addon.cpp
+++ b/xbmc/interfaces/legacy/Addon.cpp
@@ -64,7 +64,7 @@ namespace XBMCAddon
"wasn't executed in a normal Kodi manner.");
if (!CServiceBroker::GetAddonMgr().GetAddon(id.c_str(), pAddon, ADDON_UNKNOWN,
- OnlyEnabled::YES))
+ OnlyEnabled::CHOICE_YES))
throw AddonException("Unknown addon id '%s'.", id.c_str());
CServiceBroker::GetAddonMgr().AddToUpdateableAddons(pAddon);
diff --git a/xbmc/interfaces/legacy/Control.cpp b/xbmc/interfaces/legacy/Control.cpp
index 1e87083802..a6f336b384 100644
--- a/xbmc/interfaces/legacy/Control.cpp
+++ b/xbmc/interfaces/legacy/Control.cpp
@@ -1406,8 +1406,8 @@ namespace XBMCAddon
}
// set static list
- IListProvider *provider = new CStaticListProvider(items);
- static_cast<CGUIBaseContainer*>(pGUIControl)->SetListProvider(provider);
+ std::unique_ptr<IListProvider> provider = std::make_unique<CStaticListProvider>(items);
+ static_cast<CGUIBaseContainer*>(pGUIControl)->SetListProvider(std::move(provider));
}
// ============================================================
diff --git a/xbmc/interfaces/legacy/Settings.h b/xbmc/interfaces/legacy/Settings.h
index e4a583a269..8b8bb0eeb0 100644
--- a/xbmc/interfaces/legacy/Settings.h
+++ b/xbmc/interfaces/legacy/Settings.h
@@ -45,7 +45,7 @@ XBMCCOMMONS_STANDARD_EXCEPTION(SettingCallbacksNotSupportedException);
/// **Example:**
/// ~~~~~~~~~~~~~{.py}
/// ...
-/// settings = xbmc.Addon('id').getSettings()
+/// settings = xbmcaddon.Addon('id').getSettings()
/// ...
/// ~~~~~~~~~~~~~
//
diff --git a/xbmc/interfaces/python/PythonInvoker.cpp b/xbmc/interfaces/python/PythonInvoker.cpp
index 93b26c0154..f04ce32c37 100644
--- a/xbmc/interfaces/python/PythonInvoker.cpp
+++ b/xbmc/interfaces/python/PythonInvoker.cpp
@@ -724,7 +724,7 @@ void CPythonInvoker::getAddonModuleDeps(const ADDON::AddonPtr& addon, std::set<s
//Check if dependency is a module addon
ADDON::AddonPtr dependency;
if (CServiceBroker::GetAddonMgr().GetAddon(it.id, dependency, ADDON::ADDON_SCRIPT_MODULE,
- ADDON::OnlyEnabled::YES))
+ ADDON::OnlyEnabled::CHOICE_YES))
{
std::string path = CSpecialProtocol::TranslatePath(dependency->LibPath());
if (paths.find(path) == paths.end())
diff --git a/xbmc/listproviders/DirectoryProvider.cpp b/xbmc/listproviders/DirectoryProvider.cpp
index 2c7eef275a..0b20a9dcf9 100644
--- a/xbmc/listproviders/DirectoryProvider.cpp
+++ b/xbmc/listproviders/DirectoryProvider.cpp
@@ -180,11 +180,33 @@ CDirectoryProvider::CDirectoryProvider(const TiXmlElement *element, int parentID
}
}
+CDirectoryProvider::CDirectoryProvider(const CDirectoryProvider& other)
+ : IListProvider(other.m_parentID),
+ m_updateState(INVALIDATED),
+ m_isAnnounced(false),
+ m_jobID(0),
+ m_url(other.m_url),
+ m_target(other.m_target),
+ m_sortMethod(other.m_sortMethod),
+ m_sortOrder(other.m_sortOrder),
+ m_limit(other.m_limit),
+ m_currentUrl(other.m_currentUrl),
+ m_currentTarget(other.m_currentTarget),
+ m_currentSort(other.m_currentSort),
+ m_currentLimit(other.m_currentLimit)
+{
+}
+
CDirectoryProvider::~CDirectoryProvider()
{
Reset();
}
+std::unique_ptr<IListProvider> CDirectoryProvider::Clone()
+{
+ return std::make_unique<CDirectoryProvider>(*this);
+}
+
bool CDirectoryProvider::Update(bool forceRefresh)
{
// we never need to force refresh here
diff --git a/xbmc/listproviders/DirectoryProvider.h b/xbmc/listproviders/DirectoryProvider.h
index 42a03c7930..6906bd4986 100644
--- a/xbmc/listproviders/DirectoryProvider.h
+++ b/xbmc/listproviders/DirectoryProvider.h
@@ -51,8 +51,11 @@ public:
} UpdateState;
CDirectoryProvider(const TiXmlElement *element, int parentID);
+ explicit CDirectoryProvider(const CDirectoryProvider& other);
~CDirectoryProvider() override;
+ // Implementation of IListProvider
+ std::unique_ptr<IListProvider> Clone() override;
bool Update(bool forceRefresh) override;
void Announce(ANNOUNCEMENT::AnnouncementFlag flag,
const std::string& sender,
diff --git a/xbmc/listproviders/IListProvider.cpp b/xbmc/listproviders/IListProvider.cpp
index 09148c0a60..3979319ba7 100644
--- a/xbmc/listproviders/IListProvider.cpp
+++ b/xbmc/listproviders/IListProvider.cpp
@@ -13,28 +13,28 @@
#include "StaticProvider.h"
#include "utils/XBMCTinyXML.h"
-IListProvider *IListProvider::Create(const TiXmlNode *node, int parentID)
+std::unique_ptr<IListProvider> IListProvider::Create(const TiXmlNode* node, int parentID)
{
const TiXmlNode *root = node->FirstChild("content");
if (root)
{
const TiXmlNode *next = root->NextSibling("content");
if (next)
- return new CMultiProvider(root, parentID);
+ return std::make_unique<CMultiProvider>(root, parentID);
return CreateSingle(root, parentID);
}
- return NULL;
+ return std::unique_ptr<IListProvider>{};
}
-IListProvider *IListProvider::CreateSingle(const TiXmlNode *content, int parentID)
+std::unique_ptr<IListProvider> IListProvider::CreateSingle(const TiXmlNode* content, int parentID)
{
const TiXmlElement *item = content->FirstChildElement("item");
if (item)
- return new CStaticListProvider(content->ToElement(), parentID);
+ return std::make_unique<CStaticListProvider>(content->ToElement(), parentID);
if (!content->NoChildren())
- return new CDirectoryProvider(content->ToElement(), parentID);
+ return std::make_unique<CDirectoryProvider>(content->ToElement(), parentID);
- return NULL;
+ return std::unique_ptr<IListProvider>{};
}
diff --git a/xbmc/listproviders/IListProvider.h b/xbmc/listproviders/IListProvider.h
index f92d99c534..501b399c1f 100644
--- a/xbmc/listproviders/IListProvider.h
+++ b/xbmc/listproviders/IListProvider.h
@@ -23,21 +23,26 @@ class IListProvider
{
public:
explicit IListProvider(int parentID) : m_parentID(parentID) {}
+ explicit IListProvider(const IListProvider& other) = default;
virtual ~IListProvider() = default;
/*! \brief Factory to create list providers.
\param parent a parent TiXmlNode for the container.
\param parentID id of parent window for context.
- \return the list provider, NULL if none.
+ \return the list provider, empty pointer if none.
*/
- static IListProvider *Create(const TiXmlNode *parent, int parentID);
+ static std::unique_ptr<IListProvider> Create(const TiXmlNode* parent, int parentID);
/*! \brief Factory to create list providers. Cannot create a multi-provider.
\param content the TiXmlNode for the content to create.
\param parentID id of parent window for context.
- \return the list provider, NULL if none.
+ \return the list provider, empty pointer if none.
*/
- static IListProvider *CreateSingle(const TiXmlNode *content, int parentID);
+ static std::unique_ptr<IListProvider> CreateSingle(const TiXmlNode* content, int parentID);
+
+ /*! \brief Create an instance of the derived class. Allows for polymorphic copies.
+ */
+ virtual std::unique_ptr<IListProvider> Clone() = 0;
/*! \brief Update the list content
\return true if the content has changed, false otherwise.
diff --git a/xbmc/listproviders/MultiProvider.cpp b/xbmc/listproviders/MultiProvider.cpp
index be5fde4457..6791cf4a79 100644
--- a/xbmc/listproviders/MultiProvider.cpp
+++ b/xbmc/listproviders/MultiProvider.cpp
@@ -18,10 +18,25 @@ CMultiProvider::CMultiProvider(const TiXmlNode *first, int parentID)
{
IListProviderPtr sub(IListProvider::CreateSingle(content, parentID));
if (sub)
- m_providers.push_back(sub);
+ m_providers.push_back(std::move(sub));
}
}
+CMultiProvider::CMultiProvider(const CMultiProvider& other) : IListProvider(other.m_parentID)
+{
+ for (const auto& provider : other.m_providers)
+ {
+ std::unique_ptr<IListProvider> newProvider = provider->Clone();
+ if (newProvider)
+ m_providers.emplace_back(std::move(newProvider));
+ }
+}
+
+std::unique_ptr<IListProvider> CMultiProvider::Clone()
+{
+ return std::make_unique<CMultiProvider>(*this);
+}
+
bool CMultiProvider::Update(bool forceRefresh)
{
bool result = false;
@@ -42,7 +57,7 @@ void CMultiProvider::Fetch(std::vector<CGUIListItemPtr> &items)
for (auto& item : subItems)
{
auto key = GetItemKey(item);
- m_itemMap[key] = provider;
+ m_itemMap[key] = provider.get();
items.push_back(item);
}
subItems.clear();
diff --git a/xbmc/listproviders/MultiProvider.h b/xbmc/listproviders/MultiProvider.h
index 01664ecb9a..9eeddc012d 100644
--- a/xbmc/listproviders/MultiProvider.h
+++ b/xbmc/listproviders/MultiProvider.h
@@ -14,7 +14,7 @@
#include <map>
#include <vector>
-typedef std::shared_ptr<IListProvider> IListProviderPtr;
+typedef std::unique_ptr<IListProvider> IListProviderPtr;
/*!
\ingroup listproviders
@@ -24,7 +24,10 @@ class CMultiProvider : public IListProvider
{
public:
CMultiProvider(const TiXmlNode *first, int parentID);
+ explicit CMultiProvider(const CMultiProvider& other);
+ // Implementation of IListProvider
+ std::unique_ptr<IListProvider> Clone() override;
bool Update(bool forceRefresh) override;
void Fetch(std::vector<CGUIListItemPtr> &items) override;
bool IsUpdating() const override;
@@ -37,6 +40,6 @@ protected:
typedef size_t item_key_type;
static item_key_type GetItemKey(CGUIListItemPtr const &item);
std::vector<IListProviderPtr> m_providers;
- std::map<item_key_type, IListProviderPtr> m_itemMap;
+ std::map<item_key_type, IListProvider*> m_itemMap;
CCriticalSection m_section; // protects m_itemMap
};
diff --git a/xbmc/listproviders/StaticProvider.cpp b/xbmc/listproviders/StaticProvider.cpp
index 7f339b30c1..85c9d5b0e4 100644
--- a/xbmc/listproviders/StaticProvider.cpp
+++ b/xbmc/listproviders/StaticProvider.cpp
@@ -47,8 +47,33 @@ CStaticListProvider::CStaticListProvider(const std::vector<CGUIStaticItemPtr> &i
{
}
+CStaticListProvider::CStaticListProvider(const CStaticListProvider& other)
+ : IListProvider(other.m_parentID),
+ m_defaultItem(other.m_defaultItem),
+ m_defaultAlways(other.m_defaultAlways),
+ m_updateTime(other.m_updateTime)
+{
+ for (const auto& item : other.m_items)
+ {
+ std::shared_ptr<CGUIListItem> control(item->Clone());
+ if (!control)
+ continue;
+
+ std::shared_ptr<CGUIStaticItem> newItem = std::dynamic_pointer_cast<CGUIStaticItem>(control);
+ if (!newItem)
+ continue;
+
+ m_items.emplace_back(std::move(newItem));
+ }
+}
+
CStaticListProvider::~CStaticListProvider() = default;
+std::unique_ptr<IListProvider> CStaticListProvider::Clone()
+{
+ return std::make_unique<CStaticListProvider>(*this);
+}
+
bool CStaticListProvider::Update(bool forceRefresh)
{
bool changed = forceRefresh;
diff --git a/xbmc/listproviders/StaticProvider.h b/xbmc/listproviders/StaticProvider.h
index 4a62e26574..6aea6b1e58 100644
--- a/xbmc/listproviders/StaticProvider.h
+++ b/xbmc/listproviders/StaticProvider.h
@@ -18,8 +18,11 @@ class CStaticListProvider : public IListProvider
public:
CStaticListProvider(const TiXmlElement *element, int parentID);
explicit CStaticListProvider(const std::vector<CGUIStaticItemPtr> &items); // for python
+ explicit CStaticListProvider(const CStaticListProvider& other);
~CStaticListProvider() override;
+ // Implementation of IListProvider
+ std::unique_ptr<IListProvider> Clone() override;
bool Update(bool forceRefresh) override;
void Fetch(std::vector<CGUIListItemPtr> &items) override;
bool OnClick(const CGUIListItemPtr &item) override;
diff --git a/xbmc/messaging/helpers/DialogHelper.cpp b/xbmc/messaging/helpers/DialogHelper.cpp
index 2c042f5acb..0990108ba9 100644
--- a/xbmc/messaging/helpers/DialogHelper.cpp
+++ b/xbmc/messaging/helpers/DialogHelper.cpp
@@ -38,20 +38,20 @@ DialogResponse ShowYesNoCustomDialog(CVariant heading, CVariant text, CVariant n
switch (CApplicationMessenger::GetInstance().SendMsg(TMSG_GUI_DIALOG_YESNO, -1, -1, static_cast<void*>(&options)))
{
case -1:
- return DialogResponse::CANCELLED;
+ return DialogResponse::CHOICE_CANCELLED;
case 0:
- return DialogResponse::NO;
+ return DialogResponse::CHOICE_NO;
case 1:
- return DialogResponse::YES;
+ return DialogResponse::CHOICE_YES;
case 2:
- return DialogResponse::CUSTOM;
+ return DialogResponse::CHOICE_CUSTOM;
default:
//If we get here someone changed the return values without updating this code
assert(false);
}
//This is unreachable code but we need to return something to suppress warnings about
//no return
- return DialogResponse::CANCELLED;
+ return DialogResponse::CHOICE_CANCELLED;
}
DialogResponse ShowYesNoDialogLines(CVariant heading, CVariant line0, CVariant line1, CVariant line2,
@@ -70,20 +70,20 @@ DialogResponse ShowYesNoDialogLines(CVariant heading, CVariant line0, CVariant l
switch (CApplicationMessenger::GetInstance().SendMsg(TMSG_GUI_DIALOG_YESNO, -1, -1, static_cast<void*>(&options)))
{
case -1:
- return DialogResponse::CANCELLED;
+ return DialogResponse::CHOICE_CANCELLED;
case 0:
- return DialogResponse::NO;
+ return DialogResponse::CHOICE_NO;
case 1:
- return DialogResponse::YES;
+ return DialogResponse::CHOICE_YES;
case 2:
- return DialogResponse::CUSTOM;
+ return DialogResponse::CHOICE_CUSTOM;
default:
//If we get here someone changed the return values without updating this code
assert(false);
}
//This is unreachable code but we need to return something to suppress warnings about
//no return
- return DialogResponse::CANCELLED;
+ return DialogResponse::CHOICE_CANCELLED;
}
}
diff --git a/xbmc/messaging/helpers/DialogHelper.h b/xbmc/messaging/helpers/DialogHelper.h
index cf3d982502..d36fad3325 100644
--- a/xbmc/messaging/helpers/DialogHelper.h
+++ b/xbmc/messaging/helpers/DialogHelper.h
@@ -20,12 +20,12 @@ namespace MESSAGING
namespace HELPERS
{
-enum class DialogResponse
+enum class DialogResponse : int
{
- CANCELLED,
- YES,
- NO,
- CUSTOM
+ CHOICE_CANCELLED,
+ CHOICE_YES,
+ CHOICE_NO,
+ CHOICE_CUSTOM,
};
/*! \struct DialogYesNoMessage DialogHelper.h "messaging/helpers/DialogHelper.h"
diff --git a/xbmc/music/MusicDatabase.cpp b/xbmc/music/MusicDatabase.cpp
index c93ae58865..f175a2627e 100644
--- a/xbmc/music/MusicDatabase.cpp
+++ b/xbmc/music/MusicDatabase.cpp
@@ -4810,7 +4810,7 @@ void CMusicDatabase::Clean()
return;
}
- if (HELPERS::ShowYesNoDialogText(CVariant{313}, CVariant{333}) == DialogResponse::YES)
+ if (HELPERS::ShowYesNoDialogText(CVariant{313}, CVariant{333}) == DialogResponse::CHOICE_YES)
{
CMusicDatabase musicdatabase;
if (musicdatabase.Open())
@@ -11594,7 +11594,7 @@ bool CMusicDatabase::GetScraper(int id, const CONTENT_TYPE& content, ADDON::Scra
ADDON::AddonPtr addon;
if (!scraperUUID.empty() &&
CServiceBroker::GetAddonMgr().GetAddon(scraperUUID, addon, ADDON::ADDON_UNKNOWN,
- ADDON::OnlyEnabled::YES) &&
+ ADDON::OnlyEnabled::CHOICE_YES) &&
addon)
{
scraper = std::dynamic_pointer_cast<ADDON::CScraper>(addon);
diff --git a/xbmc/music/dialogs/GUIDialogInfoProviderSettings.cpp b/xbmc/music/dialogs/GUIDialogInfoProviderSettings.cpp
index 39b6203063..92245254a9 100644
--- a/xbmc/music/dialogs/GUIDialogInfoProviderSettings.cpp
+++ b/xbmc/music/dialogs/GUIDialogInfoProviderSettings.cpp
@@ -180,7 +180,7 @@ void CGUIDialogInfoProviderSettings::OnSettingAction(const std::shared_ptr<const
{
AddonPtr scraperAddon;
if (CServiceBroker::GetAddonMgr().GetAddon(selectedAddonId, scraperAddon, ADDON_UNKNOWN,
- OnlyEnabled::YES))
+ OnlyEnabled::CHOICE_YES))
{
m_albumscraper = std::dynamic_pointer_cast<CScraper>(scraperAddon);
SetupView();
@@ -205,7 +205,7 @@ void CGUIDialogInfoProviderSettings::OnSettingAction(const std::shared_ptr<const
{
AddonPtr scraperAddon;
if (CServiceBroker::GetAddonMgr().GetAddon(selectedAddonId, scraperAddon, ADDON_UNKNOWN,
- OnlyEnabled::YES))
+ OnlyEnabled::CHOICE_YES))
{
m_artistscraper = std::dynamic_pointer_cast<CScraper>(scraperAddon);
SetupView();
diff --git a/xbmc/music/windows/GUIWindowMusicBase.cpp b/xbmc/music/windows/GUIWindowMusicBase.cpp
index cb40f476ba..e11613ed8b 100644
--- a/xbmc/music/windows/GUIWindowMusicBase.cpp
+++ b/xbmc/music/windows/GUIWindowMusicBase.cpp
@@ -1233,15 +1233,15 @@ void CGUIWindowMusicBase::OnAssignContent(const std::string& oldName, const CMed
// "Add to library" yes/no dialog with additional "settings" custom button
// "Do you want to add the media from this source to your library?"
- DialogResponse rep = DialogResponse::CUSTOM;
- while (rep == DialogResponse::CUSTOM)
+ DialogResponse rep = DialogResponse::CHOICE_CUSTOM;
+ while (rep == DialogResponse::CHOICE_CUSTOM)
{
rep = HELPERS::ShowYesNoCustomDialog(CVariant{20444}, CVariant{20447}, CVariant{106}, CVariant{107}, CVariant{10004});
- if (rep == DialogResponse::CUSTOM)
+ if (rep == DialogResponse::CHOICE_CUSTOM)
// Edit default info provider settings so can be applied during scan
CGUIDialogInfoProviderSettings::Show();
}
- if (rep == DialogResponse::YES)
+ if (rep == DialogResponse::CHOICE_YES)
CMusicLibraryQueue::GetInstance().ScanLibrary(source.strPath,
MUSIC_INFO::CMusicInfoScanner::SCAN_NORMAL, true);
}
diff --git a/xbmc/network/NetworkServices.cpp b/xbmc/network/NetworkServices.cpp
index 86df207a55..03c9181b87 100644
--- a/xbmc/network/NetworkServices.cpp
+++ b/xbmc/network/NetworkServices.cpp
@@ -189,7 +189,7 @@ bool CNetworkServices::OnSettingChanging(const std::shared_ptr<const CSetting>&
(!m_settings->GetBool(CSettings::SETTING_SERVICES_WEBSERVER) ||
(m_settings->GetBool(CSettings::SETTING_SERVICES_WEBSERVER) &&
!m_settings->GetString(CSettings::SETTING_SERVICES_WEBSERVERPASSWORD).empty())) &&
- HELPERS::ShowYesNoDialogText(19098, 36634) != DialogResponse::YES)
+ HELPERS::ShowYesNoDialogText(19098, 36634) != DialogResponse::CHOICE_YES)
{
// Leave it as-is
return false;
@@ -227,7 +227,7 @@ bool CNetworkServices::OnSettingChanging(const std::shared_ptr<const CSetting>&
// Ask for confirmation when enabling the web server
if (settingId == CSettings::SETTING_SERVICES_WEBSERVER &&
- HELPERS::ShowYesNoDialogText(19098, 36632) != DialogResponse::YES)
+ HELPERS::ShowYesNoDialogText(19098, 36632) != DialogResponse::CHOICE_YES)
{
// Revert change, do not start server
return false;
@@ -438,7 +438,7 @@ bool CNetworkServices::OnSettingChanging(const std::shared_ptr<const CSetting>&
else if (settingId == CSettings::SETTING_SERVICES_ESALLINTERFACES)
{
if (m_settings->GetBool(CSettings::SETTING_SERVICES_ESALLINTERFACES) &&
- HELPERS::ShowYesNoDialogText(19098, 36633) != DialogResponse::YES)
+ HELPERS::ShowYesNoDialogText(19098, 36633) != DialogResponse::CHOICE_YES)
{
// Revert change, do not start server
return false;
@@ -506,7 +506,8 @@ void CNetworkServices::OnSettingChanged(const std::shared_ptr<const CSetting>& s
{
// okey we really don't need to restart, only deinit samba, but that could be damn hard if something is playing
//! @todo - General way of handling setting changes that require restart
- if (HELPERS::ShowYesNoDialogText(CVariant{14038}, CVariant{14039}) == DialogResponse::YES)
+ if (HELPERS::ShowYesNoDialogText(CVariant{14038}, CVariant{14039}) ==
+ DialogResponse::CHOICE_YES)
{
m_settings->Save();
CApplicationMessenger::GetInstance().PostMsg(TMSG_RESTARTAPP);
@@ -940,8 +941,8 @@ bool CNetworkServices::StopEventServer(bool bWait, bool promptuser)
{
if (server->GetNumberOfClients() > 0)
{
- if (HELPERS::ShowYesNoDialogText(CVariant{13140}, CVariant{13141}, CVariant{""}, CVariant{""}, 10000) !=
- DialogResponse::YES)
+ if (HELPERS::ShowYesNoDialogText(CVariant{13140}, CVariant{13141}, CVariant{""}, CVariant{""},
+ 10000) != DialogResponse::CHOICE_YES)
{
CLog::Log(LOGINFO, "ES: Not stopping event server");
return false;
diff --git a/xbmc/network/httprequesthandler/HTTPWebinterfaceHandler.cpp b/xbmc/network/httprequesthandler/HTTPWebinterfaceHandler.cpp
index 8e5f4f692e..48d46035fe 100644
--- a/xbmc/network/httprequesthandler/HTTPWebinterfaceHandler.cpp
+++ b/xbmc/network/httprequesthandler/HTTPWebinterfaceHandler.cpp
@@ -91,7 +91,7 @@ bool CHTTPWebinterfaceHandler::ResolveAddon(const std::string &url, ADDON::Addon
return false;
if (!CServiceBroker::GetAddonMgr().GetAddon(components.at(1), addon, ADDON::ADDON_UNKNOWN,
- ADDON::OnlyEnabled::YES) ||
+ ADDON::OnlyEnabled::CHOICE_YES) ||
addon == NULL)
return false;
diff --git a/xbmc/network/upnp/UPnPPlayer.cpp b/xbmc/network/upnp/UPnPPlayer.cpp
index 47e5b3408d..527754c141 100644
--- a/xbmc/network/upnp/UPnPPlayer.cpp
+++ b/xbmc/network/upnp/UPnPPlayer.cpp
@@ -603,7 +603,8 @@ bool CUPnPPlayer::OnAction(const CAction &action)
if(IsPlaying())
{
//stop on remote system
- m_stopremote = HELPERS::ShowYesNoDialogText(CVariant{37022}, CVariant{37023}) == DialogResponse::YES;
+ m_stopremote = HELPERS::ShowYesNoDialogText(CVariant{37022}, CVariant{37023}) ==
+ DialogResponse::CHOICE_YES;
return false; /* let normal code handle the action */
}
diff --git a/xbmc/peripherals/Peripherals.cpp b/xbmc/peripherals/Peripherals.cpp
index 5efe10283b..759cda91cf 100644
--- a/xbmc/peripherals/Peripherals.cpp
+++ b/xbmc/peripherals/Peripherals.cpp
@@ -975,7 +975,7 @@ void CPeripherals::OnSettingAction(const std::shared_ptr<const CSetting>& settin
{
ADDON::AddonPtr addon;
if (CServiceBroker::GetAddonMgr().GetAddon(strAddonId, addon, ADDON::ADDON_UNKNOWN,
- ADDON::OnlyEnabled::YES))
+ ADDON::OnlyEnabled::CHOICE_YES))
CGUIDialogAddonSettings::ShowForAddon(addon);
}
}
diff --git a/xbmc/peripherals/bus/virtual/PeripheralBusAddon.cpp b/xbmc/peripherals/bus/virtual/PeripheralBusAddon.cpp
index 6307207151..f6e6220973 100644
--- a/xbmc/peripherals/bus/virtual/PeripheralBusAddon.cpp
+++ b/xbmc/peripherals/bus/virtual/PeripheralBusAddon.cpp
@@ -482,7 +482,8 @@ void CPeripheralBusAddon::PromptEnableAddons(const std::vector<ADDON::AddonInfoP
{
// "Unable to configure controllers"
// "Controller configuration depends on a disabled add-on. Would you like to enable it?"
- bAccepted = (ShowYesNoDialogLines(CVariant{35017}, CVariant{35018}) == DialogResponse::YES);
+ bAccepted =
+ (ShowYesNoDialogLines(CVariant{35017}, CVariant{35018}) == DialogResponse::CHOICE_YES);
}
if (bAccepted)
diff --git a/xbmc/platform/android/CPUInfoAndroid.cpp b/xbmc/platform/android/CPUInfoAndroid.cpp
index 3c854e8ae2..cd7ee1ad2c 100644
--- a/xbmc/platform/android/CPUInfoAndroid.cpp
+++ b/xbmc/platform/android/CPUInfoAndroid.cpp
@@ -8,10 +8,14 @@
#include "CPUInfoAndroid.h"
+#include "URL.h"
+#include "utils/StringUtils.h"
#include "utils/Temperature.h"
#include "platform/android/activity/AndroidFeatures.h"
+#include <array>
+
std::shared_ptr<CCPUInfo> CCPUInfo::GetCPUInfo()
{
return std::make_shared<CCPUInfoAndroid>();
@@ -19,6 +23,28 @@ std::shared_ptr<CCPUInfo> CCPUInfo::GetCPUInfo()
CCPUInfoAndroid::CCPUInfoAndroid()
{
+ m_posixFile = std::make_unique<CPosixFile>();
+
+ if (m_posixFile && m_posixFile->Open(CURL("/proc/cpuinfo")))
+ {
+ std::array<char, 2048> buffer = {};
+
+ if (0 < m_posixFile->Read(buffer.data(), buffer.size()))
+ {
+ for (const auto& line : StringUtils::Split(buffer.data(), '\n'))
+ {
+ if (line.find("vendor_id") != std::string::npos)
+ m_cpuVendor = line.substr(line.find(':') + 2);
+ else if (line.find("model name") != std::string::npos)
+ m_cpuModel = line.substr(line.find(':') + 2);
+ else if (line.find("BogoMIPS") != std::string::npos)
+ m_cpuBogoMips = line.substr(line.find(':') + 2);
+ }
+ }
+
+ m_posixFile->Close();
+ }
+
m_cpuCount = CAndroidFeatures::GetCPUCount();
for (int i = 0; i < m_cpuCount; i++)
@@ -31,3 +57,23 @@ CCPUInfoAndroid::CCPUInfoAndroid()
if (CAndroidFeatures::HasNeon())
m_cpuFeatures |= CPU_FEATURE_NEON;
}
+
+float CCPUInfoAndroid::GetCPUFrequency()
+{
+ float freq = 0.f;
+
+ if (!m_posixFile)
+ return freq;
+
+ if (m_posixFile->Open(CURL("/sys/devices/system/cpu/cpu0/cpufreq/cpuinfo_max_freq")))
+ {
+ std::array<char, 32> buffer = {};
+
+ if (0 < m_posixFile->Read(buffer.data(), buffer.size()))
+ freq = std::atof(buffer.data()) / 1000;
+
+ m_posixFile->Close();
+ }
+
+ return freq;
+}
diff --git a/xbmc/platform/android/CPUInfoAndroid.h b/xbmc/platform/android/CPUInfoAndroid.h
index c8fdbd1655..edb26e5198 100644
--- a/xbmc/platform/android/CPUInfoAndroid.h
+++ b/xbmc/platform/android/CPUInfoAndroid.h
@@ -11,6 +11,11 @@
#include "utils/Temperature.h"
#include "platform/posix/CPUInfoPosix.h"
+#include "platform/posix/filesystem/PosixFile.h"
+
+#include <memory>
+
+using namespace XFILE;
class CCPUInfoAndroid : public CCPUInfoPosix
{
@@ -20,5 +25,8 @@ public:
bool SupportsCPUUsage() const override { return false; }
int GetUsedPercentage() override { return 0; }
- float GetCPUFrequency() override { return 0; }
+ float GetCPUFrequency() override;
+
+private:
+ std::unique_ptr<CPosixFile> m_posixFile;
};
diff --git a/xbmc/platform/darwin/tvos/XBMCController.mm b/xbmc/platform/darwin/tvos/XBMCController.mm
index 9e9dde4fd2..87d3da2a84 100644
--- a/xbmc/platform/darwin/tvos/XBMCController.mm
+++ b/xbmc/platform/darwin/tvos/XBMCController.mm
@@ -22,7 +22,6 @@
#include "network/NetworkServices.h"
#include "platform/xbmc.h"
#include "powermanagement/PowerManager.h"
-#include "pvr/PVRManager.h"
#include "settings/AdvancedSettings.h"
#include "settings/SettingsComponent.h"
#include "utils/log.h"
diff --git a/xbmc/platform/win32/WIN32Util.cpp b/xbmc/platform/win32/WIN32Util.cpp
index 02cb880a18..d2cf1363c7 100644
--- a/xbmc/platform/win32/WIN32Util.cpp
+++ b/xbmc/platform/win32/WIN32Util.cpp
@@ -15,6 +15,7 @@
#include "WindowHelper.h"
#include "guilib/LocalizeStrings.h"
#include "my_ntddscsi.h"
+#include "rendering/dx/DirectXHelper.h"
#include "storage/MediaManager.h"
#include "storage/cdioSupport.h"
#include "utils/CharsetConverter.h"
@@ -1504,3 +1505,78 @@ void CWIN32Util::PlatformSyslog()
CLog::Log(LOGINFO, "Display HDR capable is detected and Windows HDR switch is {}",
(hdrStatus == HDR_STATUS::HDR_ON) ? "ON" : "OFF");
}
+
+VideoDriverInfo CWIN32Util::GetVideoDriverInfo(const UINT vendorId, const std::wstring& driverDesc)
+{
+ VideoDriverInfo info = {};
+
+#ifdef TARGET_WINDOWS_DESKTOP
+ HKEY hKey = nullptr;
+ const wchar_t* SUBKEY = L"SYSTEM\\CurrentControlSet\\Control\\Video";
+
+ if (ERROR_SUCCESS != RegOpenKeyExW(HKEY_LOCAL_MACHINE, SUBKEY, 0, KEY_ENUMERATE_SUB_KEYS, &hKey))
+ return {};
+
+ LSTATUS sta = ERROR_SUCCESS;
+ wchar_t keyName[128] = {};
+ DWORD index = 0;
+ DWORD len;
+
+ using KODI::PLATFORM::WINDOWS::FromW;
+
+ do
+ {
+ len = sizeof(keyName) / sizeof(wchar_t);
+ sta = RegEnumKeyExW(hKey, index, keyName, &len, nullptr, nullptr, nullptr, nullptr);
+ index++;
+
+ if (sta != ERROR_SUCCESS)
+ continue;
+
+ std::wstring subkey(SUBKEY);
+ subkey.append(L"\\");
+ subkey.append(keyName);
+ subkey.append(L"\\");
+ subkey.append(L"0000");
+ DWORD lg;
+
+ wchar_t desc[128] = {};
+ lg = sizeof(desc) / sizeof(wchar_t);
+ if (ERROR_SUCCESS != RegGetValueW(HKEY_LOCAL_MACHINE, subkey.c_str(), L"DriverDesc",
+ RRF_RT_REG_SZ, nullptr, desc, &lg))
+ continue;
+
+ std::wstring s_desc(desc);
+ if (s_desc != driverDesc)
+ continue;
+
+ // driver of interest found, we read version
+ wchar_t version[64] = {};
+ lg = sizeof(version) / sizeof(wchar_t);
+ if (ERROR_SUCCESS != RegGetValueW(HKEY_LOCAL_MACHINE, subkey.c_str(), L"DriverVersion",
+ RRF_RT_REG_SZ, nullptr, version, &lg))
+ continue;
+
+ info.valid = true;
+ info.version = FromW(std::wstring(version));
+
+ // convert driver store version to Nvidia version
+ if (vendorId == PCIV_NVIDIA)
+ {
+ std::string ver(info.version);
+ StringUtils::Replace(ver, ".", "");
+ info.majorVersion = std::stoi(ver.substr(ver.length() - 5, 3));
+ info.minorVersion = std::stoi(ver.substr(ver.length() - 2, 2));
+ }
+ else // for Intel/AMD fill major version only
+ {
+ info.majorVersion = std::stoi(info.version.substr(0, 2));
+ }
+
+ } while (sta == ERROR_SUCCESS && !info.valid);
+
+ RegCloseKey(hKey);
+#endif
+
+ return info;
+}
diff --git a/xbmc/platform/win32/WIN32Util.h b/xbmc/platform/win32/WIN32Util.h
index e87f9ee343..247bed0a35 100644
--- a/xbmc/platform/win32/WIN32Util.h
+++ b/xbmc/platform/win32/WIN32Util.h
@@ -20,6 +20,14 @@
#define BONJOUR_BROWSER_EVENT ( WM_USER + 0x110 )
#define TRAY_ICON_NOTIFY ( WM_USER + 0x120 )
+struct VideoDriverInfo
+{
+ int majorVersion;
+ int minorVersion;
+ bool valid;
+ std::string version;
+};
+
class CURL; // forward declaration
class CWIN32Util
@@ -74,4 +82,6 @@ public:
static HDR_STATUS GetWindowsHDRStatus();
static void PlatformSyslog();
+
+ static VideoDriverInfo GetVideoDriverInfo(const UINT vendorId, const std::wstring& driverDesc);
};
diff --git a/xbmc/pvr/PVRDatabase.cpp b/xbmc/pvr/PVRDatabase.cpp
index 7cd1703dc3..cfc93cba55 100644
--- a/xbmc/pvr/PVRDatabase.cpp
+++ b/xbmc/pvr/PVRDatabase.cpp
@@ -91,6 +91,25 @@ namespace
")";
// clang-format on
+
+ std::string GetClientIdsSQL(const std::vector<std::shared_ptr<CPVRClient>>& clients)
+ {
+ if (clients.empty())
+ return {};
+
+ std::string clientIds = "(";
+ for (auto it = clients.cbegin(); it != clients.cend(); ++it)
+ {
+ if (it != clients.cbegin())
+ clientIds += " OR ";
+
+ clientIds += "iClientId = ";
+ clientIds += std::to_string((*it)->GetID());
+ }
+ clientIds += ")";
+ return clientIds;
+ }
+
} // unnamed namespace
bool CPVRDatabase::Open()
@@ -406,12 +425,18 @@ bool CPVRDatabase::Delete(const CPVRProvider& provider)
return DeleteValues("providers", filter);
}
-bool CPVRDatabase::Get(CPVRProviders& results)
+bool CPVRDatabase::Get(CPVRProviders& results,
+ const std::vector<std::shared_ptr<CPVRClient>>& clients) const
{
bool bReturn = false;
- CSingleLock lock(m_critSection);
- const std::string strQuery = PrepareSQL("SELECT * from providers");
+ std::string strQuery = "SELECT * from providers ";
+ const std::string clientIds = GetClientIdsSQL(clients);
+ if (!clientIds.empty())
+ strQuery += "WHERE " + clientIds;
+
+ CSingleLock lock(m_critSection);
+ strQuery = PrepareSQL(strQuery);
if (ResultQuery(strQuery))
{
try
@@ -451,12 +476,18 @@ bool CPVRDatabase::Get(CPVRProviders& results)
/********** Channel methods **********/
int CPVRDatabase::Get(bool bRadio,
- std::map<std::pair<int, int>, std::shared_ptr<CPVRChannel>>& results)
+ const std::vector<std::shared_ptr<CPVRClient>>& clients,
+ std::map<std::pair<int, int>, std::shared_ptr<CPVRChannel>>& results) const
{
int iReturn = 0;
- const std::string strQuery = PrepareSQL("SELECT * from channels WHERE bIsRadio = %u", bRadio);
+
+ std::string strQuery = "SELECT * from channels WHERE bIsRadio = %u ";
+ const std::string clientIds = GetClientIdsSQL(clients);
+ if (!clientIds.empty())
+ strQuery += "AND " + clientIds;
CSingleLock lock(m_critSection);
+ strQuery = PrepareSQL(strQuery, bRadio);
if (ResultQuery(strQuery))
{
try
@@ -590,7 +621,7 @@ bool CPVRDatabase::Delete(const CPVRChannelGroup& group)
return RemoveChannelsFromGroup(group) && DeleteValues("channelgroups", filter);
}
-int CPVRDatabase::Get(CPVRChannelGroups& results)
+int CPVRDatabase::Get(CPVRChannelGroups& results) const
{
int iLoaded = 0;
CSingleLock lock(m_critSection);
@@ -635,7 +666,7 @@ int CPVRDatabase::Get(CPVRChannelGroups& results)
}
std::vector<std::shared_ptr<CPVRChannelGroupMember>> CPVRDatabase::Get(
- const CPVRChannelGroup& group)
+ const CPVRChannelGroup& group, const std::vector<std::shared_ptr<CPVRClient>>& clients) const
{
std::vector<std::shared_ptr<CPVRChannelGroupMember>> results;
@@ -646,22 +677,24 @@ std::vector<std::shared_ptr<CPVRChannelGroupMember>> CPVRDatabase::Get(
return results;
}
- const std::string strQuery =
- PrepareSQL("SELECT map_channelgroups_channels.idChannel, "
- "map_channelgroups_channels.iChannelNumber, "
- "map_channelgroups_channels.iSubChannelNumber, "
- "map_channelgroups_channels.iOrder, "
- "map_channelgroups_channels.iClientChannelNumber, "
- "map_channelgroups_channels.iClientSubChannelNumber, "
- "channels.iClientId, channels.iUniqueId, channels.bIsRadio "
- "FROM map_channelgroups_channels "
- "LEFT JOIN channels ON channels.idChannel = map_channelgroups_channels.idChannel "
- "WHERE map_channelgroups_channels.idGroup = %i ORDER BY "
- "map_channelgroups_channels.iChannelNumber",
- group.GroupID());
+ std::string strQuery =
+ "SELECT map_channelgroups_channels.idChannel, "
+ "map_channelgroups_channels.iChannelNumber, "
+ "map_channelgroups_channels.iSubChannelNumber, "
+ "map_channelgroups_channels.iOrder, "
+ "map_channelgroups_channels.iClientChannelNumber, "
+ "map_channelgroups_channels.iClientSubChannelNumber, "
+ "channels.iClientId, channels.iUniqueId, channels.bIsRadio "
+ "FROM map_channelgroups_channels "
+ "LEFT JOIN channels ON channels.idChannel = map_channelgroups_channels.idChannel "
+ "WHERE map_channelgroups_channels.idGroup = %i ";
+ const std::string clientIds = GetClientIdsSQL(clients);
+ if (!clientIds.empty())
+ strQuery += "AND " + clientIds;
+ strQuery += " ORDER BY map_channelgroups_channels.iChannelNumber";
CSingleLock lock(m_critSection);
-
+ strQuery = PrepareSQL(strQuery, group.GroupID());
if (ResultQuery(strQuery))
{
try
@@ -963,12 +996,18 @@ bool CPVRDatabase::UpdateLastOpened(const CPVRChannelGroup& group)
/********** Timer methods **********/
-std::vector<std::shared_ptr<CPVRTimerInfoTag>> CPVRDatabase::GetTimers(CPVRTimers& timers)
+std::vector<std::shared_ptr<CPVRTimerInfoTag>> CPVRDatabase::GetTimers(
+ CPVRTimers& timers, const std::vector<std::shared_ptr<CPVRClient>>& clients) const
{
std::vector<std::shared_ptr<CPVRTimerInfoTag>> result;
+ std::string strQuery = "SELECT * FROM timers ";
+ const std::string clientIds = GetClientIdsSQL(clients);
+ if (!clientIds.empty())
+ strQuery += "WHERE " + clientIds;
+
CSingleLock lock(m_critSection);
- const std::string strQuery = PrepareSQL("SELECT * FROM timers");
+ strQuery = PrepareSQL(strQuery);
if (ResultQuery(strQuery))
{
try
diff --git a/xbmc/pvr/PVRDatabase.h b/xbmc/pvr/PVRDatabase.h
index 853de802be..9359148734 100644
--- a/xbmc/pvr/PVRDatabase.h
+++ b/xbmc/pvr/PVRDatabase.h
@@ -114,10 +114,13 @@ namespace PVR
/*!
* @brief Get channels from the database.
* @param bRadio Whether to fetch radio or TV channels.
+ * @param clients The PVR clients the channels should be loaded for. Leave empty for all clients.
* @param results The container for the channels.
* @return The number of channels loaded.
*/
- int Get(bool bRadio, std::map<std::pair<int, int>, std::shared_ptr<CPVRChannel>>& results);
+ int Get(bool bRadio,
+ const std::vector<std::shared_ptr<CPVRClient>>& clients,
+ std::map<std::pair<int, int>, std::shared_ptr<CPVRChannel>>& results) const;
/*!
* @brief Add or update a channel entry in the database
@@ -175,9 +178,10 @@ namespace PVR
/*!
* @brief Get the list of providers from the database
* @param results The providers to store the results in.
+ * @param clients The PVR clients the providers should be loaded for. Leave empty for all clients.
* @return The amount of providers that were added.
*/
- bool Get(CPVRProviders& results);
+ bool Get(CPVRProviders& results, const std::vector<std::shared_ptr<CPVRClient>>& clients) const;
//@}
@@ -202,14 +206,17 @@ namespace PVR
* @param results The container to store the results in.
* @return The number of groups loaded.
*/
- int Get(CPVRChannelGroups& results);
+ int Get(CPVRChannelGroups& results) const;
/*!
* @brief Get the members of a channel group.
* @param group The group to get the members for.
+ * @param clients The PVR clients the group members should be loaded for. Leave empty for all clients.
* @return The group members.
*/
- std::vector<std::shared_ptr<CPVRChannelGroupMember>> Get(const CPVRChannelGroup& group);
+ std::vector<std::shared_ptr<CPVRChannelGroupMember>> Get(
+ const CPVRChannelGroup& group,
+ const std::vector<std::shared_ptr<CPVRClient>>& clients) const;
/*!
* @brief Add or update a channel group entry in the database.
@@ -230,9 +237,11 @@ namespace PVR
/*!
* @brief Get the timers.
* @param timers The container for the timers.
+ * @param clients The PVR clients the timers should be loaded for. Leave empty for all clients.
* @return The timers.
*/
- std::vector<std::shared_ptr<CPVRTimerInfoTag>> GetTimers(CPVRTimers& timers);
+ std::vector<std::shared_ptr<CPVRTimerInfoTag>> GetTimers(
+ CPVRTimers& timers, const std::vector<std::shared_ptr<CPVRClient>>& clients) const;
/*!
* @brief Add or update a timer entry in the database
@@ -300,6 +309,6 @@ namespace PVR
bool RemoveChannelsFromGroup(const CPVRChannelGroup& group);
- CCriticalSection m_critSection;
+ mutable CCriticalSection m_critSection;
};
}
diff --git a/xbmc/pvr/PVRManager.cpp b/xbmc/pvr/PVRManager.cpp
index 24f083695a..f8ff4ed2d0 100644
--- a/xbmc/pvr/PVRManager.cpp
+++ b/xbmc/pvr/PVRManager.cpp
@@ -390,7 +390,7 @@ void CPVRManager::Start()
return;
CLog::Log(LOGINFO, "PVR Manager: Starting");
- SetState(ManagerStateStarting);
+ SetState(ManagerState::STATE_STARTING);
/* create the pvrmanager thread, which will ensure that all data will be loaded */
Create();
@@ -413,25 +413,9 @@ void CPVRManager::Stop(bool bRestart /* = false */)
}
CLog::Log(LOGINFO, "PVR Manager: Stopping");
- SetState(ManagerStateStopping);
-
- m_addons->Stop();
- m_pendingUpdates->Stop();
- m_timers->Stop();
- m_epgContainer.Stop();
- m_guiInfo->Stop();
+ SetState(ManagerState::STATE_SSTOPPING);
StopThread();
-
- SetState(ManagerStateInterrupted);
-
- UnloadComponents();
- m_database->Close();
-
- ResetProperties();
-
- CLog::Log(LOGINFO, "PVR Manager: Stopped");
- SetState(ManagerStateStopped);
}
void CPVRManager::Unload()
@@ -469,22 +453,22 @@ void CPVRManager::SetState(CPVRManager::ManagerState state)
PVREvent event;
switch (state)
{
- case ManagerStateError:
+ case ManagerState::STATE_ERROR:
event = PVREvent::ManagerError;
break;
- case ManagerStateStopped:
+ case ManagerState::STATE_STOPPED:
event = PVREvent::ManagerStopped;
break;
- case ManagerStateStarting:
+ case ManagerState::STATE_STARTING:
event = PVREvent::ManagerStarting;
break;
- case ManagerStateStopping:
+ case ManagerState::STATE_SSTOPPING:
event = PVREvent::ManagerStopped;
break;
- case ManagerStateInterrupted:
+ case ManagerState::STATE_INTERRUPTED:
event = PVREvent::ManagerInterrupted;
break;
- case ManagerStateStarted:
+ case ManagerState::STATE_STARTED:
event = PVREvent::ManagerStarted;
break;
default:
@@ -504,27 +488,24 @@ void CPVRManager::Process()
m_addons->Continue();
m_database->Open();
- /* load the pvr data from the db and clients if it's not already loaded */
- XbmcThreads::EndTime<> progressTimeout(30s); // 30 secs
- CPVRGUIProgressHandler* progressHandler = new CPVRGUIProgressHandler(g_localizeStrings.Get(19235)); // PVR manager is starting up
- while (!LoadComponents(progressHandler) && IsInitialising())
+ if (!IsInitialising())
{
- CLog::Log(LOGWARNING, "PVR Manager failed to load data, retrying");
- CThread::Sleep(1000ms);
-
- if (progressHandler && progressTimeout.IsTimePast())
- {
- progressHandler->DestroyProgress();
- progressHandler = nullptr; // no delete, instance is deleting itself
- }
+ CLog::Log(LOGINFO, "PVR Manager: Start aborted");
+ return;
}
- if (progressHandler)
+ UnloadComponents();
+
+ if (!IsInitialising())
{
- progressHandler->DestroyProgress();
- progressHandler = nullptr; // no delete, instance is deleting itself
+ CLog::Log(LOGINFO, "PVR Manager: Start aborted");
+ return;
}
+ // Wait for at least one client to come up and load/update data
+ std::vector<std::shared_ptr<CPVRClient>> knownClients;
+ UpdateComponents(knownClients, ManagerState::STATE_STARTING);
+
if (!IsInitialising())
{
CLog::Log(LOGINFO, "PVR Manager: Start aborted");
@@ -542,22 +523,30 @@ void CPVRManager::Process()
m_timers->Start();
m_pendingUpdates->Start();
- SetState(ManagerStateStarted);
+ SetState(ManagerState::STATE_STARTED);
CLog::Log(LOGINFO, "PVR Manager: Started");
- /* main loop */
- CLog::LogFC(LOGDEBUG, LOGPVR, "PVR Manager entering main loop");
-
bool bRestart(false);
XbmcThreads::EndTime<> cachedImagesCleanupTimeout(30s); // first timeout after 30 secs
while (IsStarted() && m_addons->HasCreatedClients() && !bRestart)
{
+ // In case any new client connected, load from db and fetch data update from new client(s)
+ UpdateComponents(knownClients, ManagerState::STATE_STARTED);
+
if (cachedImagesCleanupTimeout.IsTimePast())
{
- // start a job to erase stale texture db entries and image files
- TriggerCleanupCachedImages();
- cachedImagesCleanupTimeout.Set(12h); // following timeouts after 12 hours
+ // We don't know for sure what to delete if there are not (yet) connected clients
+ if (m_addons->HasIgnoredClients())
+ {
+ cachedImagesCleanupTimeout.Set(10s); // try again in 10 secs
+ }
+ else
+ {
+ // start a job to erase stale texture db entries and image files
+ TriggerCleanupCachedImages();
+ cachedImagesCleanupTimeout.Set(12h); // following timeouts after 12 hours
+ }
}
/* first startup */
@@ -593,7 +582,21 @@ void CPVRManager::Process()
m_pendingUpdates->WaitForJobs(1000);
}
- CLog::LogFC(LOGDEBUG, LOGPVR, "PVR Manager leaving main loop");
+ m_addons->Stop();
+ m_pendingUpdates->Stop();
+ m_timers->Stop();
+ m_epgContainer.Stop();
+ m_guiInfo->Stop();
+
+ SetState(ManagerState::STATE_INTERRUPTED);
+
+ UnloadComponents();
+ m_database->Close();
+
+ ResetProperties();
+
+ CLog::Log(LOGINFO, "PVR Manager: Stopped");
+ SetState(ManagerState::STATE_STOPPED);
}
bool CPVRManager::SetWakeupCommand()
@@ -659,47 +662,127 @@ void CPVRManager::OnWake()
TriggerTimersUpdate();
}
-bool CPVRManager::LoadComponents(CPVRGUIProgressHandler* progressHandler)
+void CPVRManager::UpdateComponents(std::vector<std::shared_ptr<CPVRClient>>& knownClients,
+ ManagerState stateToCheck)
+{
+ XbmcThreads::EndTime<> progressTimeout(30s);
+ CPVRGUIProgressHandler* progressHandler =
+ new CPVRGUIProgressHandler(g_localizeStrings.Get(19235)); // PVR manager is starting up
+
+ // Wait for at least one client to come up and load/update data
+ while (!UpdateComponents(knownClients, stateToCheck, progressHandler) &&
+ m_addons->HasCreatedClients() && (stateToCheck == GetState()))
+ {
+ CThread::Sleep(1000ms);
+
+ if (progressHandler && progressTimeout.IsTimePast())
+ {
+ progressHandler->DestroyProgress();
+ progressHandler = nullptr; // no delete, instance is deleting itself
+ }
+ }
+
+ if (progressHandler)
+ {
+ progressHandler->DestroyProgress();
+ progressHandler = nullptr; // no delete, instance is deleting itself
+ }
+}
+
+bool CPVRManager::UpdateComponents(std::vector<std::shared_ptr<CPVRClient>>& knownClients,
+ ManagerState stateToCheck,
+ CPVRGUIProgressHandler* progressHandler)
{
- /* load at least one client */
- while (IsInitialising() && m_addons && !m_addons->HasCreatedClients())
- CThread::Sleep(50ms);
+ // find clients which disappeared since last check and remove them from known clients
+ for (auto it = knownClients.begin(); it != knownClients.end();)
+ {
+ if ((*it)->IgnoreClient())
+ {
+ it = knownClients.erase(it);
+ CLog::LogFC(LOGDEBUG, LOGPVR,
+ "PVR client '{}' disconnected. Erasing from list of known clients.", (*it)->ID());
+ }
+ else
+ ++it;
+ }
- if (!IsInitialising() || !m_addons->HasCreatedClients())
+ // find clients which appeared since last check and update them
+ CPVRClientMap clientMap;
+ m_addons->GetCreatedClients(clientMap);
+ if (clientMap.empty())
+ {
+ CLog::LogFC(LOGDEBUG, LOGPVR, "All created PVR clients gone!");
return false;
+ }
+
+ std::vector<std::shared_ptr<CPVRClient>> newClients;
+ for (const auto& entry : clientMap)
+ {
+ // skip not (yet) connected clients
+ if (entry.second->IgnoreClient())
+ {
+ CLog::LogFC(LOGDEBUG, LOGPVR, "Skipping not (yet) connected PVR client '{}'",
+ entry.second->ID());
+ continue;
+ }
- CLog::LogFC(LOGDEBUG, LOGPVR, "PVR Manager found active clients. Continuing startup");
+ if (knownClients.empty() || std::find_if(knownClients.cbegin(), knownClients.cend(),
+ [&entry](const std::shared_ptr<CPVRClient>& client) {
+ return entry.first == client->GetID();
+ }) == knownClients.cend())
+ {
+ knownClients.emplace_back(entry.second);
+ newClients.emplace_back(entry.second);
- /* load all channels and groups */
+ CLog::LogFC(LOGDEBUG, LOGPVR, "Adding new PVR client '{}' to list of known clients",
+ entry.second->ID());
+ }
+ }
+
+ if (newClients.empty())
+ return !knownClients.empty();
+
+ // Load all channels and groups
if (progressHandler)
- progressHandler->UpdateProgress(g_localizeStrings.Get(19236), 0); // Loading channels from clients
+ progressHandler->UpdateProgress(g_localizeStrings.Get(19236), 0); // Loading channels and groups
- if (!m_providers->Load() || !IsInitialising())
+ if (!m_providers->Update(newClients) || (stateToCheck != GetState()))
+ {
+ CLog::LogF(LOGERROR, "Failed to load PVR providers.");
+ knownClients.clear(); // start over
return false;
+ }
- if (!m_channelGroups->Load() || !IsInitialising())
+ if (!m_channelGroups->Update(newClients) || (stateToCheck != GetState()))
+ {
+ CLog::LogF(LOGERROR, "Failed to load PVR channels / groups.");
+ knownClients.clear(); // start over
return false;
+ }
PublishEvent(PVREvent::ChannelGroupsLoaded);
- /* get timers from the backends */
+ // Load all timers
if (progressHandler)
- progressHandler->UpdateProgress(g_localizeStrings.Get(19237), 50); // Loading timers from clients
+ progressHandler->UpdateProgress(g_localizeStrings.Get(19237), 50); // Loading timers
- m_timers->Load();
+ if (!m_timers->Update(newClients) || (stateToCheck != GetState()))
+ {
+ CLog::LogF(LOGERROR, "Failed to load PVR timers.");
+ knownClients.clear(); // start over
+ return false;
+ }
- /* get recordings from the backend */
+ // Load all recordings
if (progressHandler)
- progressHandler->UpdateProgress(g_localizeStrings.Get(19238), 75); // Loading recordings from clients
+ progressHandler->UpdateProgress(g_localizeStrings.Get(19238), 75); // Loading recordings
- m_recordings->Load();
-
- if (!IsInitialising())
+ if (!m_recordings->Update(newClients) || (stateToCheck != GetState()))
+ {
+ CLog::LogF(LOGERROR, "Failed to load PVR recordings.");
+ knownClients.clear(); // start over
return false;
-
- /* start the other pvr related update threads */
- if (progressHandler)
- progressHandler->UpdateProgress(g_localizeStrings.Get(19239), 85); // Starting background threads
+ }
return true;
}
@@ -812,13 +895,6 @@ void CPVRManager::TriggerEpgsCreate()
});
}
-void CPVRManager::TriggerRecordingsUpdate()
-{
- m_pendingUpdates->Append("pvr-update-recordings", [this]() {
- return Recordings()->Update();
- });
-}
-
void CPVRManager::TriggerRecordingsSizeInProgressUpdate()
{
m_pendingUpdates->Append("pvr-update-recordings-size", [this]() {
@@ -826,32 +902,80 @@ void CPVRManager::TriggerRecordingsSizeInProgressUpdate()
});
}
-void CPVRManager::TriggerTimersUpdate()
+void CPVRManager::TriggerRecordingsUpdate(int clientId)
{
- m_pendingUpdates->Append("pvr-update-timers", [this]() {
- return Timers()->Update();
+ m_pendingUpdates->Append("pvr-update-recordings-" + std::to_string(clientId), [this, clientId]() {
+ const std::shared_ptr<CPVRClient> client = GetClient(clientId);
+ if (client)
+ Recordings()->UpdateFromClients({client});
});
}
-void CPVRManager::TriggerChannelsUpdate()
+void CPVRManager::TriggerRecordingsUpdate()
{
- m_pendingUpdates->Append("pvr-update-channels", [this]() {
- return ChannelGroups()->Update(true);
+ m_pendingUpdates->Append("pvr-update-recordings",
+ [this]() { Recordings()->UpdateFromClients({}); });
+}
+
+void CPVRManager::TriggerTimersUpdate(int clientId)
+{
+ m_pendingUpdates->Append("pvr-update-timers-" + std::to_string(clientId), [this, clientId]() {
+ const std::shared_ptr<CPVRClient> client = GetClient(clientId);
+ if (client)
+ Timers()->UpdateFromClients({client});
});
}
+void CPVRManager::TriggerTimersUpdate()
+{
+ m_pendingUpdates->Append("pvr-update-timers", [this]() { Timers()->UpdateFromClients({}); });
+}
+
+void CPVRManager::TriggerProvidersUpdate(int clientId)
+{
+ m_pendingUpdates->Append("pvr-update-channel-providers-" + std::to_string(clientId),
+ [this, clientId]() {
+ const std::shared_ptr<CPVRClient> client = GetClient(clientId);
+ if (client)
+ Providers()->UpdateFromClients({client});
+ });
+}
+
void CPVRManager::TriggerProvidersUpdate()
{
- m_pendingUpdates->Append("pvr-update-channel-providers", [this]() {
- return Providers()->Update();
+ m_pendingUpdates->Append("pvr-update-channel-providers",
+ [this]() { Providers()->UpdateFromClients({}); });
+}
+
+void CPVRManager::TriggerChannelsUpdate(int clientId)
+{
+ m_pendingUpdates->Append("pvr-update-channels-" + std::to_string(clientId), [this, clientId]() {
+ const std::shared_ptr<CPVRClient> client = GetClient(clientId);
+ if (client)
+ ChannelGroups()->UpdateFromClients({client}, true);
});
}
+void CPVRManager::TriggerChannelsUpdate()
+{
+ m_pendingUpdates->Append("pvr-update-channels",
+ [this]() { ChannelGroups()->UpdateFromClients({}, true); });
+}
+
+void CPVRManager::TriggerChannelGroupsUpdate(int clientId)
+{
+ m_pendingUpdates->Append("pvr-update-channelgroups-" + std::to_string(clientId),
+ [this, clientId]() {
+ const std::shared_ptr<CPVRClient> client = GetClient(clientId);
+ if (client)
+ ChannelGroups()->UpdateFromClients({client}, false);
+ });
+}
+
void CPVRManager::TriggerChannelGroupsUpdate()
{
- m_pendingUpdates->Append("pvr-update-channelgroups", [this]() {
- return ChannelGroups()->Update(false);
- });
+ m_pendingUpdates->Append("pvr-update-channelgroups",
+ [this]() { ChannelGroups()->UpdateFromClients({}, false); });
}
void CPVRManager::TriggerSearchMissingChannelIcons()
@@ -895,10 +1019,6 @@ void CPVRManager::ConnectionStateChange(CPVRClient* client,
{
CJobManager::GetInstance().Submit([this, client, connectString, state, message] {
Clients()->ConnectionStateChange(client, connectString, state, message);
-
- if (state == PVR_CONNECTION_STATE_CONNECTED)
- Start(); // start over
-
return true;
});
}
diff --git a/xbmc/pvr/PVRManager.h b/xbmc/pvr/PVRManager.h
index a28ce57c6b..86e5326dab 100644
--- a/xbmc/pvr/PVRManager.h
+++ b/xbmc/pvr/PVRManager.h
@@ -211,39 +211,10 @@ namespace PVR
std::shared_ptr<CPVRDatabase> GetTVDatabase() const;
/*!
- * @return True while the PVRManager is initialising.
- */
- inline bool IsInitialising() const
- {
- return GetState() == ManagerStateStarting;
- }
-
- /*!
* @brief Check whether the PVRManager has fully started.
* @return True if started, false otherwise.
*/
- inline bool IsStarted() const
- {
- return GetState() == ManagerStateStarted;
- }
-
- /*!
- * @brief Check whether the PVRManager is stopping
- * @return True while the PVRManager is stopping.
- */
- inline bool IsStopping() const
- {
- return GetState() == ManagerStateStopping;
- }
-
- /*!
- * @brief Check whether the PVRManager has been stopped.
- * @return True if stopped, false otherwise.
- */
- inline bool IsStopped() const
- {
- return GetState() == ManagerStateStopped;
- }
+ bool IsStarted() const { return GetState() == ManagerState::STATE_STARTED; }
/*!
* @brief Check whether EPG tags for channels have been created.
@@ -276,7 +247,9 @@ namespace PVR
/*!
* @brief Let the background thread update the recordings list.
+ * @param clientId The id of the PVR client to update.
*/
+ void TriggerRecordingsUpdate(int clientId);
void TriggerRecordingsUpdate();
/*!
@@ -286,22 +259,30 @@ namespace PVR
/*!
* @brief Let the background thread update the timer list.
+ * @param clientId The id of the PVR client to update.
*/
+ void TriggerTimersUpdate(int clientId);
void TriggerTimersUpdate();
/*!
* @brief Let the background thread update the channel list.
+ * @param clientId The id of the PVR client to update.
*/
+ void TriggerChannelsUpdate(int clientId);
void TriggerChannelsUpdate();
/*!
* @brief Let the background thread update the provider list.
+ * @param clientId The id of the PVR client to update.
*/
+ void TriggerProvidersUpdate(int clientId);
void TriggerProvidersUpdate();
/*!
* @brief Let the background thread update the channel groups list.
+ * @param clientId The id of the PVR client to update.
*/
+ void TriggerChannelGroupsUpdate(int clientId);
void TriggerChannelGroupsUpdate();
/*!
@@ -381,12 +362,57 @@ namespace PVR
*/
bool SetWakeupCommand();
+ enum class ManagerState
+ {
+ STATE_ERROR = 0,
+ STATE_STOPPED,
+ STATE_STARTING,
+ STATE_SSTOPPING,
+ STATE_INTERRUPTED,
+ STATE_STARTED
+ };
+
+ /*!
+ * @return True while the PVRManager is initialising.
+ */
+ bool IsInitialising() const { return GetState() == ManagerState::STATE_STARTING; }
+
+ /*!
+ * @brief Check whether the PVRManager has been stopped.
+ * @return True if stopped, false otherwise.
+ */
+ bool IsStopped() const { return GetState() == ManagerState::STATE_STOPPED; }
+
+ /*!
+ * @brief Get the current state of the PVR manager.
+ * @return the state.
+ */
+ ManagerState GetState() const;
+
/*!
- * @brief Load at least one client and load all other PVR data (channelgroups, timers, recordings) after loading the client.
- * @param progressHandler The progress handler to use for showing the different load stages.
- * @return If at least one client and all pvr data was loaded, false otherwise.
+ * @brief Set the current state of the PVR manager.
+ * @param state the new state.
*/
- bool LoadComponents(CPVRGUIProgressHandler* progressHandler);
+ void SetState(ManagerState state);
+
+ /*!
+ * @brief Wait until at least one client is up. Update all data from database and the given PVR clients.
+ * @param knownClients [inout] List of last known active clients.
+ * @param stateToCheck Required state of the PVR manager while this method gets called.
+ */
+ void UpdateComponents(std::vector<std::shared_ptr<CPVRClient>>& knownClients,
+ ManagerState stateToCheck);
+
+ /*!
+ * @brief Update all data from database and the given PVR clients.
+ * @param knownClients [inout] List of last known active clients.
+ * @param stateToCheck Required state of the PVR manager while this method gets called.
+ * @param progressHandler The progress handler to use for showing the different stages.
+ * @return True if at least one client is known and successfully loaded, false otherwise.
+ */
+ bool UpdateComponents(std::vector<std::shared_ptr<CPVRClient>>& knownClients,
+ ManagerState stateToCheck,
+ CPVRGUIProgressHandler* progressHandler);
/*!
* @brief Unload all PVR data (recordings, timers, channelgroups).
@@ -408,28 +434,6 @@ namespace PVR
*/
void TriggerPlayChannelOnStartup();
- enum ManagerState
- {
- ManagerStateError = 0,
- ManagerStateStopped,
- ManagerStateStarting,
- ManagerStateStopping,
- ManagerStateInterrupted,
- ManagerStateStarted
- };
-
- /*!
- * @brief Get the current state of the PVR manager.
- * @return the state.
- */
- ManagerState GetState() const;
-
- /*!
- * @brief Set the current state of the PVR manager.
- * @param state the new state.
- */
- void SetState(ManagerState state);
-
bool IsCurrentlyParentalLocked(const std::shared_ptr<CPVRChannel>& channel, bool bGenerallyLocked) const;
CEventSource<PVREvent> m_events;
@@ -453,7 +457,7 @@ namespace PVR
bool m_bEpgsCreated = false; /*!< true if epg data for channels has been created */
mutable CCriticalSection m_managerStateMutex;
- ManagerState m_managerState = ManagerStateStopped;
+ ManagerState m_managerState = ManagerState::STATE_STOPPED;
std::unique_ptr<CStopWatch> m_parentalTimer;
CCriticalSection m_startStopMutex; // mutex for protecting pvr manager's start/restart/stop sequence */
diff --git a/xbmc/pvr/addons/PVRClient.cpp b/xbmc/pvr/addons/PVRClient.cpp
index fb374ec5e1..5e95f27fdb 100644
--- a/xbmc/pvr/addons/PVRClient.cpp
+++ b/xbmc/pvr/addons/PVRClient.cpp
@@ -171,11 +171,15 @@ ADDON_STATUS CPVRClient::Create(int iClientId)
ResetProperties(iClientId);
/* initialise the add-on */
- bool bReadyToUse(false);
- CLog::LogFC(LOGDEBUG, LOGPVR, "Creating PVR add-on instance '{}'", Name());
+ CLog::LogFC(LOGDEBUG, LOGPVR, "Creating PVR add-on instance '{}'", ID());
+
+ bool bReadyToUse = false;
if ((status = CreateInstance()) == ADDON_STATUS_OK)
bReadyToUse = GetAddonProperties();
+ CLog::LogFC(LOGDEBUG, LOGPVR, "Created PVR add-on instance '{}'. readytouse={} ", ID(),
+ bReadyToUse);
+
m_bReadyToUse = bReadyToUse;
return status;
}
@@ -187,14 +191,14 @@ void CPVRClient::Destroy()
m_bReadyToUse = false;
- CLog::LogFC(LOGDEBUG, LOGPVR, "Destroying PVR add-on instance '{}'", GetFriendlyName());
+ CLog::LogFC(LOGDEBUG, LOGPVR, "Destroying PVR add-on instance '{}'", ID());
m_bBlockAddonCalls = true;
m_allAddonCallsFinished.Wait();
DestroyInstance();
- CLog::LogFC(LOGDEBUG, LOGPVR, "PVR add-on instance '{}' destroyed", GetFriendlyName());
+ CLog::LogFC(LOGDEBUG, LOGPVR, "Destroyed PVR add-on instance '{}'", ID());
if (m_menuhooks)
m_menuhooks->Clear();
@@ -561,10 +565,7 @@ bool CPVRClient::GetAddonProperties()
{
if (types_array[i].iId == PVR_TIMER_TYPE_NONE)
{
- CLog::LogF(LOGERROR,
- "Invalid timer type supplied by add-on '{}'. Please contact the developer "
- "of this add-on: {}",
- GetFriendlyName(), Author());
+ CLog::LogF(LOGERROR, "Invalid timer type supplied by add-on '{}'.", ID());
continue;
}
timerTypes.emplace_back(
@@ -1418,10 +1419,24 @@ PVR_ERROR CPVRClient::DoAddonCall(const char* strFunctionName,
return PVR_ERROR_NOT_IMPLEMENTED;
if (m_bBlockAddonCalls)
+ {
+ CLog::Log(LOGWARNING, "{}: Blocking call to add-on '{}'.", strFunctionName, ID());
+ return PVR_ERROR_SERVER_ERROR;
+ }
+
+ if (bCheckReadyToUse && IgnoreClient())
+ {
+ CLog::Log(LOGWARNING, "{}: Blocking call to add-on '{}'. Add-on not (yet) connected.",
+ strFunctionName, ID());
return PVR_ERROR_SERVER_ERROR;
+ }
- if (bCheckReadyToUse && (!ReadyToUse() || IgnoreClient()))
+ if (bCheckReadyToUse && !ReadyToUse())
+ {
+ CLog::Log(LOGWARNING, "{}: Blocking call to add-on '{}'. Add-on not ready to use.",
+ strFunctionName, ID());
return PVR_ERROR_SERVER_ERROR;
+ }
// Call.
m_allAddonCallsFinished.Reset();
@@ -1435,7 +1450,7 @@ PVR_ERROR CPVRClient::DoAddonCall(const char* strFunctionName,
// Log error, if any.
if (error != PVR_ERROR_NO_ERROR && error != PVR_ERROR_NOT_IMPLEMENTED)
- CLog::Log(LOGERROR, "{}: Add-on '{}' returned an error: {}", strFunctionName, GetFriendlyName(),
+ CLog::Log(LOGERROR, "{}: Add-on '{}' returned an error: {}", strFunctionName, ID(),
ToString(error));
return error;
@@ -1457,7 +1472,7 @@ PVR_ERROR CPVRClient::OpenLiveStream(const std::shared_ptr<CPVRChannel>& channel
if (!CanPlayChannel(channel))
{
- CLog::LogFC(LOGDEBUG, LOGPVR, "Add-on '{}' can not play channel '{}'", GetFriendlyName(),
+ CLog::LogFC(LOGDEBUG, LOGPVR, "Add-on '{}' can not play channel '{}'", ID(),
channel->ChannelName());
return PVR_ERROR_SERVER_ERROR;
}
@@ -1716,7 +1731,7 @@ void CPVRClient::HandleAddonCallback(const char* strFunctionName,
if (!bForceCall && client->m_bBlockAddonCalls && client->m_iAddonCalls == 0)
{
CLog::Log(LOGWARNING, LOGPVR, "{}: Ignoring callback from PVR client '{}'", strFunctionName,
- client->GetFriendlyName());
+ client->ID());
return;
}
@@ -1922,7 +1937,7 @@ void CPVRClient::cb_recording_notification(void* kodiInstance,
EventPtr(new CNotificationEvent(client->Name(), strLine1, client->Icon(), strLine2)));
CLog::LogFC(LOGDEBUG, LOGPVR, "Recording {} on client '{}'. name='{}' filename='{}'",
- bOnOff ? "started" : "finished", client->Name(), strName, strFileName);
+ bOnOff ? "started" : "finished", client->ID(), strName, strFileName);
});
}
@@ -1930,21 +1945,23 @@ void CPVRClient::cb_trigger_channel_update(void* kodiInstance)
{
HandleAddonCallback(__func__, kodiInstance, [&](CPVRClient* client) {
// update channels in the next iteration of the pvrmanager's main loop
- CServiceBroker::GetPVRManager().TriggerChannelsUpdate();
+ CServiceBroker::GetPVRManager().TriggerChannelsUpdate(client->GetID());
});
}
void CPVRClient::cb_trigger_provider_update(void* kodiInstance)
{
- /* update the providers table in the next iteration of the pvrmanager's main loop */
- CServiceBroker::GetPVRManager().TriggerProvidersUpdate();
+ HandleAddonCallback(__func__, kodiInstance, [&](CPVRClient* client) {
+ /* update the providers table in the next iteration of the pvrmanager's main loop */
+ CServiceBroker::GetPVRManager().TriggerProvidersUpdate(client->GetID());
+ });
}
void CPVRClient::cb_trigger_timer_update(void* kodiInstance)
{
HandleAddonCallback(__func__, kodiInstance, [&](CPVRClient* client) {
// update timers in the next iteration of the pvrmanager's main loop
- CServiceBroker::GetPVRManager().TriggerTimersUpdate();
+ CServiceBroker::GetPVRManager().TriggerTimersUpdate(client->GetID());
});
}
@@ -1952,7 +1969,7 @@ void CPVRClient::cb_trigger_recording_update(void* kodiInstance)
{
HandleAddonCallback(__func__, kodiInstance, [&](CPVRClient* client) {
// update recordings in the next iteration of the pvrmanager's main loop
- CServiceBroker::GetPVRManager().TriggerRecordingsUpdate();
+ CServiceBroker::GetPVRManager().TriggerRecordingsUpdate(client->GetID());
});
}
@@ -1960,7 +1977,7 @@ void CPVRClient::cb_trigger_channel_groups_update(void* kodiInstance)
{
HandleAddonCallback(__func__, kodiInstance, [&](CPVRClient* client) {
// update all channel groups in the next iteration of the pvrmanager's main loop
- CServiceBroker::GetPVRManager().TriggerChannelGroupsUpdate();
+ CServiceBroker::GetPVRManager().TriggerChannelGroupsUpdate(client->GetID());
});
}
@@ -2009,7 +2026,7 @@ void CPVRClient::cb_connection_state_change(void* kodiInstance,
CLog::LogFC(LOGDEBUG, LOGPVR,
"State for connection '{}' on client '{}' changed from '{}' to '{}'",
- strConnectionString, client->Name(), prevState, newState);
+ strConnectionString, client->ID(), prevState, newState);
client->SetConnectionState(newState);
diff --git a/xbmc/pvr/addons/PVRClients.cpp b/xbmc/pvr/addons/PVRClients.cpp
index d6b30ca5f6..23ce9bbed7 100644
--- a/xbmc/pvr/addons/PVRClients.cpp
+++ b/xbmc/pvr/addons/PVRClients.cpp
@@ -157,8 +157,7 @@ void CPVRClients::UpdateAddons(const std::string& changedAddonId /*= ""*/)
if (status != ADDON_STATUS_OK)
{
- CLog::LogF(LOGERROR, "Failed to create add-on {}, status = {}", addon.first->Name(),
- status);
+ CLog::LogF(LOGERROR, "Failed to create add-on {}, status = {}", addon.first->ID(), status);
if (status == ADDON_STATUS_PERMANENT_FAILURE)
{
CServiceBroker::GetAddonMgr().DisableAddon(addon.first->ID(),
@@ -305,7 +304,7 @@ bool CPVRClients::HasCreatedClients() const
CSingleLock lock(m_critSection);
for (const auto& client : m_clientMap)
{
- if (client.second->ReadyToUse() && !client.second->IgnoreClient())
+ if (client.second->ReadyToUse())
return true;
}
@@ -350,7 +349,7 @@ int CPVRClients::GetCreatedClients(CPVRClientMap& clients) const
CSingleLock lock(m_critSection);
for (const auto& client : m_clientMap)
{
- if (client.second->ReadyToUse() && !client.second->IgnoreClient())
+ if (client.second->ReadyToUse())
{
clients.insert(std::make_pair(client.second->GetID(), client.second));
++iReturn;
@@ -391,7 +390,20 @@ std::vector<CVariant> CPVRClients::GetClientProviderInfos() const
return clientProviderInfos;
}
-PVR_ERROR CPVRClients::GetCreatedClients(CPVRClientMap& clientsReady, std::vector<int>& clientsNotReady) const
+int CPVRClients::GetFirstCreatedClientID()
+{
+ CSingleLock lock(m_critSection);
+ for (const auto& client : m_clientMap)
+ {
+ if (client.second->ReadyToUse())
+ return client.second->GetID();
+ }
+
+ return -1;
+}
+
+PVR_ERROR CPVRClients::GetCallableClients(CPVRClientMap& clientsReady,
+ std::vector<int>& clientsNotReady) const
{
clientsNotReady.clear();
@@ -417,18 +429,6 @@ PVR_ERROR CPVRClients::GetCreatedClients(CPVRClientMap& clientsReady, std::vecto
return clientsNotReady.empty() ? PVR_ERROR_NO_ERROR : PVR_ERROR_SERVER_ERROR;
}
-int CPVRClients::GetFirstCreatedClientID()
-{
- CSingleLock lock(m_critSection);
- for (const auto& client : m_clientMap)
- {
- if (client.second->ReadyToUse())
- return client.second->GetID();
- }
-
- return -1;
-}
-
int CPVRClients::EnabledClientAmount() const
{
int iReturn = 0;
@@ -448,6 +448,13 @@ int CPVRClients::EnabledClientAmount() const
return iReturn;
}
+bool CPVRClients::IsEnabledClient(int clientId) const
+{
+ std::shared_ptr<CPVRClient> client;
+ GetClient(clientId, client);
+ return client && !CServiceBroker::GetAddonMgr().IsAddonDisabled(client->ID());
+}
+
std::vector<CVariant> CPVRClients::GetEnabledClientInfos() const
{
std::vector<CVariant> clientInfos;
@@ -487,6 +494,18 @@ std::vector<CVariant> CPVRClients::GetEnabledClientInfos() const
return clientInfos;
}
+bool CPVRClients::HasIgnoredClients() const
+{
+ CSingleLock lock(m_critSection);
+ for (const auto& client : m_clientMap)
+ {
+ if (client.second->IgnoreClient())
+ return true;
+ }
+
+ return false;
+}
+
////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// client API calls
////////////////////////////////////////////////////////////////////////////////////////////////////////////////
@@ -528,11 +547,15 @@ std::vector<SBackend> CPVRClients::GetBackendProperties() const
return backendProperties;
}
-bool CPVRClients::GetTimers(CPVRTimersContainer* timers, std::vector<int>& failedClients)
+bool CPVRClients::GetTimers(const std::vector<std::shared_ptr<CPVRClient>>& clients,
+ CPVRTimersContainer* timers,
+ std::vector<int>& failedClients)
{
- return ForCreatedClients(__FUNCTION__, [timers](const std::shared_ptr<CPVRClient>& client) {
- return client->GetTimers(timers);
- }, failedClients) == PVR_ERROR_NO_ERROR;
+ return ForClients(__FUNCTION__, clients,
+ [timers](const std::shared_ptr<CPVRClient>& client) {
+ return client->GetTimers(timers);
+ },
+ failedClients) == PVR_ERROR_NO_ERROR;
}
PVR_ERROR CPVRClients::GetTimerTypes(std::vector<std::shared_ptr<CPVRTimerType>>& results) const
@@ -546,16 +569,16 @@ PVR_ERROR CPVRClients::GetTimerTypes(std::vector<std::shared_ptr<CPVRTimerType>>
});
}
-PVR_ERROR CPVRClients::GetRecordings(CPVRRecordings* recordings,
+PVR_ERROR CPVRClients::GetRecordings(const std::vector<std::shared_ptr<CPVRClient>>& clients,
+ CPVRRecordings* recordings,
bool deleted,
std::vector<int>& failedClients)
{
- return ForCreatedClients(
- __FUNCTION__,
- [recordings, deleted](const std::shared_ptr<CPVRClient>& client) {
- return client->GetRecordings(recordings, deleted);
- },
- failedClients);
+ return ForClients(__FUNCTION__, clients,
+ [recordings, deleted](const std::shared_ptr<CPVRClient>& client) {
+ return client->GetRecordings(recordings, deleted);
+ },
+ failedClients);
}
PVR_ERROR CPVRClients::DeleteAllRecordingsFromTrash()
@@ -579,44 +602,51 @@ PVR_ERROR CPVRClients::SetEPGMaxFutureDays(int iFutureDays)
});
}
-PVR_ERROR CPVRClients::GetChannels(bool bRadio,
+PVR_ERROR CPVRClients::GetChannels(const std::vector<std::shared_ptr<CPVRClient>>& clients,
+ bool bRadio,
std::vector<std::shared_ptr<CPVRChannel>>& channels,
std::vector<int>& failedClients)
{
- return ForCreatedClients(
- __FUNCTION__,
- [bRadio, &channels](const std::shared_ptr<CPVRClient>& client) {
- return client->GetChannels(bRadio, channels);
- },
- failedClients);
+ return ForClients(__FUNCTION__, clients,
+ [bRadio, &channels](const std::shared_ptr<CPVRClient>& client) {
+ return client->GetChannels(bRadio, channels);
+ },
+ failedClients);
}
-PVR_ERROR CPVRClients::GetProviders(CPVRProvidersContainer* providers,
+PVR_ERROR CPVRClients::GetProviders(const std::vector<std::shared_ptr<CPVRClient>>& clients,
+ CPVRProvidersContainer* providers,
std::vector<int>& failedClients)
{
- return ForCreatedClients(__FUNCTION__, [providers](const std::shared_ptr<CPVRClient>& client) {
- return client->GetProviders(*providers);
- }, failedClients);
+ return ForClients(__FUNCTION__, clients,
+ [providers](const std::shared_ptr<CPVRClient>& client) {
+ return client->GetProviders(*providers);
+ },
+ failedClients);
}
-PVR_ERROR CPVRClients::GetChannelGroups(CPVRChannelGroups* groups, std::vector<int>& failedClients)
+PVR_ERROR CPVRClients::GetChannelGroups(const std::vector<std::shared_ptr<CPVRClient>>& clients,
+ CPVRChannelGroups* groups,
+ std::vector<int>& failedClients)
{
- return ForCreatedClients(__FUNCTION__, [groups](const std::shared_ptr<CPVRClient>& client) {
- return client->GetChannelGroups(groups);
- }, failedClients);
+ return ForClients(__FUNCTION__, clients,
+ [groups](const std::shared_ptr<CPVRClient>& client) {
+ return client->GetChannelGroups(groups);
+ },
+ failedClients);
}
PVR_ERROR CPVRClients::GetChannelGroupMembers(
+ const std::vector<std::shared_ptr<CPVRClient>>& clients,
CPVRChannelGroup* group,
std::vector<std::shared_ptr<CPVRChannelGroupMember>>& groupMembers,
std::vector<int>& failedClients)
{
- return ForCreatedClients(
- __FUNCTION__,
- [group, &groupMembers](const std::shared_ptr<CPVRClient>& client) {
- return client->GetChannelGroupMembers(group, groupMembers);
- },
- failedClients);
+ return ForClients(__FUNCTION__, clients,
+ [group, &groupMembers](const std::shared_ptr<CPVRClient>& client) {
+ return client->GetChannelGroupMembers(group, groupMembers);
+ },
+ failedClients);
}
std::vector<std::shared_ptr<CPVRClient>> CPVRClients::GetClientsSupportingChannelScan() const
@@ -786,6 +816,24 @@ void CPVRClients::ConnectionStateChange(CPVRClient* client,
CJobManager::GetInstance().AddJob(new CPVREventLogJob(bNotify, bError, client->Name(), strMsg, client->Icon()), nullptr);
}
+namespace
+{
+
+void LogClientWarning(const char* strFunctionName, const std::shared_ptr<CPVRClient>& client)
+{
+ if (client->IgnoreClient())
+ CLog::Log(LOGWARNING, "{}: Not calling add-on '{}'. Add-on not (yet) connected.",
+ strFunctionName, client->ID());
+ else if (!client->ReadyToUse())
+ CLog::Log(LOGWARNING, "{}: Not calling add-on '{}'. Add-on not ready to use.", strFunctionName,
+ client->ID());
+ else
+ CLog::Log(LOGERROR, "{}: Not calling add-on '{}' for unexpected reason.", strFunctionName,
+ client->ID());
+}
+
+} // unnamed namespace
+
PVR_ERROR CPVRClients::ForCreatedClients(const char* strFunctionName,
const PVRClientFunction& function) const
{
@@ -800,7 +848,19 @@ PVR_ERROR CPVRClients::ForCreatedClients(const char* strFunctionName,
PVR_ERROR lastError = PVR_ERROR_NO_ERROR;
CPVRClientMap clients;
- GetCreatedClients(clients, failedClients);
+ GetCallableClients(clients, failedClients);
+
+ if (!failedClients.empty())
+ {
+ for (int id : failedClients)
+ {
+ std::shared_ptr<CPVRClient> client;
+ GetClient(id, client);
+
+ if (client)
+ LogClientWarning(strFunctionName, client);
+ }
+ }
for (const auto& clientEntry : clients)
{
@@ -808,11 +868,61 @@ PVR_ERROR CPVRClients::ForCreatedClients(const char* strFunctionName,
if (currentError != PVR_ERROR_NO_ERROR && currentError != PVR_ERROR_NOT_IMPLEMENTED)
{
- CLog::Log(LOGERROR, "{}: PVR client '{}' returned an error: {}", strFunctionName,
- clientEntry.second->GetFriendlyName(), CPVRClient::ToString(currentError));
lastError = currentError;
failedClients.emplace_back(clientEntry.first);
}
}
return lastError;
}
+
+PVR_ERROR CPVRClients::ForClients(const char* strFunctionName,
+ const std::vector<std::shared_ptr<CPVRClient>>& clients,
+ const PVRClientFunction& function,
+ std::vector<int>& failedClients) const
+{
+ if (clients.empty())
+ return ForCreatedClients(strFunctionName, function, failedClients);
+
+ PVR_ERROR lastError = PVR_ERROR_NO_ERROR;
+
+ failedClients.clear();
+
+ {
+ CSingleLock lock(m_critSection);
+ for (const auto& entry : m_clientMap)
+ {
+ if (entry.second->ReadyToUse() && !entry.second->IgnoreClient() &&
+ std::find_if(clients.cbegin(), clients.cend(),
+ [&entry](const std::shared_ptr<CPVRClient>& client) {
+ return entry.first == client->GetID();
+ }) != clients.cend())
+ {
+ // Allow ready to use clients that shall be called
+ continue;
+ }
+
+ failedClients.emplace_back(entry.first);
+ }
+ }
+
+ for (const auto& client : clients)
+ {
+ if (std::find_if(failedClients.cbegin(), failedClients.cend(), [&client](int failedClientId) {
+ return client->GetID() == failedClientId;
+ }) == failedClients.cend())
+ {
+ PVR_ERROR currentError = function(client);
+
+ if (currentError != PVR_ERROR_NO_ERROR && currentError != PVR_ERROR_NOT_IMPLEMENTED)
+ {
+ lastError = currentError;
+ failedClients.emplace_back(client->GetID());
+ }
+ }
+ else
+ {
+ LogClientWarning(strFunctionName, client);
+ }
+ }
+ return lastError;
+}
diff --git a/xbmc/pvr/addons/PVRClients.h b/xbmc/pvr/addons/PVRClients.h
index f1edc34331..8bb173069b 100644
--- a/xbmc/pvr/addons/PVRClients.h
+++ b/xbmc/pvr/addons/PVRClients.h
@@ -158,12 +158,25 @@ namespace PVR
int GetFirstCreatedClientID();
/*!
+ * @brief Check whether there are any created, but not (yet) connected clients.
+ * @return True if at least one client is ignored.
+ */
+ bool HasIgnoredClients() const;
+
+ /*!
* @brief Get the number of enabled clients.
* @return The amount of enabled clients.
*/
int EnabledClientAmount() const;
/*!
+ * @brief Check whether a given client ID points to an enabled client.
+ * @param clientId The client ID.
+ * @return True if the the client ID represents an enabled client, false otherwise.
+ */
+ bool IsEnabledClient(int clientId) const;
+
+ /*!
* @brief Get a list of the enabled client infos.
* @return A list of enabled client infos.
*/
@@ -186,12 +199,15 @@ namespace PVR
//@{
/*!
- * @brief Get all timers from all created clients
+ * @brief Get all timers from the given clients
+ * @param clients The clients to fetch data from. Leave empty to fetch data from all created clients.
* @param timers Store the timers in this container.
* @param failedClients in case of errors will contain the ids of the clients for which the timers could not be obtained.
* @return true on success for all clients, false in case of error for at least one client.
*/
- bool GetTimers(CPVRTimersContainer* timers, std::vector<int>& failedClients);
+ bool GetTimers(const std::vector<std::shared_ptr<CPVRClient>>& clients,
+ CPVRTimersContainer* timers,
+ std::vector<int>& failedClients);
/*!
* @brief Get all supported timer types.
@@ -206,13 +222,15 @@ namespace PVR
//@{
/*!
- * @brief Get all recordings from clients
+ * @brief Get all recordings from the given clients
+ * @param clients The clients to fetch data from. Leave empty to fetch data from all created clients.
* @param recordings Store the recordings in this container.
* @param deleted If true, return deleted recordings, return not deleted recordings otherwise.
* @param failedClients in case of errors will contain the ids of the clients for which the recordings could not be obtained.
* @return PVR_ERROR_NO_ERROR if the operation succeeded, the respective PVR_ERROR value otherwise.
*/
- PVR_ERROR GetRecordings(CPVRRecordings* recordings,
+ PVR_ERROR GetRecordings(const std::vector<std::shared_ptr<CPVRClient>>& clients,
+ CPVRRecordings* recordings,
bool deleted,
std::vector<int>& failedClients);
@@ -263,40 +281,50 @@ namespace PVR
//@{
/*!
- * @brief Get all channels from backends.
+ * @brief Get all channels from the given clients.
+ * @param clients The clients to fetch data from. Leave empty to fetch data from all created clients.
* @param bRadio Whether to fetch radio or TV channels.
* @param channels The container to store the channels.
* @param failedClients in case of errors will contain the ids of the clients for which the channels could not be obtained.
* @return PVR_ERROR_NO_ERROR if the channels were fetched successfully, last error otherwise.
*/
- PVR_ERROR GetChannels(bool bRadio,
+ PVR_ERROR GetChannels(const std::vector<std::shared_ptr<CPVRClient>>& clients,
+ bool bRadio,
std::vector<std::shared_ptr<CPVRChannel>>& channels,
std::vector<int>& failedClients);
/*!
* @brief Get all providers from backends.
+ * @param clients The clients to fetch data from. Leave empty to fetch data from all created clients.
* @param group The container to store the providers in.
* @param failedClients in case of errors will contain the ids of the clients for which the providers could not be obtained.
* @return PVR_ERROR_NO_ERROR if the providers were fetched successfully, last error otherwise.
*/
- PVR_ERROR GetProviders(CPVRProvidersContainer* providers, std::vector<int>& failedClients);
+ PVR_ERROR GetProviders(const std::vector<std::shared_ptr<CPVRClient>>& clients,
+ CPVRProvidersContainer* providers,
+ std::vector<int>& failedClients);
/*!
- * @brief Get all channel groups from backends.
+ * @brief Get all channel groups from the given clients.
+ * @param clients The clients to fetch data from. Leave empty to fetch data from all created clients.
* @param groups Store the channel groups in this container.
* @param failedClients in case of errors will contain the ids of the clients for which the channel groups could not be obtained.
* @return PVR_ERROR_NO_ERROR if the channel groups were fetched successfully, last error otherwise.
*/
- PVR_ERROR GetChannelGroups(CPVRChannelGroups* groups, std::vector<int>& failedClients);
+ PVR_ERROR GetChannelGroups(const std::vector<std::shared_ptr<CPVRClient>>& clients,
+ CPVRChannelGroups* groups,
+ std::vector<int>& failedClients);
/*!
- * @brief Get all group members of a channel group.
+ * @brief Get all group members of a channel group from the given clients.
+ * @param clients The clients to fetch data from. Leave empty to fetch data from all created clients.
* @param group The group to get the member for.
* @param groupMembers The container for the group members.
* @param failedClients in case of errors will contain the ids of the clients for which the channel group members could not be obtained.
* @return PVR_ERROR_NO_ERROR if the channel group members were fetched successfully, last error otherwise.
*/
PVR_ERROR GetChannelGroupMembers(
+ const std::vector<std::shared_ptr<CPVRClient>>& clients,
CPVRChannelGroup* group,
std::vector<std::shared_ptr<CPVRChannelGroupMember>>& groupMembers,
std::vector<int>& failedClients);
@@ -405,11 +433,25 @@ namespace PVR
* @param clientsNotReady Store the the ids of the not (yet) ready clients in this list.
* @return PVR_ERROR_NO_ERROR in case all clients are ready, PVR_ERROR_SERVER_ERROR otherwise.
*/
- PVR_ERROR GetCreatedClients(CPVRClientMap& clientsReady, std::vector<int>& clientsNotReady) const;
+ PVR_ERROR GetCallableClients(CPVRClientMap& clientsReady,
+ std::vector<int>& clientsNotReady) const;
typedef std::function<PVR_ERROR(const std::shared_ptr<CPVRClient>&)> PVRClientFunction;
/*!
+ * @brief Wraps calls to the given clients in order to do common pre and post function invocation actions.
+ * @param strFunctionName The function name, for logging purposes.
+ * @param clients The clients to wrap.
+ * @param function The function to wrap. It has to have return type PVR_ERROR and must take a const reference to a std::shared_ptr<CPVRClient> as parameter.
+ * @param failedClients Contains a list of the ids of clients for that the call failed, if any.
+ * @return PVR_ERROR_NO_ERROR on success, any other PVR_ERROR_* value otherwise.
+ */
+ PVR_ERROR ForClients(const char* strFunctionName,
+ const std::vector<std::shared_ptr<CPVRClient>>& clients,
+ const PVRClientFunction& function,
+ std::vector<int>& failedClients) const;
+
+ /*!
* @brief Wraps calls to all created clients in order to do common pre and post function invocation actions.
* @param strFunctionName The function name, for logging purposes.
* @param function The function to wrap. It has to have return type PVR_ERROR and must take a const reference to a std::shared_ptr<CPVRClient> as parameter.
diff --git a/xbmc/pvr/channels/PVRChannelGroup.cpp b/xbmc/pvr/channels/PVRChannelGroup.cpp
index ca15abd5de..460c6ba12b 100644
--- a/xbmc/pvr/channels/PVRChannelGroup.cpp
+++ b/xbmc/pvr/channels/PVRChannelGroup.cpp
@@ -93,18 +93,19 @@ std::shared_ptr<CPVRChannelGroupSettings> CPVRChannelGroup::GetSettings() const
return m_settings;
}
-bool CPVRChannelGroup::Load(
- const std::map<std::pair<int, int>, std::shared_ptr<CPVRChannel>>& channels)
+bool CPVRChannelGroup::LoadFromDatabase(
+ const std::map<std::pair<int, int>, std::shared_ptr<CPVRChannel>>& channels,
+ const std::vector<std::shared_ptr<CPVRClient>>& clients)
{
- /* make sure this container is empty before loading */
- Unload();
-
- int iChannelCount = m_iGroupId > 0 ? LoadFromDb() : 0;
+ const int iChannelCount = m_iGroupId > 0 ? LoadFromDatabase(clients) : 0;
CLog::LogFC(LOGDEBUG, LOGPVR, "Fetched {} {} group members from the database for group '{}'",
iChannelCount, IsRadio() ? "radio" : "TV", GroupName());
for (const auto& groupMember : m_members)
{
+ if (groupMember.second->Channel())
+ continue;
+
auto channel = channels.find(groupMember.first);
if (channel == channels.end())
{
@@ -127,14 +128,14 @@ void CPVRChannelGroup::Unload()
m_failedClients.clear();
}
-bool CPVRChannelGroup::Update()
+bool CPVRChannelGroup::UpdateFromClients(const std::vector<std::shared_ptr<CPVRClient>>& clients)
{
if (GroupType() == PVR_GROUP_TYPE_USER_DEFINED || !GetSettings()->SyncChannelGroups())
return true;
// get the channel group members from the backends.
std::vector<std::shared_ptr<CPVRChannelGroupMember>> groupMembers;
- CServiceBroker::GetPVRManager().Clients()->GetChannelGroupMembers(this, groupMembers,
+ CServiceBroker::GetPVRManager().Clients()->GetChannelGroupMembers(clients, this, groupMembers,
m_failedClients);
return UpdateGroupEntries(groupMembers);
}
@@ -470,26 +471,32 @@ void CPVRChannelGroup::GetChannelNumbers(std::vector<std::string>& channelNumber
}
}
-int CPVRChannelGroup::LoadFromDb()
+int CPVRChannelGroup::LoadFromDatabase(const std::vector<std::shared_ptr<CPVRClient>>& clients)
{
const std::shared_ptr<CPVRDatabase> database(CServiceBroker::GetPVRManager().GetTVDatabase());
if (!database)
return -1;
- const int iChannelCount = Size();
- const std::vector<std::shared_ptr<CPVRChannelGroupMember>> results = database->Get(*this);
+ const std::vector<std::shared_ptr<CPVRChannelGroupMember>> results =
+ database->Get(*this, clients);
std::vector<std::shared_ptr<CPVRChannelGroupMember>> membersToDelete;
if (!results.empty())
{
+ const std::shared_ptr<CPVRClients> clients = CServiceBroker::GetPVRManager().Clients();
+
CSingleLock lock(m_critSection);
for (const auto& member : results)
{
// Consistency check.
if (member->ClientID() > 0 && member->ChannelUID() > 0 && member->IsRadio() == IsRadio())
{
- m_sortedMembers.emplace_back(member);
- m_members.emplace(std::make_pair(member->ClientID(), member->ChannelUID()), member);
+ // Ignore data from unknown/disabled clients
+ if (clients->IsEnabledClient(member->ClientID()))
+ {
+ m_sortedMembers.emplace_back(member);
+ m_members.emplace(std::make_pair(member->ClientID(), member->ChannelUID()), member);
+ }
}
else
{
@@ -506,7 +513,7 @@ int CPVRChannelGroup::LoadFromDb()
DeleteGroupMembersFromDb(membersToDelete);
- return results.size() - membersToDelete.size() - iChannelCount;
+ return results.size() - membersToDelete.size();
}
void CPVRChannelGroup::DeleteGroupMembersFromDb(
@@ -661,15 +668,13 @@ std::vector<std::shared_ptr<CPVRChannelGroupMember>> CPVRChannelGroup::RemoveDel
CLog::Log(LOGINFO, "Removed stale {} channel '{}' from group '{}'",
IsRadio() ? "radio" : "TV", channel->ChannelName(), GroupName());
membersToRemove.emplace_back(*it);
- }
- m_members.erase(channel->StorageId());
- it = m_sortedMembers.erase(it);
- }
- else
- {
- ++it;
+ m_members.erase(channel->StorageId());
+ it = m_sortedMembers.erase(it);
+ continue;
+ }
}
+ ++it;
}
DeleteGroupMembersFromDb(membersToRemove);
diff --git a/xbmc/pvr/channels/PVRChannelGroup.h b/xbmc/pvr/channels/PVRChannelGroup.h
index ca3026aa44..07c4be20cc 100644
--- a/xbmc/pvr/channels/PVRChannelGroup.h
+++ b/xbmc/pvr/channels/PVRChannelGroup.h
@@ -32,6 +32,7 @@ namespace PVR
class CPVRChannel;
class CPVRChannelGroupMember;
+ class CPVRClient;
class CPVREpgInfoTag;
enum EpgDateType
@@ -82,11 +83,14 @@ namespace PVR
CEventStream<PVREvent>& Events() { return m_events; }
/*!
- * @brief Load the channels from the database, update and sync data from clients.
+ * @brief Load the channels from the database.
* @param channels All available channels.
+ * @param clients The PVR clients data should be loaded for. Leave empty for all clients.
* @return True when loaded successfully, false otherwise.
*/
- virtual bool Load(const std::map<std::pair<int, int>, std::shared_ptr<CPVRChannel>>& channels);
+ virtual bool LoadFromDatabase(
+ const std::map<std::pair<int, int>, std::shared_ptr<CPVRChannel>>& channels,
+ const std::vector<std::shared_ptr<CPVRClient>>& clients);
/*!
* @brief Clear all data.
@@ -99,10 +103,11 @@ namespace PVR
size_t Size() const;
/*!
- * @brief Refresh the channel list from the clients, sync with local data.
+ * @brief Update data with channel group members from the given clients, sync with local data.
+ * @param clients The clients to fetch data from. Leave empty to fetch data from all created clients.
* @return True on success, false otherwise.
*/
- virtual bool Update();
+ virtual bool UpdateFromClients(const std::vector<std::shared_ptr<CPVRClient>>& clients);
/*!
* @brief Get the path of this group.
@@ -514,9 +519,10 @@ namespace PVR
private:
/*!
* @brief Load the channel group members stored in the database.
+ * @param clients The PVR clients to load data for. Leave empty for all clients.
* @return The amount of channel group members that were added.
*/
- int LoadFromDb();
+ int LoadFromDatabase(const std::vector<std::shared_ptr<CPVRClient>>& clients);
/*!
* @brief Delete channel group members from database.
diff --git a/xbmc/pvr/channels/PVRChannelGroupInternal.cpp b/xbmc/pvr/channels/PVRChannelGroupInternal.cpp
index e7b4bc6715..0ec5ffb3a4 100644
--- a/xbmc/pvr/channels/PVRChannelGroupInternal.cpp
+++ b/xbmc/pvr/channels/PVRChannelGroupInternal.cpp
@@ -44,10 +44,11 @@ CPVRChannelGroupInternal::~CPVRChannelGroupInternal()
Unload();
}
-bool CPVRChannelGroupInternal::Load(
- const std::map<std::pair<int, int>, std::shared_ptr<CPVRChannel>>& channels)
+bool CPVRChannelGroupInternal::LoadFromDatabase(
+ const std::map<std::pair<int, int>, std::shared_ptr<CPVRChannel>>& channels,
+ const std::vector<std::shared_ptr<CPVRClient>>& clients)
{
- if (CPVRChannelGroup::Load(channels))
+ if (CPVRChannelGroup::LoadFromDatabase(channels, clients))
{
for (const auto& groupMember : m_members)
{
@@ -102,11 +103,13 @@ void CPVRChannelGroupInternal::UpdateChannelPaths()
}
}
-bool CPVRChannelGroupInternal::Update()
+bool CPVRChannelGroupInternal::UpdateFromClients(
+ const std::vector<std::shared_ptr<CPVRClient>>& clients)
{
- // get the channels from the backends
+ // get the channels from the given clients
std::vector<std::shared_ptr<CPVRChannel>> channels;
- CServiceBroker::GetPVRManager().Clients()->GetChannels(IsRadio(), channels, m_failedClients);
+ CServiceBroker::GetPVRManager().Clients()->GetChannels(clients, IsRadio(), channels,
+ m_failedClients);
// create group members for the channels
std::vector<std::shared_ptr<CPVRChannelGroupMember>> groupMembers;
diff --git a/xbmc/pvr/channels/PVRChannelGroupInternal.h b/xbmc/pvr/channels/PVRChannelGroupInternal.h
index 5511a6087e..5f8a06d9a7 100644
--- a/xbmc/pvr/channels/PVRChannelGroupInternal.h
+++ b/xbmc/pvr/channels/PVRChannelGroupInternal.h
@@ -82,17 +82,21 @@ namespace PVR
const std::vector<std::shared_ptr<CPVRChannelGroupMember>>& groupMembers) override;
/*!
- * @brief Refresh the channel list from the clients, sync with local data.
+ * @brief Update data with 'all channels' group members from the given clients, sync with local data.
+ * @param clients The clients to fetch data from. Leave empty to fetch data from all created clients.
* @return True on success, false otherwise.
*/
- bool Update() override;
+ bool UpdateFromClients(const std::vector<std::shared_ptr<CPVRClient>>& clients) override;
/*!
- * @brief Load the channels from the database, update and sync data from clients.
+ * @brief Load the channels from the database.
* @param channels All available channels.
+ * @param clients The PVR clients data should be loaded for. Leave empty for all clients.
* @return True when loaded successfully, false otherwise.
*/
- bool Load(const std::map<std::pair<int, int>, std::shared_ptr<CPVRChannel>>& channels) override;
+ bool LoadFromDatabase(
+ const std::map<std::pair<int, int>, std::shared_ptr<CPVRChannel>>& channels,
+ const std::vector<std::shared_ptr<CPVRClient>>& clients) override;
/*!
* @brief Clear all data.
diff --git a/xbmc/pvr/channels/PVRChannelGroups.cpp b/xbmc/pvr/channels/PVRChannelGroups.cpp
index dc0529e354..b8c97cf754 100644
--- a/xbmc/pvr/channels/PVRChannelGroups.cpp
+++ b/xbmc/pvr/channels/PVRChannelGroups.cpp
@@ -39,12 +39,15 @@ CPVRChannelGroups::CPVRChannelGroups(bool bRadio) :
CPVRChannelGroups::~CPVRChannelGroups()
{
- Clear();
+ Unload();
}
-void CPVRChannelGroups::Clear()
+void CPVRChannelGroups::Unload()
{
CSingleLock lock(m_critSection);
+ for (const auto& group : m_groups)
+ group->Unload();
+
m_groups.clear();
m_failedClientsForChannelGroups.clear();
}
@@ -195,7 +198,8 @@ bool CPVRChannelGroups::HasValidDataForAllClients() const
return m_failedClientsForChannelGroups.empty();
}
-bool CPVRChannelGroups::Update(bool bChannelsOnly /* = false */)
+bool CPVRChannelGroups::UpdateFromClients(const std::vector<std::shared_ptr<CPVRClient>>& clients,
+ bool bChannelsOnly /* = false */)
{
bool bSyncWithBackends = CServiceBroker::GetSettingsComponent()->GetSettings()->GetBool(
CSettings::SETTING_PVRMANAGER_SYNCCHANNELGROUPS);
@@ -207,7 +211,7 @@ bool CPVRChannelGroups::Update(bool bChannelsOnly /* = false */)
if (bUpdateAllGroups)
{
// get channel groups from the clients
- CServiceBroker::GetPVRManager().Clients()->GetChannelGroups(this,
+ CServiceBroker::GetPVRManager().Clients()->GetChannelGroups(clients, this,
m_failedClientsForChannelGroups);
CLog::LogFC(LOGDEBUG, LOGPVR, "{} new user defined {} channel groups fetched from clients",
(m_groups.size() - iSize), m_bRadio ? "radio" : "TV");
@@ -231,7 +235,7 @@ bool CPVRChannelGroups::Update(bool bChannelsOnly /* = false */)
if (bUpdateAllGroups || group->IsInternalGroup())
{
const int iMemberCount = group->Size();
- if (!group->Update())
+ if (!group->UpdateFromClients(clients))
{
CLog::LogFC(LOGERROR, LOGPVR, "Failed to update channel group '{}'", group->GroupName());
bReturn = false;
@@ -298,18 +302,29 @@ std::shared_ptr<CPVRChannelGroup> CPVRChannelGroups::CreateChannelGroup(
return std::make_shared<CPVRChannelGroup>(path, GetGroupAll());
}
-bool CPVRChannelGroups::LoadFromDb()
+bool CPVRChannelGroups::LoadFromDatabase(const std::vector<std::shared_ptr<CPVRClient>>& clients)
{
const std::shared_ptr<CPVRDatabase> database(CServiceBroker::GetPVRManager().GetTVDatabase());
if (!database)
return false;
+ CSingleLock lock(m_critSection);
+
+ // Ensure we have an internal group. It is important that the internal group is created before
+ // loading contents from database and that it gets inserted in front of m_groups. Look at
+ // GetGroupAll() implementation to see why.
+ if (m_groups.empty())
+ {
+ const auto internalGroup = std::make_shared<CPVRChannelGroupInternal>(m_bRadio);
+ m_groups.emplace_back(internalGroup);
+ }
+
CLog::LogFC(LOGDEBUG, LOGPVR, "Loading all {} channel groups and members",
m_bRadio ? "radio" : "TV");
// load all channels from the database
std::map<std::pair<int, int>, std::shared_ptr<CPVRChannel>> channels;
- database->Get(m_bRadio, channels);
+ database->Get(m_bRadio, clients, channels);
CLog::LogFC(LOGDEBUG, LOGPVR, "Fetched {} {} channels from the database", channels.size(),
m_bRadio ? "radio" : "TV");
@@ -321,41 +336,24 @@ bool CPVRChannelGroups::LoadFromDb()
// load all group members from the database
for (const auto& group : m_groups)
{
- if (!group->Load(channels))
+ if (!group->LoadFromDatabase(channels, clients))
{
- CLog::LogFC(LOGERROR, LOGPVR, "Failed to load {} channel group '{}'",
+ CLog::LogFC(LOGERROR, LOGPVR,
+ "Failed to load members of {} channel group '{}' from the database",
m_bRadio ? "radio" : "TV", group->GroupName());
}
}
- return true;
-}
-bool CPVRChannelGroups::Load()
-{
+ // Hide empty groups
+ for (auto it = m_groups.begin(); it != m_groups.end();)
{
- CSingleLock lock(m_critSection);
-
- // Remove previous contents
- Clear();
-
- // Ensure we have an internal group. It is important that the internal group is created before
- // loading contents from database and that it gets inserted in front of m_groups. Look at
- // GetGroupAll() implementation to see why.
- const auto internalGroup = std::make_shared<CPVRChannelGroupInternal>(m_bRadio);
- m_groups.emplace_back(internalGroup);
-
- // Load groups, group members and channels from database
- LoadFromDb();
+ if ((*it)->Size() == 0 && !(*it)->IsInternalGroup())
+ it = m_groups.erase(it);
+ else
+ ++it;
}
- // Load data from clients and sync with local data
- Update();
-
- CLog::LogFC(LOGDEBUG, LOGPVR, "{} {} channel groups loaded", m_groups.size(),
- m_bRadio ? "radio" : "TV");
-
- // need at least 1 group
- return m_groups.size() > 0;
+ return true;
}
bool CPVRChannelGroups::PersistAll()
diff --git a/xbmc/pvr/channels/PVRChannelGroups.h b/xbmc/pvr/channels/PVRChannelGroups.h
index f3367668c7..0e64ece1ca 100644
--- a/xbmc/pvr/channels/PVRChannelGroups.h
+++ b/xbmc/pvr/channels/PVRChannelGroups.h
@@ -19,6 +19,7 @@
namespace PVR
{
class CPVRChannel;
+ class CPVRClient;
/** A container class for channel groups */
@@ -33,15 +34,16 @@ namespace PVR
virtual ~CPVRChannelGroups();
/*!
- * @brief Remove all channels from this group.
+ * @brief Remove all groups from this container.
*/
- void Clear();
+ void Unload();
/*!
- * @brief Load this container's contents from the database or PVR clients.
- * @return True if it was loaded successfully, false if not.
+ * @brief Load all channel groups and all channels from PVR database.
+ * @param clients The PVR clients data should be loaded for. Leave empty for all clients.
+ * @return True on success, false otherwise.
*/
- bool Load();
+ bool LoadFromDatabase(const std::vector<std::shared_ptr<CPVRClient>>& clients);
/*!
* @brief Create a channel group matching the given type.
@@ -199,11 +201,13 @@ namespace PVR
bool IsRadio() const { return m_bRadio; }
/*!
- * @brief Update the contents of the groups in this container.
+ * @brief Update data with groups and channels from the given clients, sync with local data.
+ * @param clients The clients to fetch data from. Leave empty to fetch data from all created clients.
* @param bChannelsOnly Set to true to only update channels, not the groups themselves.
- * @return True if the update was successful, false otherwise.
+ * @return True on success, false otherwise.
*/
- bool Update(bool bChannelsOnly = false);
+ bool UpdateFromClients(const std::vector<std::shared_ptr<CPVRClient>>& clients,
+ bool bChannelsOnly = false);
/*!
* @brief Update the channel numbers across the channel groups from the all channels group
@@ -218,7 +222,6 @@ namespace PVR
int CleanupCachedImages();
private:
- bool LoadFromDb();
void SortGroups();
/*!
diff --git a/xbmc/pvr/channels/PVRChannelGroupsContainer.cpp b/xbmc/pvr/channels/PVRChannelGroupsContainer.cpp
index 19cdf51cd9..a8b65ddbe1 100644
--- a/xbmc/pvr/channels/PVRChannelGroupsContainer.cpp
+++ b/xbmc/pvr/channels/PVRChannelGroupsContainer.cpp
@@ -27,11 +27,24 @@ CPVRChannelGroupsContainer::CPVRChannelGroupsContainer() :
CPVRChannelGroupsContainer::~CPVRChannelGroupsContainer()
{
+ Unload();
delete m_groupsRadio;
delete m_groupsTV;
}
-bool CPVRChannelGroupsContainer::Update(bool bChannelsOnly /* = false */)
+bool CPVRChannelGroupsContainer::Update(const std::vector<std::shared_ptr<CPVRClient>>& clients)
+{
+ return LoadFromDatabase(clients) && UpdateFromClients(clients);
+}
+
+bool CPVRChannelGroupsContainer::LoadFromDatabase(
+ const std::vector<std::shared_ptr<CPVRClient>>& clients)
+{
+ return m_groupsTV->LoadFromDatabase(clients) && m_groupsRadio->LoadFromDatabase(clients);
+}
+
+bool CPVRChannelGroupsContainer::UpdateFromClients(
+ const std::vector<std::shared_ptr<CPVRClient>>& clients, bool bChannelsOnly /* = false */)
{
CSingleLock lock(m_critSection);
if (m_bIsUpdating)
@@ -40,7 +53,8 @@ bool CPVRChannelGroupsContainer::Update(bool bChannelsOnly /* = false */)
lock.Leave();
CLog::LogFC(LOGDEBUG, LOGPVR, "Updating {}", bChannelsOnly ? "channels" : "channel groups");
- bool bReturn = m_groupsTV->Update(bChannelsOnly) && m_groupsRadio->Update(bChannelsOnly);
+ bool bReturn = m_groupsTV->UpdateFromClients(clients, bChannelsOnly) &&
+ m_groupsRadio->UpdateFromClients(clients, bChannelsOnly);
lock.Enter();
m_bIsUpdating = false;
@@ -49,23 +63,10 @@ bool CPVRChannelGroupsContainer::Update(bool bChannelsOnly /* = false */)
return bReturn;
}
-bool CPVRChannelGroupsContainer::Load()
-{
- Unload();
- m_bLoaded = m_groupsTV->Load() && m_groupsRadio->Load();
- return m_bLoaded;
-}
-
-bool CPVRChannelGroupsContainer::Loaded() const
-{
- return m_bLoaded;
-}
-
void CPVRChannelGroupsContainer::Unload()
{
- m_groupsRadio->Clear();
- m_groupsTV->Clear();
- m_bLoaded = false;
+ m_groupsRadio->Unload();
+ m_groupsTV->Unload();
}
CPVRChannelGroups* CPVRChannelGroupsContainer::Get(bool bRadio) const
diff --git a/xbmc/pvr/channels/PVRChannelGroupsContainer.h b/xbmc/pvr/channels/PVRChannelGroupsContainer.h
index 3eefc7276d..d7b7f57835 100644
--- a/xbmc/pvr/channels/PVRChannelGroupsContainer.h
+++ b/xbmc/pvr/channels/PVRChannelGroupsContainer.h
@@ -11,6 +11,7 @@
#include "threads/CriticalSection.h"
#include <memory>
+#include <vector>
namespace PVR
{
@@ -18,6 +19,7 @@ namespace PVR
class CPVRChannelGroup;
class CPVRChannelGroupMember;
class CPVRChannelGroups;
+ class CPVRClient;
class CPVREpgInfoTag;
class CPVRChannelGroupsContainer
@@ -34,16 +36,20 @@ namespace PVR
virtual ~CPVRChannelGroupsContainer();
/*!
- * @brief Load all channel groups and all channels in those channel groups.
- * @return True if all groups were loaded, false otherwise.
+ * @brief Update all channel groups and all channels from PVR database and from given clients.
+ * @param clients The PVR clients data should be loaded for. Leave empty for all clients.
+ * @return True on success, false otherwise.
*/
- bool Load();
+ bool Update(const std::vector<std::shared_ptr<CPVRClient>>& clients);
/*!
- * @brief Checks whether groups were already loaded.
- * @return True if groups were successfully loaded, false otherwise.
+ * @brief Update data with groups and channels from the given clients, sync with local data.
+ * @param clients The clients to fetch data from. Leave empty to fetch data from all created clients.
+ * @param bChannelsOnly Set to true to only update channels, not the groups themselves.
+ * @return True on success, false otherwise.
*/
- bool Loaded() const;
+ bool UpdateFromClients(const std::vector<std::shared_ptr<CPVRClient>>& clients,
+ bool bChannelsOnly = false);
/*!
* @brief Unload and destruct all channel groups and all channels in them.
@@ -51,13 +57,6 @@ namespace PVR
void Unload();
/*!
- * @brief Update the contents of all the groups in this container.
- * @param bChannelsOnly Set to true to only update channels, not the groups themselves.
- * @return True if the update was successful, false otherwise.
- */
- bool Update(bool bChannelsOnly = false);
-
- /*!
* @brief Get the TV channel groups.
* @return The TV channel groups.
*/
@@ -161,10 +160,16 @@ namespace PVR
CPVRChannelGroupsContainer& operator=(const CPVRChannelGroupsContainer&) = delete;
CPVRChannelGroupsContainer(const CPVRChannelGroupsContainer&) = delete;
+ /*!
+ * @brief Load all channel groups and all channels from PVR database.
+ * @param clients The PVR clients data should be loaded for. Leave empty for all clients.
+ * @return True on success, false otherwise.
+ */
+ bool LoadFromDatabase(const std::vector<std::shared_ptr<CPVRClient>>& clients);
+
CPVRChannelGroups* m_groupsRadio; /*!< all radio channel groups */
CPVRChannelGroups* m_groupsTV; /*!< all TV channel groups */
CCriticalSection m_critSection;
bool m_bIsUpdating = false;
- bool m_bLoaded = false;
};
}
diff --git a/xbmc/pvr/dialogs/GUIDialogPVRChannelManager.cpp b/xbmc/pvr/dialogs/GUIDialogPVRChannelManager.cpp
index 7c8f9b364c..d92d049a7f 100644
--- a/xbmc/pvr/dialogs/GUIDialogPVRChannelManager.cpp
+++ b/xbmc/pvr/dialogs/GUIDialogPVRChannelManager.cpp
@@ -706,7 +706,7 @@ bool CGUIDialogPVRChannelManager::OnContextButton(int itemNumber, CONTEXT_BUTTON
CServiceBroker::GetPVRManager().ChannelGroups()->Get(m_bIsRadio);
if (groups)
{
- groups->Update();
+ groups->UpdateFromClients({});
Update();
}
}
@@ -754,10 +754,10 @@ void CGUIDialogPVRChannelManager::Update()
std::shared_ptr<CPVRChannelGroup> channels = CServiceBroker::GetPVRManager().ChannelGroups()->GetGroupAll(m_bIsRadio);
// No channels available, nothing to do.
- if(!channels)
+ if (!channels)
return;
- channels->Update();
+ channels->UpdateFromClients({});
const std::vector<std::shared_ptr<CPVRChannelGroupMember>> groupMembers = channels->GetMembers();
std::shared_ptr<CFileItem> channelFile;
diff --git a/xbmc/pvr/dialogs/GUIDialogPVRRecordingSettings.cpp b/xbmc/pvr/dialogs/GUIDialogPVRRecordingSettings.cpp
index 01904e66aa..7f3d7c3fd5 100644
--- a/xbmc/pvr/dialogs/GUIDialogPVRRecordingSettings.cpp
+++ b/xbmc/pvr/dialogs/GUIDialogPVRRecordingSettings.cpp
@@ -136,7 +136,7 @@ bool CGUIDialogPVRRecordingSettings::OnSettingChanging(
CVariant{19068}, // "Recording settings"
StringUtils::Format(g_localizeStrings.Get(19147),
iNewLifetime)) // "Setting the lifetime..."
- != HELPERS::DialogResponse::YES)
+ != HELPERS::DialogResponse::CHOICE_YES)
return false;
}
}
diff --git a/xbmc/pvr/epg/EpgContainer.cpp b/xbmc/pvr/epg/EpgContainer.cpp
index ef6bc2af19..9bb73d7315 100644
--- a/xbmc/pvr/epg/EpgContainer.cpp
+++ b/xbmc/pvr/epg/EpgContainer.cpp
@@ -236,7 +236,7 @@ void CPVREpgContainer::Notify(const PVREvent& event)
m_events.Publish(event);
}
-void CPVREpgContainer::LoadFromDB()
+void CPVREpgContainer::LoadFromDatabase()
{
CSingleLock lock(m_critSection);
@@ -564,7 +564,7 @@ std::shared_ptr<CPVREpg> CPVREpgContainer::CreateChannelEpg(int iEpgId, const st
std::shared_ptr<CPVREpg> epg;
WaitForUpdateFinish();
- LoadFromDB();
+ LoadFromDatabase();
if (iEpgId > 0)
epg = GetById(iEpgId);
@@ -736,7 +736,8 @@ bool CPVREpgContainer::UpdateEPG(bool bOnlyPending /* = false */)
CPVRGUIProgressHandler* progressHandler = nullptr;
if (bShowProgress && !bOnlyPending)
- progressHandler = new CPVRGUIProgressHandler(g_localizeStrings.Get(19004)); // Importing guide from clients
+ progressHandler =
+ new CPVRGUIProgressHandler(g_localizeStrings.Get(19004)); // Loading programme guide
/* load or update all EPG tables */
unsigned int iCounter = 0;
diff --git a/xbmc/pvr/epg/EpgContainer.h b/xbmc/pvr/epg/EpgContainer.h
index 90df6d3eb3..f4a3fed2d2 100644
--- a/xbmc/pvr/epg/EpgContainer.h
+++ b/xbmc/pvr/epg/EpgContainer.h
@@ -312,7 +312,7 @@ namespace PVR
/*!
* @brief Load all tables from the database
*/
- void LoadFromDB();
+ void LoadFromDatabase();
/*!
* @brief Insert data from database
diff --git a/xbmc/pvr/filesystem/PVRGUIDirectory.cpp b/xbmc/pvr/filesystem/PVRGUIDirectory.cpp
index 148c05afeb..5dabfde0db 100644
--- a/xbmc/pvr/filesystem/PVRGUIDirectory.cpp
+++ b/xbmc/pvr/filesystem/PVRGUIDirectory.cpp
@@ -200,8 +200,7 @@ bool CPVRGUIDirectory::GetDirectory(CFileItemList& results) const
}
else if (StringUtils::StartsWith(fileName, "channels"))
{
- if (CServiceBroker::GetPVRManager().ChannelGroups() &&
- CServiceBroker::GetPVRManager().ChannelGroups()->Loaded())
+ if (CServiceBroker::GetPVRManager().IsStarted())
{
return GetChannelsDirectory(results);
}
diff --git a/xbmc/pvr/guilib/GUIEPGGridContainer.cpp b/xbmc/pvr/guilib/GUIEPGGridContainer.cpp
index 78deab458d..6015883787 100644
--- a/xbmc/pvr/guilib/GUIEPGGridContainer.cpp
+++ b/xbmc/pvr/guilib/GUIEPGGridContainer.cpp
@@ -370,7 +370,7 @@ void CGUIEPGGridContainer::ProcessItem(float posX, float posY, const CFileItemPt
{
if (!item->GetFocusedLayout())
{
- item->SetFocusedLayout(CGUIListItemLayoutPtr(new CGUIListItemLayout(*focusedlayout)));
+ item->SetFocusedLayout(std::make_unique<CGUIListItemLayout>(*focusedlayout, this));
}
if (resize != -1.0f)
@@ -402,7 +402,7 @@ void CGUIEPGGridContainer::ProcessItem(float posX, float posY, const CFileItemPt
{
if (!item->GetLayout())
{
- item->SetLayout(CGUIListItemLayoutPtr(new CGUIListItemLayout(*normallayout)));
+ item->SetLayout(std::make_unique<CGUIListItemLayout>(*normallayout, this));
}
if (resize != -1.0f)
diff --git a/xbmc/pvr/guilib/PVRGUIActionListener.cpp b/xbmc/pvr/guilib/PVRGUIActionListener.cpp
index d6112c2515..374801b0cc 100644
--- a/xbmc/pvr/guilib/PVRGUIActionListener.cpp
+++ b/xbmc/pvr/guilib/PVRGUIActionListener.cpp
@@ -333,7 +333,7 @@ void CPVRGUIActionListener::OnSettingAction(const std::shared_ptr<const CSetting
if (dialog)
{
dialog->Open();
- CServiceBroker::GetPVRManager().ChannelGroups()->Update();
+ CServiceBroker::GetPVRManager().ChannelGroups()->UpdateFromClients({});
}
}
}
diff --git a/xbmc/pvr/guilib/PVRGUIActions.cpp b/xbmc/pvr/guilib/PVRGUIActions.cpp
index 321afd8ed5..3c6a9f6e04 100644
--- a/xbmc/pvr/guilib/PVRGUIActions.cpp
+++ b/xbmc/pvr/guilib/PVRGUIActions.cpp
@@ -950,9 +950,11 @@ namespace PVR
case TimerOperationResult::RECORDING:
{
// recording running. ask the user if it should be deleted anyway
- if (HELPERS::ShowYesNoDialogText(CVariant{122}, // "Confirm delete"
- CVariant{19122}) // "This timer is still recording. Are you sure you want to delete this timer?"
- != HELPERS::DialogResponse::YES)
+ if (HELPERS::ShowYesNoDialogText(
+ CVariant{122}, // "Confirm delete"
+ CVariant{
+ 19122}) // "This timer is still recording. Are you sure you want to delete this timer?"
+ != HELPERS::DialogResponse::CHOICE_YES)
return false;
return DeleteTimer(timer, true, bDeleteRule);
@@ -2168,12 +2170,12 @@ namespace PVR
}
// Inform user about PVR being busy. Ask if user wants to powerdown anyway.
- bReturn = HELPERS::ShowYesNoDialogText(CVariant{19685}, // "Confirm shutdown"
- CVariant{text},
- CVariant{222}, // "Shutdown anyway",
- CVariant{19696}, // "Cancel"
- 10000) // timeout value before closing
- == HELPERS::DialogResponse::YES;
+ bReturn =
+ HELPERS::ShowYesNoDialogText(CVariant{19685}, // "Confirm shutdown"
+ CVariant{text}, CVariant{222}, // "Shutdown anyway",
+ CVariant{19696}, // "Cancel"
+ 10000) // timeout value before closing
+ == HELPERS::DialogResponse::CHOICE_YES;
}
else
bReturn = false; // do not powerdown (busy, but no user interaction requested).
diff --git a/xbmc/pvr/guilib/PVRGUIProgressHandler.cpp b/xbmc/pvr/guilib/PVRGUIProgressHandler.cpp
index c03fac7a0d..2b2f8cc4ba 100644
--- a/xbmc/pvr/guilib/PVRGUIProgressHandler.cpp
+++ b/xbmc/pvr/guilib/PVRGUIProgressHandler.cpp
@@ -22,77 +22,82 @@ using namespace std::chrono_literals;
namespace PVR
{
- CPVRGUIProgressHandler::CPVRGUIProgressHandler(const std::string& strTitle)
- : CThread("PVRGUIProgressHandler"),
- m_strTitle(strTitle),
- m_fProgress(0.0f),
- m_bChanged(false)
+
+CPVRGUIProgressHandler::CPVRGUIProgressHandler(const std::string& strTitle)
+ : CThread("PVRGUIProgressHandler"), m_strTitle(strTitle)
+{
+}
+
+void CPVRGUIProgressHandler::UpdateProgress(const std::string& strText, float fProgress)
+{
+ CSingleLock lock(m_critSection);
+ m_bChanged = true;
+ m_strText = strText;
+ m_fProgress = fProgress;
+
+ if (!m_bCreated)
{
+ m_bCreated = true;
Create(true /* bAutoDelete */);
}
+}
- void CPVRGUIProgressHandler::UpdateProgress(const std::string& strText, float fProgress)
- {
- CSingleLock lock(m_critSection);
- m_bChanged = true;
- m_strText = strText;
- m_fProgress = fProgress;
- }
+void CPVRGUIProgressHandler::UpdateProgress(const std::string& strText, int iCurrent, int iMax)
+{
+ float fPercentage = (iCurrent * 100.0f) / iMax;
+ if (!std::isnan(fPercentage))
+ fPercentage = std::min(100.0f, fPercentage);
- void CPVRGUIProgressHandler::UpdateProgress(const std::string& strText, int iCurrent, int iMax)
- {
- float fPercentage = (iCurrent * 100.0f) / iMax;
- if (!std::isnan(fPercentage))
- fPercentage = std::min(100.0f, fPercentage);
+ UpdateProgress(strText, fPercentage);
+}
- UpdateProgress(strText, fPercentage);
- }
+void CPVRGUIProgressHandler::DestroyProgress()
+{
+ CSingleLock lock(m_critSection);
+ m_bStop = true;
+ m_bChanged = false;
+}
- void CPVRGUIProgressHandler::DestroyProgress()
- {
- CSingleLock lock(m_critSection);
- m_bStop = true;
- m_bChanged = false;
- }
+void CPVRGUIProgressHandler::Process()
+{
+ CGUIDialogExtendedProgressBar* progressBar =
+ CServiceBroker::GetGUI()->GetWindowManager().GetWindow<CGUIDialogExtendedProgressBar>(
+ WINDOW_DIALOG_EXT_PROGRESS);
+ if (m_bStop || !progressBar)
+ return;
- void CPVRGUIProgressHandler::Process()
- {
- CGUIDialogExtendedProgressBar* progressBar = CServiceBroker::GetGUI()->GetWindowManager().GetWindow<CGUIDialogExtendedProgressBar>(WINDOW_DIALOG_EXT_PROGRESS);
- if (m_bStop || !progressBar)
- return;
+ CGUIDialogProgressBarHandle* progressHandle = progressBar->GetHandle(m_strTitle);
+ if (!progressHandle)
+ return;
- CGUIDialogProgressBarHandle* progressHandle = progressBar->GetHandle(m_strTitle);
- if (!progressHandle)
- return;
+ while (!m_bStop)
+ {
+ float fProgress = 0.0;
+ std::string strText;
+ bool bUpdate = false;
- while (!m_bStop)
{
- float fProgress = 0.0;
- std::string strText;
- bool bUpdate = false;
-
+ CSingleLock lock(m_critSection);
+ if (m_bChanged)
{
- CSingleLock lock(m_critSection);
- if (m_bChanged)
- {
- m_bChanged = false;
- fProgress = m_fProgress;
- strText = m_strText;
- bUpdate = true;
- }
- }
-
- if (bUpdate)
- {
- progressHandle->SetPercentage(fProgress);
- progressHandle->SetText(strText);
+ m_bChanged = false;
+ fProgress = m_fProgress;
+ strText = m_strText;
+ bUpdate = true;
}
+ }
- // Intentionally ignore some changes that come in too fast. Humans cannot read as fast as Mr. Data ;-)
- CThread::Sleep(100ms);
+ if (bUpdate)
+ {
+ progressHandle->SetPercentage(fProgress);
+ progressHandle->SetText(strText);
}
- progressHandle->MarkFinished();
+ // Intentionally ignore some changes that come in too fast. Humans cannot read as fast as Mr. Data ;-)
+ CThread::Sleep(100ms);
}
+ progressHandle->MarkFinished();
+}
+
} // namespace PVR
diff --git a/xbmc/pvr/guilib/PVRGUIProgressHandler.h b/xbmc/pvr/guilib/PVRGUIProgressHandler.h
index 7660edb77f..b82534328b 100644
--- a/xbmc/pvr/guilib/PVRGUIProgressHandler.h
+++ b/xbmc/pvr/guilib/PVRGUIProgressHandler.h
@@ -55,8 +55,9 @@ namespace PVR
CCriticalSection m_critSection;
const std::string m_strTitle;
std::string m_strText;
- float m_fProgress;
- bool m_bChanged;
+ float m_fProgress{0.0f};
+ bool m_bChanged{false};
+ bool m_bCreated{false};
};
} // namespace PVR
diff --git a/xbmc/pvr/providers/PVRProviders.cpp b/xbmc/pvr/providers/PVRProviders.cpp
index a65ce7fc2c..53f9ec2f88 100644
--- a/xbmc/pvr/providers/PVRProviders.cpp
+++ b/xbmc/pvr/providers/PVRProviders.cpp
@@ -90,18 +90,9 @@ std::size_t CPVRProvidersContainer::GetNumProviders() const
return m_providers.size();
}
-bool CPVRProviders::Load()
+bool CPVRProviders::Update(const std::vector<std::shared_ptr<CPVRClient>>& clients)
{
- // unload previous providers
- Unload();
-
- // load providers from database
- bool bReturn = LoadFromDatabase();
-
- // update from clients
- Update();
-
- return bReturn;
+ return LoadFromDatabase(clients) && UpdateFromClients(clients);
}
void CPVRProviders::Unload()
@@ -111,7 +102,7 @@ void CPVRProviders::Unload()
m_providers.clear();
}
-bool CPVRProviders::LoadFromDatabase()
+bool CPVRProviders::LoadFromDatabase(const std::vector<std::shared_ptr<CPVRClient>>& clients)
{
const std::shared_ptr<CPVRDatabase> database = CServiceBroker::GetPVRManager().GetTVDatabase();
if (database)
@@ -119,7 +110,7 @@ bool CPVRProviders::LoadFromDatabase()
bool bChanged = false;
CPVRProviders providers;
- database->Get(providers);
+ database->Get(providers, clients);
for (auto& provider : providers.GetProvidersList())
{
@@ -129,7 +120,7 @@ bool CPVRProviders::LoadFromDatabase()
return true;
}
-bool CPVRProviders::Update()
+bool CPVRProviders::UpdateFromClients(const std::vector<std::shared_ptr<CPVRClient>>& clients)
{
{
CSingleLock lock(m_critSection);
@@ -163,7 +154,7 @@ bool CPVRProviders::Update()
CLog::LogFC(LOGDEBUG, LOGPVR, "Updating providers");
CPVRProvidersContainer newProviderList;
std::vector<int> failedClients;
- CServiceBroker::GetPVRManager().Clients()->GetProviders(&newProviderList, failedClients);
+ CServiceBroker::GetPVRManager().Clients()->GetProviders(clients, &newProviderList, failedClients);
return UpdateClientEntries(newProviderList, failedClients, disabledClients);
}
@@ -220,14 +211,12 @@ bool CPVRProviders::UpdateClientEntries(const CPVRProvidersContainer& newProvide
const std::vector<int>& failedClients,
const std::vector<int>& disabledClients)
{
- bool bChanged = false;
-
CSingleLock lock(m_critSection);
// go through the provider list and check for updated or new providers
for (const auto& newProvider : newProviders.GetProvidersList())
{
- bChanged |= (CheckAndPersistEntry(newProvider, ProviderUpdateMode::BY_CLIENT) != nullptr);
+ CheckAndPersistEntry(newProvider, ProviderUpdateMode::BY_CLIENT);
}
// check for deleted providers
@@ -271,8 +260,6 @@ bool CPVRProviders::UpdateClientEntries(const CPVRProvidersContainer& newProvide
(*it)->DeleteFromDatabase();
it = m_providers.erase(it);
-
- bChanged = true;
}
else
{
@@ -282,7 +269,7 @@ bool CPVRProviders::UpdateClientEntries(const CPVRProvidersContainer& newProvide
m_bIsUpdating = false;
- return bChanged;
+ return true;
}
std::shared_ptr<CPVRProvider> CPVRProviders::CheckAndAddEntry(
diff --git a/xbmc/pvr/providers/PVRProviders.h b/xbmc/pvr/providers/PVRProviders.h
index acb4b11737..8196d3b6d2 100644
--- a/xbmc/pvr/providers/PVRProviders.h
+++ b/xbmc/pvr/providers/PVRProviders.h
@@ -15,6 +15,7 @@
namespace PVR
{
+class CPVRClient;
class CPVRProvider;
enum class ProviderUpdateMode;
@@ -64,10 +65,11 @@ public:
~CPVRProviders() = default;
/**
- * @brief (re)load the providers from the clients.
- * @return True if loaded successfully, false otherwise.
+ * @brief Update all providers from PVR database and from given clients.
+ * @param clients The PVR clients data should be loaded for. Leave empty for all clients.
+ * @return True on success, false otherwise.
*/
- bool Load();
+ bool Update(const std::vector<std::shared_ptr<CPVRClient>>& clients);
/**
* @brief unload all providers.
@@ -75,15 +77,18 @@ public:
void Unload();
/**
- * @brief refresh the providers list from the clients.
+ * @brief Update data with providers from the given clients, sync with local data.
+ * @param clients The clients to fetch data from. Leave empty to fetch data from all created clients.
+ * @return True on success, false otherwise.
*/
- bool Update();
+ bool UpdateFromClients(const std::vector<std::shared_ptr<CPVRClient>>& clients);
/**
- * @brief load the local providers from database.
- * @return True if loaded successfully, false otherwise.
+ * @brief Load all local providers from PVR database.
+ * @param clients The PVR clients data should be loaded for. Leave empty for all clients.
+ * @return True on success, false otherwise.
*/
- bool LoadFromDatabase();
+ bool LoadFromDatabase(const std::vector<std::shared_ptr<CPVRClient>>& clients);
/*!
* @brief Check if the entry exists in the container, if it does update it otherwise add it
diff --git a/xbmc/pvr/recordings/PVRRecordings.cpp b/xbmc/pvr/recordings/PVRRecordings.cpp
index f4c3b4c98c..ad0b74c397 100644
--- a/xbmc/pvr/recordings/PVRRecordings.cpp
+++ b/xbmc/pvr/recordings/PVRRecordings.cpp
@@ -34,16 +34,21 @@ CPVRRecordings::~CPVRRecordings()
m_database->Close();
}
-void CPVRRecordings::UpdateFromClients()
+bool CPVRRecordings::UpdateFromClients(const std::vector<std::shared_ptr<CPVRClient>>& clients)
{
CSingleLock lock(m_critSection);
+ if (m_bIsUpdating)
+ return false;
+
+ m_bIsUpdating = true;
+
for (const auto& recording : m_recordings)
recording.second->SetDirty(true);
std::vector<int> failedClients;
- CServiceBroker::GetPVRManager().Clients()->GetRecordings(this, false, failedClients);
- CServiceBroker::GetPVRManager().Clients()->GetRecordings(this, true, failedClients);
+ CServiceBroker::GetPVRManager().Clients()->GetRecordings(clients, this, false, failedClients);
+ CServiceBroker::GetPVRManager().Clients()->GetRecordings(clients, this, true, failedClients);
// remove recordings that were deleted at the backend
for (auto it = m_recordings.begin(); it != m_recordings.end();)
@@ -54,13 +59,15 @@ void CPVRRecordings::UpdateFromClients()
else
++it;
}
+
+ m_bIsUpdating = false;
+ CServiceBroker::GetPVRManager().PublishEvent(PVREvent::RecordingsInvalidated);
+ return true;
}
-int CPVRRecordings::Load()
+bool CPVRRecordings::Update(const std::vector<std::shared_ptr<CPVRClient>>& clients)
{
- Unload();
- Update();
- return m_recordings.size();
+ return UpdateFromClients(clients);
}
void CPVRRecordings::Unload()
@@ -73,24 +80,6 @@ void CPVRRecordings::Unload()
m_recordings.clear();
}
-void CPVRRecordings::Update()
-{
- CSingleLock lock(m_critSection);
- if (m_bIsUpdating)
- return;
- m_bIsUpdating = true;
- lock.Leave();
-
- CLog::LogFC(LOGDEBUG, LOGPVR, "Updating recordings");
- UpdateFromClients();
-
- lock.Enter();
- m_bIsUpdating = false;
- lock.Leave();
-
- CServiceBroker::GetPVRManager().PublishEvent(PVREvent::RecordingsInvalidated);
-}
-
void CPVRRecordings::UpdateInProgressSize()
{
CSingleLock lock(m_critSection);
diff --git a/xbmc/pvr/recordings/PVRRecordings.h b/xbmc/pvr/recordings/PVRRecordings.h
index a592687a92..6ddea0fe69 100644
--- a/xbmc/pvr/recordings/PVRRecordings.h
+++ b/xbmc/pvr/recordings/PVRRecordings.h
@@ -32,10 +32,11 @@ namespace PVR
virtual ~CPVRRecordings();
/*!
- * @brief (re)load the recordings from the clients.
- * @return the number of recordings loaded.
+ * @brief Update all recordings from the given PVR clients.
+ * @param clients The PVR clients data should be loaded for. Leave empty for all clients.
+ * @return True on success, false otherwise.
*/
- int Load();
+ bool Update(const std::vector<std::shared_ptr<CPVRClient>>& clients);
/*!
* @brief unload all recordings.
@@ -43,6 +44,13 @@ namespace PVR
void Unload();
/*!
+ * @brief Update data with recordings from the given clients, sync with local data.
+ * @param clients The clients to fetch data from. Leave empty to fetch data from all created clients.
+ * @return True on success, false otherwise.
+ */
+ bool UpdateFromClients(const std::vector<std::shared_ptr<CPVRClient>>& clients);
+
+ /*!
* @brief client has delivered a new/updated recording.
* @param tag The recording
* @param client The client the recording belongs to.
@@ -50,11 +58,6 @@ namespace PVR
void UpdateFromClient(const std::shared_ptr<CPVRRecording>& tag, const CPVRClient& client);
/*!
- * @brief refresh the recordings list from the clients.
- */
- void Update();
-
- /*!
* @brief refresh the size of any in progress recordings from the clients.
*/
void UpdateInProgressSize();
@@ -113,8 +116,6 @@ namespace PVR
unsigned int m_iTVRecordings = 0;
unsigned int m_iRadioRecordings = 0;
- void UpdateFromClients();
-
/*!
* @brief Get/Open the video database.
* @return A reference to the video database.
diff --git a/xbmc/pvr/timers/PVRTimers.cpp b/xbmc/pvr/timers/PVRTimers.cpp
index 3b906454d4..b1c5ed7af9 100644
--- a/xbmc/pvr/timers/PVRTimers.cpp
+++ b/xbmc/pvr/timers/PVRTimers.cpp
@@ -99,18 +99,30 @@ CPVRTimers::CPVRTimers()
{
}
-bool CPVRTimers::Load()
+bool CPVRTimers::Update(const std::vector<std::shared_ptr<CPVRClient>>& clients)
{
- // unload previous timers
- Unload();
+ return LoadFromDatabase(clients) && UpdateFromClients(clients);
+}
+bool CPVRTimers::LoadFromDatabase(const std::vector<std::shared_ptr<CPVRClient>>& clients)
+{
// load local timers from database
- bool bReturn = LoadFromDatabase();
+ const std::shared_ptr<CPVRDatabase> database = CServiceBroker::GetPVRManager().GetTVDatabase();
+ if (database)
+ {
+ bool bChanged = false;
- // update from clients
- Update();
+ const std::vector<std::shared_ptr<CPVRTimerInfoTag>> timers =
+ database->GetTimers(*this, clients);
+ for (const auto& timer : timers)
+ {
+ bChanged |= !!UpdateEntry(timer);
+ }
- return bReturn;
+ if (bChanged)
+ NotifyTimersEvent();
+ }
+ return true;
}
void CPVRTimers::Unload()
@@ -134,7 +146,7 @@ void CPVRTimers::Stop()
CServiceBroker::GetPVRManager().Events().Unsubscribe(this);
}
-bool CPVRTimers::Update()
+bool CPVRTimers::UpdateFromClients(const std::vector<std::shared_ptr<CPVRClient>>& clients)
{
{
CSingleLock lock(m_critSection);
@@ -146,29 +158,10 @@ bool CPVRTimers::Update()
CLog::LogFC(LOGDEBUG, LOGPVR, "Updating timers");
CPVRTimersContainer newTimerList;
std::vector<int> failedClients;
- CServiceBroker::GetPVRManager().Clients()->GetTimers(&newTimerList, failedClients);
+ CServiceBroker::GetPVRManager().Clients()->GetTimers(clients, &newTimerList, failedClients);
return UpdateEntries(newTimerList, failedClients);
}
-bool CPVRTimers::LoadFromDatabase()
-{
- const std::shared_ptr<CPVRDatabase> database = CServiceBroker::GetPVRManager().GetTVDatabase();
- if (database)
- {
- bool bChanged = false;
-
- const std::vector<std::shared_ptr<CPVRTimerInfoTag>> timers = database->GetTimers(*this);
- for (const auto& timer : timers)
- {
- bChanged |= !!UpdateEntry(timer);
- }
-
- if (bChanged)
- NotifyTimersEvent();
- }
- return true;
-}
-
void CPVRTimers::Process()
{
while (!m_bStop)
@@ -404,7 +397,7 @@ bool CPVRTimers::UpdateEntries(const CPVRTimersContainer& timers, const std::vec
}
}
- return bChanged;
+ return true;
}
namespace
diff --git a/xbmc/pvr/timers/PVRTimers.h b/xbmc/pvr/timers/PVRTimers.h
index 9a937070f0..c052379d29 100644
--- a/xbmc/pvr/timers/PVRTimers.h
+++ b/xbmc/pvr/timers/PVRTimers.h
@@ -23,6 +23,7 @@ namespace PVR
enum class PVREvent;
class CPVRChannel;
+ class CPVRClient;
class CPVREpgInfoTag;
class CPVRTimerInfoTag;
class CPVRTimersPath;
@@ -68,37 +69,34 @@ namespace PVR
CPVRTimers();
~CPVRTimers() override = default;
- /**
+ /*!
* @brief start the timer update thread.
*/
void Start();
- /**
+ /*!
* @brief stop the timer update thread.
*/
void Stop();
- /**
- * @brief (re)load the timers from the clients.
- * @return True if loaded successfully, false otherwise.
+ /*!
+ * @brief Update all timers from PVR database and from given clients.
+ * @param clients The PVR clients data should be loaded for. Leave empty for all clients.
+ * @return True on success, false otherwise.
*/
- bool Load();
+ bool Update(const std::vector<std::shared_ptr<CPVRClient>>& clients);
- /**
+ /*!
* @brief unload all timers.
*/
void Unload();
- /**
- * @brief refresh the timer list from the clients.
- */
- bool Update();
-
- /**
- * @brief load the local timers from database.
- * @return True if loaded successfully, false otherwise.
+ /*!
+ * @brief Update data with recordings from the given clients, sync with local data.
+ * @param clients The clients to fetch data from. Leave empty to fetch data from all created clients.
+ * @return True on success, false otherwise.
*/
- bool LoadFromDatabase();
+ bool UpdateFromClients(const std::vector<std::shared_ptr<CPVRClient>>& clients);
/*!
* @param bIgnoreReminders include or ignore reminders
@@ -269,6 +267,13 @@ namespace PVR
private:
void Process() override;
+ /*!
+ * @brief Load all timers from PVR database.
+ * @param clients The PVR clients data should be loaded for. Leave empty for all clients.
+ * @return True on success, false otherwise.
+ */
+ bool LoadFromDatabase(const std::vector<std::shared_ptr<CPVRClient>>& clients);
+
void RemoveEntry(const std::shared_ptr<CPVRTimerInfoTag>& tag);
bool UpdateEntries(const CPVRTimersContainer& timers, const std::vector<int>& failedClients);
bool UpdateEntries(int iMaxNotificationDelay);
diff --git a/xbmc/pvr/windows/GUIWindowPVRGuide.cpp b/xbmc/pvr/windows/GUIWindowPVRGuide.cpp
index 728ee88df2..bbac6396cf 100644
--- a/xbmc/pvr/windows/GUIWindowPVRGuide.cpp
+++ b/xbmc/pvr/windows/GUIWindowPVRGuide.cpp
@@ -486,9 +486,9 @@ bool CGUIWindowPVRGuideBase::OnMessage(CGUIMessage& message)
HELPERS::ShowYesNoDialogText(CVariant{19096}, // "Smart select"
CVariant{iTextID}, CVariant{iNoButtonID},
CVariant{19165}); // Yes => "Switch"
- if (ret == HELPERS::DialogResponse::NO)
+ if (ret == HELPERS::DialogResponse::CHOICE_NO)
CServiceBroker::GetPVRManager().GUIActions()->AddTimer(pItem, false);
- else if (ret == HELPERS::DialogResponse::YES)
+ else if (ret == HELPERS::DialogResponse::CHOICE_YES)
CServiceBroker::GetPVRManager().GUIActions()->SwitchToChannel(pItem, true);
}
}
diff --git a/xbmc/rendering/dx/DeviceResources.cpp b/xbmc/rendering/dx/DeviceResources.cpp
index b58a1e6df3..4993b9344b 100644
--- a/xbmc/rendering/dx/DeviceResources.cpp
+++ b/xbmc/rendering/dx/DeviceResources.cpp
@@ -432,6 +432,8 @@ void DX::DeviceResources::CreateDeviceResources()
KODI::PLATFORM::WINDOWS::FromW(aDesc.Description),
GetFeatureLevelDescription(m_d3dFeatureLevel));
+ CheckDXVA2SharedDecoderSurfaces();
+
m_bDeviceCreated = true;
}
@@ -1096,6 +1098,45 @@ void DX::DeviceResources::CheckNV12SharedTexturesSupport()
m_NV12SharedTexturesSupport ? " " : " NOT ");
}
+void DX::DeviceResources::CheckDXVA2SharedDecoderSurfaces()
+{
+ if (CSysInfo::GetWindowsDeviceFamily() != CSysInfo::Desktop)
+ return;
+
+ VideoDriverInfo driver = GetVideoDriverVersion();
+
+ if (!m_NV12SharedTexturesSupport)
+ return;
+
+ DXGI_ADAPTER_DESC ad = {};
+ GetAdapterDesc(&ad);
+
+ m_DXVA2SharedDecoderSurfaces =
+ ad.VendorId == PCIV_Intel ||
+ (ad.VendorId == PCIV_NVIDIA && driver.valid && driver.majorVersion >= 465) ||
+ (ad.VendorId == PCIV_AMD && driver.valid && driver.majorVersion >= 30);
+
+ CLog::LogF(LOGINFO, "DXVA2 shared decoder surfaces is{}supported",
+ m_DXVA2SharedDecoderSurfaces ? " " : " NOT ");
+}
+
+VideoDriverInfo DX::DeviceResources::GetVideoDriverVersion()
+{
+ DXGI_ADAPTER_DESC ad = {};
+ GetAdapterDesc(&ad);
+
+ VideoDriverInfo driver = CWIN32Util::GetVideoDriverInfo(ad.VendorId, ad.Description);
+
+ if (ad.VendorId == PCIV_NVIDIA)
+ CLog::LogF(LOGINFO, "video driver version is {} {}.{} ({})", GetGFXProviderName(ad.VendorId),
+ driver.majorVersion, driver.minorVersion, driver.version);
+ else
+ CLog::LogF(LOGINFO, "video driver version is {} {}", GetGFXProviderName(ad.VendorId),
+ driver.version);
+
+ return driver;
+}
+
#if defined(TARGET_WINDOWS_DESKTOP)
// This method is called when the window (WND) is created (or re-created).
void DX::DeviceResources::SetWindow(HWND window)
diff --git a/xbmc/rendering/dx/DeviceResources.h b/xbmc/rendering/dx/DeviceResources.h
index 33c93b1462..d45890264f 100644
--- a/xbmc/rendering/dx/DeviceResources.h
+++ b/xbmc/rendering/dx/DeviceResources.h
@@ -22,6 +22,7 @@
struct RESOLUTION_INFO;
struct DEBUG_INFO_RENDER;
+struct VideoDriverInfo;
namespace DX
{
@@ -112,6 +113,7 @@ namespace DX
void SetWindowPos(winrt::Windows::Foundation::Rect rect);
#endif // TARGET_WINDOWS_STORE
bool IsNV12SharedTexturesSupported() const { return m_NV12SharedTexturesSupport; }
+ bool IsDXVA2SharedDecoderSurfaces() const { return m_DXVA2SharedDecoderSurfaces; }
// Gets debug info from swapchain
DEBUG_INFO_RENDER GetDebugInfo() const;
@@ -136,6 +138,8 @@ namespace DX
void HandleOutputChange(const std::function<bool(DXGI_OUTPUT_DESC)>& cmpFunc);
bool CreateFactory();
void CheckNV12SharedTexturesSupport();
+ VideoDriverInfo GetVideoDriverVersion();
+ void CheckDXVA2SharedDecoderSurfaces();
HWND m_window{ nullptr };
#if defined(TARGET_WINDOWS_STORE)
@@ -178,5 +182,6 @@ namespace DX
bool m_IsHDROutput;
bool m_IsTransferPQ;
bool m_NV12SharedTexturesSupport{false};
+ bool m_DXVA2SharedDecoderSurfaces{false};
};
}
diff --git a/xbmc/rendering/dx/DirectXHelper.h b/xbmc/rendering/dx/DirectXHelper.h
index 1133b6b024..bb51ca6fd7 100644
--- a/xbmc/rendering/dx/DirectXHelper.h
+++ b/xbmc/rendering/dx/DirectXHelper.h
@@ -16,6 +16,13 @@
#include <d3d11_4.h>
#include <ppltasks.h> // For create_task
+enum PCI_Vendors
+{
+ PCIV_AMD = 0x1002,
+ PCIV_NVIDIA = 0x10DE,
+ PCIV_Intel = 0x8086,
+};
+
namespace DX
{
#define RATIONAL_TO_FLOAT(rational) ((rational.Denominator != 0) ? \
@@ -94,6 +101,25 @@ namespace DX
return StringUtils::Format("D3D_FEATURE_LEVEL_{}_{}", fl_major, fl_minor);
}
+ inline std::string GetGFXProviderName(UINT vendorId)
+ {
+ std::string name;
+ switch (vendorId)
+ {
+ case PCIV_AMD:
+ name = "AMD";
+ break;
+ case PCIV_Intel:
+ name = "Intel";
+ break;
+ case PCIV_NVIDIA:
+ name = "NVIDIA";
+ break;
+ }
+
+ return name;
+ }
+
template <typename T> struct SizeGen
{
SizeGen<T>() { Width = Height = 0; }
diff --git a/xbmc/rendering/dx/RenderSystemDX.h b/xbmc/rendering/dx/RenderSystemDX.h
index 0889fe096c..9a18e22045 100644
--- a/xbmc/rendering/dx/RenderSystemDX.h
+++ b/xbmc/rendering/dx/RenderSystemDX.h
@@ -17,13 +17,6 @@
#include <wrl/client.h>
-enum PCI_Vendors
-{
- PCIV_ATI = 0x1002,
- PCIV_nVidia = 0x10DE,
- PCIV_Intel = 0x8086
-};
-
class ID3DResource;
class CGUIShaderDX;
enum AVPixelFormat;
diff --git a/xbmc/settings/DisplaySettings.cpp b/xbmc/settings/DisplaySettings.cpp
index 407a3e126a..c6e816c550 100644
--- a/xbmc/settings/DisplaySettings.cpp
+++ b/xbmc/settings/DisplaySettings.cpp
@@ -290,8 +290,8 @@ bool CDisplaySettings::OnSettingChanging(const std::shared_ptr<const CSetting>&
{
if (!m_resolutionChangeAborted)
{
- if (HELPERS::ShowYesNoDialogText(CVariant{13110}, CVariant{13111}, CVariant{""}, CVariant{""}, 15000) !=
- DialogResponse::YES)
+ if (HELPERS::ShowYesNoDialogText(CVariant{13110}, CVariant{13111}, CVariant{""},
+ CVariant{""}, 15000) != DialogResponse::CHOICE_YES)
{
m_resolutionChangeAborted = true;
return false;
@@ -311,8 +311,8 @@ bool CDisplaySettings::OnSettingChanging(const std::shared_ptr<const CSetting>&
if (!m_resolutionChangeAborted)
{
- if (HELPERS::ShowYesNoDialogText(CVariant{13110}, CVariant{13111}, CVariant{""}, CVariant{""}, 10000) !=
- DialogResponse::YES)
+ if (HELPERS::ShowYesNoDialogText(CVariant{13110}, CVariant{13111}, CVariant{""}, CVariant{""},
+ 10000) != DialogResponse::CHOICE_YES)
{
m_resolutionChangeAborted = true;
return false;
diff --git a/xbmc/settings/MediaSettings.cpp b/xbmc/settings/MediaSettings.cpp
index f4af55a0ce..bc090ffb18 100644
--- a/xbmc/settings/MediaSettings.cpp
+++ b/xbmc/settings/MediaSettings.cpp
@@ -301,7 +301,7 @@ void CMediaSettings::OnSettingAction(const std::shared_ptr<const CSetting>& sett
const std::string &settingId = setting->GetId();
if (settingId == CSettings::SETTING_MUSICLIBRARY_CLEANUP)
{
- if (HELPERS::ShowYesNoDialogText(CVariant{313}, CVariant{333}) == DialogResponse::YES)
+ if (HELPERS::ShowYesNoDialogText(CVariant{313}, CVariant{333}) == DialogResponse::CHOICE_YES)
{
if (!CMusicLibraryQueue::GetInstance().IsRunning())
CMusicLibraryQueue::GetInstance().CleanLibrary(true);
@@ -332,7 +332,7 @@ void CMediaSettings::OnSettingAction(const std::shared_ptr<const CSetting>& sett
}
else if (settingId == CSettings::SETTING_VIDEOLIBRARY_CLEANUP)
{
- if (HELPERS::ShowYesNoDialogText(CVariant{313}, CVariant{333}) == DialogResponse::YES)
+ if (HELPERS::ShowYesNoDialogText(CVariant{313}, CVariant{333}) == DialogResponse::CHOICE_YES)
{
if (!CVideoLibraryQueue::GetInstance().IsRunning())
CVideoLibraryQueue::GetInstance().CleanLibraryModal();
diff --git a/xbmc/settings/SettingConditions.cpp b/xbmc/settings/SettingConditions.cpp
index 048f269c17..8f5ec6a824 100644
--- a/xbmc/settings/SettingConditions.cpp
+++ b/xbmc/settings/SettingConditions.cpp
@@ -41,8 +41,9 @@ bool AddonHasSettings(const std::string& condition,
return false;
ADDON::AddonPtr addon;
- if (!CServiceBroker::GetAddonMgr().GetAddon(
- settingAddon->GetValue(), addon, settingAddon->GetAddonType(), ADDON::OnlyEnabled::YES) ||
+ if (!CServiceBroker::GetAddonMgr().GetAddon(settingAddon->GetValue(), addon,
+ settingAddon->GetAddonType(),
+ ADDON::OnlyEnabled::CHOICE_YES) ||
addon == NULL)
return false;
diff --git a/xbmc/settings/dialogs/GUIDialogContentSettings.cpp b/xbmc/settings/dialogs/GUIDialogContentSettings.cpp
index fb4e6e689e..8d0061d2ef 100644
--- a/xbmc/settings/dialogs/GUIDialogContentSettings.cpp
+++ b/xbmc/settings/dialogs/GUIDialogContentSettings.cpp
@@ -248,8 +248,8 @@ void CGUIDialogContentSettings::OnSettingAction(const std::shared_ptr<const CSet
&& selectedAddonId != currentScraperId)
{
AddonPtr scraperAddon;
- if (CServiceBroker::GetAddonMgr().GetAddon(selectedAddonId, scraperAddon,
- ADDON::ADDON_UNKNOWN, ADDON::OnlyEnabled::YES))
+ if (CServiceBroker::GetAddonMgr().GetAddon(
+ selectedAddonId, scraperAddon, ADDON::ADDON_UNKNOWN, ADDON::OnlyEnabled::CHOICE_YES))
{
m_scraper = std::dynamic_pointer_cast<CScraper>(scraperAddon);
SetupView();
diff --git a/xbmc/settings/dialogs/GUIDialogLibExportSettings.cpp b/xbmc/settings/dialogs/GUIDialogLibExportSettings.cpp
index 9c3a2c585a..7e88553af9 100644
--- a/xbmc/settings/dialogs/GUIDialogLibExportSettings.cpp
+++ b/xbmc/settings/dialogs/GUIDialogLibExportSettings.cpp
@@ -211,7 +211,7 @@ void CGUIDialogLibExportSettings::OnOK()
{
//"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::YES)
+ if (HELPERS::ShowYesNoDialogText(20223, 38317, 186, 10004) == DialogResponse::CHOICE_YES)
{
m_confirmed = false;
Close();
diff --git a/xbmc/settings/windows/GUIControlSettings.cpp b/xbmc/settings/windows/GUIControlSettings.cpp
index a4f77c13d1..12aced38e7 100644
--- a/xbmc/settings/windows/GUIControlSettings.cpp
+++ b/xbmc/settings/windows/GUIControlSettings.cpp
@@ -1089,7 +1089,7 @@ void CGUIControlButtonSetting::Update(bool fromControl, bool updateDisplayOnly)
{
ADDON::AddonPtr addon;
if (CServiceBroker::GetAddonMgr().GetAddon(addonID, addon, ADDON::ADDON_UNKNOWN,
- ADDON::OnlyEnabled::YES))
+ ADDON::OnlyEnabled::CHOICE_YES))
addonNames.push_back(addon->Name());
}
diff --git a/xbmc/utils/RssManager.cpp b/xbmc/utils/RssManager.cpp
index 765d8f9058..099347f436 100644
--- a/xbmc/utils/RssManager.cpp
+++ b/xbmc/utils/RssManager.cpp
@@ -66,10 +66,10 @@ void CRssManager::OnSettingAction(const std::shared_ptr<const CSetting>& setting
{
ADDON::AddonPtr addon;
if (!CServiceBroker::GetAddonMgr().GetAddon("script.rss.editor", addon, ADDON::ADDON_UNKNOWN,
- ADDON::OnlyEnabled::YES))
+ ADDON::OnlyEnabled::CHOICE_YES))
{
- if (!ADDON::CAddonInstaller::GetInstance().InstallModal("script.rss.editor", addon,
- ADDON::InstallModalPrompt::PROMPT))
+ if (!ADDON::CAddonInstaller::GetInstance().InstallModal(
+ "script.rss.editor", addon, ADDON::InstallModalPrompt::CHOICE_YES))
return;
}
CBuiltins::GetInstance().Execute("RunScript(script.rss.editor)");
diff --git a/xbmc/utils/StreamDetails.cpp b/xbmc/utils/StreamDetails.cpp
index bea28b20c1..4944134df0 100644
--- a/xbmc/utils/StreamDetails.cpp
+++ b/xbmc/utils/StreamDetails.cpp
@@ -615,7 +615,11 @@ std::string CStreamDetails::VideoAspectToAspectDescription(float fAspect)
// aspect ratios, particularly when cropping prior to video encoding is taken into account
// the best we can do is take the "common" aspect ratios, and return the closest one available.
// The cutoffs are the geometric mean of the two aspect ratios either side.
- if (fAspect < 1.3499f) // sqrt(1.33*1.37)
+ if (fAspect < 1.0909f) // sqrt(1.00*1.19)
+ return "1.00";
+ else if (fAspect < 1.2581f) // sqrt(1.19*1.33)
+ return "1.19";
+ else if (fAspect < 1.3499f) // sqrt(1.33*1.37)
return "1.33";
else if (fAspect < 1.5080f) // sqrt(1.37*1.66)
return "1.37";
@@ -623,8 +627,10 @@ std::string CStreamDetails::VideoAspectToAspectDescription(float fAspect)
return "1.66";
else if (fAspect < 1.8147f) // sqrt(1.78*1.85)
return "1.78";
- else if (fAspect < 2.0174f) // sqrt(1.85*2.20)
+ else if (fAspect < 1.9235f) // sqrt(1.85*2.00)
return "1.85";
+ else if (fAspect < 2.0976f) // sqrt(2.00*2.20)
+ return "2.00";
else if (fAspect < 2.2738f) // sqrt(2.20*2.35)
return "2.20";
else if (fAspect < 2.3749f) // sqrt(2.35*2.40)
diff --git a/xbmc/video/VideoDatabase.cpp b/xbmc/video/VideoDatabase.cpp
index b82cb92b7a..2ee513e978 100644
--- a/xbmc/video/VideoDatabase.cpp
+++ b/xbmc/video/VideoDatabase.cpp
@@ -8082,7 +8082,7 @@ ScraperPtr CVideoDatabase::GetScraperForPath(const std::string& strPath, SScanSe
AddonPtr addon;
if (!scraperID.empty() &&
CServiceBroker::GetAddonMgr().GetAddon(scraperID, addon, ADDON::ADDON_UNKNOWN,
- ADDON::OnlyEnabled::YES))
+ ADDON::OnlyEnabled::CHOICE_YES))
{
scraper = std::dynamic_pointer_cast<CScraper>(addon);
if (!scraper)
@@ -8130,7 +8130,7 @@ ScraperPtr CVideoDatabase::GetScraperForPath(const std::string& strPath, SScanSe
AddonPtr addon;
if (content != CONTENT_NONE && CServiceBroker::GetAddonMgr().GetAddon(
m_pDS->fv("path.strScraper").get_asString(), addon,
- ADDON::ADDON_UNKNOWN, ADDON::OnlyEnabled::YES))
+ ADDON::ADDON_UNKNOWN, ADDON::OnlyEnabled::CHOICE_YES))
{
scraper = std::dynamic_pointer_cast<CScraper>(addon);
scraper->SetPathSettings(content, m_pDS->fv("path.strSettings").get_asString());
@@ -10434,7 +10434,7 @@ void CVideoDatabase::ImportFromXML(const std::string &path)
std::string id;
XMLUtils::GetString(path,"scraperpath",id);
if (CServiceBroker::GetAddonMgr().GetAddon(id, addon, ADDON::ADDON_UNKNOWN,
- ADDON::OnlyEnabled::YES))
+ ADDON::OnlyEnabled::CHOICE_YES))
{
SScanSettings settings;
ScraperPtr scraper = std::dynamic_pointer_cast<CScraper>(addon);
diff --git a/xbmc/video/VideoInfoScanner.cpp b/xbmc/video/VideoInfoScanner.cpp
index 39bfcb52d7..8cd3c937fb 100644
--- a/xbmc/video/VideoInfoScanner.cpp
+++ b/xbmc/video/VideoInfoScanner.cpp
@@ -2166,7 +2166,8 @@ namespace VIDEO
HELPERS::ShowOKDialogText(CVariant{20448}, CVariant{20449});
return false;
}
- return HELPERS::ShowYesNoDialogText(CVariant{20448}, CVariant{20450}) == DialogResponse::YES;
+ return HELPERS::ShowYesNoDialogText(CVariant{20448}, CVariant{20450}) ==
+ DialogResponse::CHOICE_YES;
}
bool CVideoInfoScanner::ProgressCancelled(CGUIDialogProgress* progress, int heading, const std::string &line1)
diff --git a/xbmc/video/dialogs/GUIDialogSubtitles.cpp b/xbmc/video/dialogs/GUIDialogSubtitles.cpp
index 4f0f3f29f5..99ec404cdc 100644
--- a/xbmc/video/dialogs/GUIDialogSubtitles.cpp
+++ b/xbmc/video/dialogs/GUIDialogSubtitles.cpp
@@ -425,7 +425,7 @@ void CGUIDialogSubtitles::OnSubtitleServiceContextMenu(int itemIdx)
{
AddonPtr addon;
if (CServiceBroker::GetAddonMgr().GetAddon(service->GetProperty("Addon.ID").asString(), addon,
- ADDON_SUBTITLE_MODULE, OnlyEnabled::YES))
+ ADDON_SUBTITLE_MODULE, OnlyEnabled::CHOICE_YES))
{
CGUIDialogAddonSettings::ShowForAddon(addon);
}
diff --git a/xbmc/view/GUIViewState.cpp b/xbmc/view/GUIViewState.cpp
index f54d5ff45f..ff99c1baa4 100644
--- a/xbmc/view/GUIViewState.cpp
+++ b/xbmc/view/GUIViewState.cpp
@@ -598,7 +598,7 @@ CGUIViewStateFromItems::CGUIViewStateFromItems(const CFileItemList &items) : CGU
CURL url(items.GetPath());
AddonPtr addon;
if (CServiceBroker::GetAddonMgr().GetAddon(url.GetHostName(), addon, ADDON_PLUGIN,
- OnlyEnabled::YES))
+ OnlyEnabled::CHOICE_YES))
{
PluginPtr plugin = std::static_pointer_cast<CPluginSource>(addon);
if (plugin->Provides(CPluginSource::AUDIO))
diff --git a/xbmc/weather/WeatherJob.cpp b/xbmc/weather/WeatherJob.cpp
index 6cb214bf19..7638dbbad3 100644
--- a/xbmc/weather/WeatherJob.cpp
+++ b/xbmc/weather/WeatherJob.cpp
@@ -53,7 +53,7 @@ bool CWeatherJob::DoWork()
if (!CServiceBroker::GetAddonMgr().GetAddon(
CServiceBroker::GetSettingsComponent()->GetSettings()->GetString(
CSettings::SETTING_WEATHER_ADDON),
- addon, ADDON_SCRIPT_WEATHER, OnlyEnabled::YES))
+ addon, ADDON_SCRIPT_WEATHER, OnlyEnabled::CHOICE_YES))
return false;
// initialize our sys.argv variables
diff --git a/xbmc/weather/WeatherManager.cpp b/xbmc/weather/WeatherManager.cpp
index 0c31cbdf9a..42c2c65ea2 100644
--- a/xbmc/weather/WeatherManager.cpp
+++ b/xbmc/weather/WeatherManager.cpp
@@ -177,7 +177,7 @@ void CWeatherManager::OnSettingAction(const std::shared_ptr<const CSetting>& set
if (CServiceBroker::GetAddonMgr().GetAddon(
CServiceBroker::GetSettingsComponent()->GetSettings()->GetString(
CSettings::SETTING_WEATHER_ADDON),
- addon, ADDON_SCRIPT_WEATHER, OnlyEnabled::YES) &&
+ addon, ADDON_SCRIPT_WEATHER, OnlyEnabled::CHOICE_YES) &&
addon != NULL)
{ //! @todo maybe have ShowAndGetInput return a bool if settings changed, then only reset weather if true.
CGUIDialogAddonSettings::ShowForAddon(addon);
diff --git a/xbmc/windows/GUIMediaWindow.cpp b/xbmc/windows/GUIMediaWindow.cpp
index a36b4d5253..908abe5bb3 100644
--- a/xbmc/windows/GUIMediaWindow.cpp
+++ b/xbmc/windows/GUIMediaWindow.cpp
@@ -1052,7 +1052,7 @@ bool CGUIMediaWindow::OnClick(int iItem, const std::string &player)
CURL url(pItem->GetPath());
AddonPtr addon;
if (CServiceBroker::GetAddonMgr().GetAddon(url.GetHostName(), addon, ADDON_SCRIPT,
- OnlyEnabled::YES))
+ OnlyEnabled::CHOICE_YES))
{
if (!CScriptInvocationManager::GetInstance().Stop(addon->LibPath()))
{
@@ -1156,7 +1156,7 @@ bool CGUIMediaWindow::OnClick(int iItem, const std::string &player)
CURL url(m_vecItems->GetPath());
AddonPtr addon;
if (CServiceBroker::GetAddonMgr().GetAddon(url.GetHostName(), addon, ADDON_UNKNOWN,
- OnlyEnabled::YES))
+ OnlyEnabled::CHOICE_YES))
{
PluginPtr plugin = std::dynamic_pointer_cast<CPluginSource>(addon);
if (plugin && plugin->Provides(CPluginSource::AUDIO))
diff --git a/xbmc/windows/GUIWindowScreensaverDim.cpp b/xbmc/windows/GUIWindowScreensaverDim.cpp
index 7746b23f39..87a12331e2 100644
--- a/xbmc/windows/GUIWindowScreensaverDim.cpp
+++ b/xbmc/windows/GUIWindowScreensaverDim.cpp
@@ -38,7 +38,7 @@ void CGUIWindowScreensaverDim::UpdateVisibility()
m_visible = true;
ADDON::AddonPtr info;
bool success = CServiceBroker::GetAddonMgr().GetAddon(usedId, info, ADDON::ADDON_SCREENSAVER,
- ADDON::OnlyEnabled::YES);
+ ADDON::OnlyEnabled::CHOICE_YES);
if (success && info && !info->GetSetting("level").empty())
m_newDimLevel = 100.0f - (float)atof(info->GetSetting("level").c_str());
else