aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--addons/metadata.demo.movies/demo.py4
-rw-r--r--addons/metadata.demo.tv/demo.py4
-rw-r--r--addons/repository.xbmc.org/addon.xml4
-rw-r--r--addons/resource.language.en_gb/resources/strings.po12
-rw-r--r--addons/screensaver.xbmc.builtin.dim/addon.xml6
-rw-r--r--addons/screensaver.xbmc.builtin.dim/resources/language/resource.language.bg_bg/strings.po8
-rw-r--r--addons/screensaver.xbmc.builtin.dim/resources/language/resource.language.en_us/strings.po8
-rw-r--r--addons/screensaver.xbmc.builtin.dim/resources/language/resource.language.es_es/strings.po8
-rw-r--r--addons/screensaver.xbmc.builtin.dim/resources/language/resource.language.fi_fi/strings.po8
-rw-r--r--addons/screensaver.xbmc.builtin.dim/resources/language/resource.language.gl_es/strings.po8
-rw-r--r--addons/screensaver.xbmc.builtin.dim/resources/language/resource.language.hu_hu/strings.po8
-rw-r--r--addons/screensaver.xbmc.builtin.dim/resources/language/resource.language.is_is/strings.po8
-rw-r--r--addons/screensaver.xbmc.builtin.dim/resources/language/resource.language.ja_jp/strings.po12
-rw-r--r--addons/screensaver.xbmc.builtin.dim/resources/language/resource.language.pt_br/strings.po8
-rw-r--r--addons/screensaver.xbmc.builtin.dim/resources/language/resource.language.sl_si/strings.po12
-rw-r--r--addons/screensaver.xbmc.builtin.dim/resources/language/resource.language.tr_tr/strings.po4
-rw-r--r--addons/screensaver.xbmc.builtin.dim/resources/language/resource.language.zh_cn/strings.po8
-rw-r--r--addons/service.xbmc.versioncheck/resources/lib/version_check/service.py2
-rw-r--r--addons/service.xbmc.versioncheck/resources/lib/version_check/viewer.py2
-rw-r--r--addons/skin.estouchy/addon.xml2
-rw-r--r--addons/skin.estouchy/language/resource.language.bg_bg/strings.po8
-rw-r--r--addons/skin.estouchy/language/resource.language.de_de/strings.po16
-rw-r--r--addons/skin.estouchy/language/resource.language.gl_es/strings.po14
-rw-r--r--addons/skin.estouchy/language/resource.language.is_is/strings.po12
-rw-r--r--addons/skin.estouchy/language/resource.language.ja_jp/strings.po4
-rw-r--r--addons/skin.estouchy/language/resource.language.sv_se/strings.po10
-rw-r--r--addons/skin.estuary/addon.xml2
-rw-r--r--addons/skin.estuary/language/resource.language.bg_bg/strings.po44
-rw-r--r--addons/skin.estuary/language/resource.language.de_de/strings.po48
-rw-r--r--addons/skin.estuary/language/resource.language.en_us/strings.po24
-rw-r--r--addons/skin.estuary/language/resource.language.es_es/strings.po38
-rw-r--r--addons/skin.estuary/language/resource.language.et_ee/strings.po16
-rw-r--r--addons/skin.estuary/language/resource.language.fi_fi/strings.po24
-rw-r--r--addons/skin.estuary/language/resource.language.fr_fr/strings.po2
-rw-r--r--addons/skin.estuary/language/resource.language.gl_es/strings.po52
-rw-r--r--addons/skin.estuary/language/resource.language.hu_hu/strings.po24
-rw-r--r--addons/skin.estuary/language/resource.language.is_is/strings.po32
-rw-r--r--addons/skin.estuary/language/resource.language.ja_jp/strings.po24
-rw-r--r--addons/skin.estuary/language/resource.language.pt_br/strings.po24
-rw-r--r--addons/skin.estuary/language/resource.language.sl_si/strings.po4
-rw-r--r--addons/skin.estuary/language/resource.language.sv_se/strings.po30
-rw-r--r--addons/skin.estuary/language/resource.language.zh_cn/strings.po20
-rw-r--r--addons/skin.estuary/xml/MusicVisualisation.xml2
-rw-r--r--docs/manpages/TexturePacker.124
-rw-r--r--docs/manpages/kodi-wiiremote.12
-rw-r--r--docs/manpages/kodi.bin.116
-rw-r--r--system/shaders/guishader_common.hlsl31
-rw-r--r--system/shaders/guishader_default.hlsl2
-rw-r--r--system/shaders/guishader_fonts.hlsl2
-rw-r--r--system/shaders/guishader_multi_texture_blend.hlsl4
-rw-r--r--system/shaders/guishader_texture.hlsl2
-rwxr-xr-xtools/EventClients/Clients/KodiSend/kodi-send.py2
-rwxr-xr-xtools/EventClients/Clients/PS3BDRemote/ps3_remote.py2
-rwxr-xr-xtools/EventClients/Clients/PS3SixaxisController/ps3d.py2
-rw-r--r--tools/EventClients/examples/c#/XBMCDemoClient1.cs20
-rw-r--r--tools/EventClients/examples/c++/example_button1.cpp29
-rw-r--r--tools/EventClients/examples/c++/example_button2.cpp35
-rw-r--r--tools/EventClients/examples/c++/example_log.cpp5
-rw-r--r--tools/EventClients/examples/c++/example_mouse.cpp29
-rw-r--r--tools/EventClients/examples/c++/example_notification.cpp31
-rw-r--r--tools/EventClients/examples/java/XBMCDemoClient1.java22
-rwxr-xr-xtools/EventClients/examples/python/example_action.py21
-rwxr-xr-xtools/EventClients/examples/python/example_button1.py21
-rwxr-xr-xtools/EventClients/examples/python/example_button2.py21
-rwxr-xr-xtools/EventClients/examples/python/example_mouse.py21
-rwxr-xr-xtools/EventClients/examples/python/example_notification.py27
-rwxr-xr-xtools/EventClients/examples/python/example_simple.py22
-rw-r--r--tools/EventClients/lib/python/ps3/sixaxis.py2
-rwxr-xr-xtools/EventClients/lib/python/ps3/sixpair.py2
-rwxr-xr-xtools/EventClients/lib/python/ps3/sixwatch.py2
-rw-r--r--tools/EventClients/lib/python/xbmcclient.py2
-rw-r--r--tools/EventClients/lib/python/zeroconf.py13
-rw-r--r--tools/Linux/kodi-xsession.desktop.in2
-rw-r--r--tools/Linux/kodi.desktop.in1
-rw-r--r--tools/buildsteps/jenkins_docs/README.mac24
-rwxr-xr-xtools/darwin/Support/GenerateMissingImages-tvos.py4
-rw-r--r--tools/depends/target/dav1d/DAV1D-VERSION2
-rw-r--r--xbmc/Application.cpp18
-rw-r--r--xbmc/addons/AddonDatabase.cpp2
-rw-r--r--xbmc/addons/gui/GUIDialogAddonSettings.h2
-rw-r--r--xbmc/addons/kodi-dev-kit/include/kodi/addon-instance/PVR.h70
-rw-r--r--xbmc/addons/kodi-dev-kit/include/kodi/c-api/addon-instance/pvr.h6
-rw-r--r--xbmc/addons/kodi-dev-kit/include/kodi/versions.h4
-rwxr-xr-xxbmc/addons/kodi-dev-kit/tools/doxygen-header-class-list-creator.py2
-rw-r--r--xbmc/addons/settings/AddonSettings.cpp4
-rw-r--r--xbmc/dbwrappers/mysqldataset.cpp23
-rw-r--r--xbmc/dialogs/GUIDialogMediaFilter.h2
-rw-r--r--xbmc/dialogs/GUIDialogYesNo.cpp2
-rw-r--r--xbmc/filesystem/CurlFile.cpp43
-rw-r--r--xbmc/filesystem/CurlFile.h1
-rw-r--r--xbmc/guilib/GUIShaderDX.cpp1
-rw-r--r--xbmc/guilib/GUIShaderDX.h1
-rw-r--r--xbmc/interfaces/json-rpc/schema/version.txt2
-rw-r--r--xbmc/interfaces/legacy/Dialog.cpp47
-rw-r--r--xbmc/interfaces/legacy/Dialog.h57
-rw-r--r--xbmc/interfaces/python/LanguageHook.cpp16
-rw-r--r--xbmc/music/dialogs/GUIDialogInfoProviderSettings.cpp6
-rw-r--r--xbmc/music/dialogs/GUIDialogInfoProviderSettings.h2
-rw-r--r--xbmc/network/GUIDialogNetworkSetup.h2
-rw-r--r--xbmc/peripherals/dialogs/GUIDialogPeripheralSettings.cpp8
-rw-r--r--xbmc/peripherals/dialogs/GUIDialogPeripheralSettings.h2
-rw-r--r--xbmc/platform/posix/filesystem/SMBDirectory.cpp8
-rw-r--r--xbmc/platform/posix/filesystem/SMBFile.cpp29
-rw-r--r--xbmc/platform/posix/filesystem/SMBFile.h2
-rw-r--r--xbmc/profiles/dialogs/GUIDialogLockSettings.h2
-rw-r--r--xbmc/profiles/dialogs/GUIDialogProfileSettings.h2
-rw-r--r--xbmc/pvr/PVRManager.h1
-rw-r--r--xbmc/pvr/addons/PVRClient.cpp20
-rw-r--r--xbmc/pvr/addons/PVRClient.h26
-rw-r--r--xbmc/pvr/addons/PVRClients.cpp13
-rw-r--r--xbmc/pvr/addons/PVRClients.h35
-rw-r--r--xbmc/pvr/channels/PVRChannel.cpp48
-rw-r--r--xbmc/pvr/channels/PVRChannel.h28
-rw-r--r--xbmc/pvr/channels/PVRChannelGroupInternal.cpp69
-rw-r--r--xbmc/pvr/dialogs/GUIDialogPVRClientPriorities.cpp4
-rw-r--r--xbmc/pvr/dialogs/GUIDialogPVRClientPriorities.h2
-rw-r--r--xbmc/pvr/dialogs/GUIDialogPVRRecordingSettings.cpp4
-rw-r--r--xbmc/pvr/dialogs/GUIDialogPVRRecordingSettings.h2
-rw-r--r--xbmc/pvr/dialogs/GUIDialogPVRTimerSettings.cpp43
-rw-r--r--xbmc/pvr/dialogs/GUIDialogPVRTimerSettings.h3
-rw-r--r--xbmc/pvr/epg/Epg.cpp5
-rw-r--r--xbmc/pvr/epg/Epg.h5
-rw-r--r--xbmc/pvr/epg/EpgContainer.cpp55
-rw-r--r--xbmc/pvr/epg/EpgContainer.h13
-rw-r--r--xbmc/pvr/guilib/PVRGUIActionListener.cpp9
-rw-r--r--xbmc/pvr/windows/GUIWindowPVRGuide.cpp3
-rw-r--r--xbmc/rendering/dx/DeviceResources.cpp7
-rw-r--r--xbmc/rendering/dx/DeviceResources.h4
-rw-r--r--xbmc/settings/AdvancedSettings.cpp31
-rw-r--r--xbmc/settings/AdvancedSettings.h2
-rw-r--r--xbmc/settings/dialogs/GUIDialogContentSettings.cpp3
-rw-r--r--xbmc/settings/dialogs/GUIDialogContentSettings.h2
-rw-r--r--xbmc/settings/dialogs/GUIDialogLibExportSettings.cpp4
-rw-r--r--xbmc/settings/dialogs/GUIDialogLibExportSettings.h2
-rw-r--r--xbmc/settings/dialogs/GUIDialogSettingsBase.cpp10
-rw-r--r--xbmc/settings/dialogs/GUIDialogSettingsBase.h6
-rw-r--r--xbmc/settings/dialogs/GUIDialogSettingsManagerBase.cpp10
-rw-r--r--xbmc/settings/dialogs/GUIDialogSettingsManagerBase.h4
-rw-r--r--xbmc/settings/windows/GUIWindowSettingsCategory.cpp4
-rw-r--r--xbmc/settings/windows/GUIWindowSettingsCategory.h2
-rw-r--r--xbmc/storage/MediaManager.cpp14
-rw-r--r--xbmc/video/VideoDatabase.cpp22
-rw-r--r--xbmc/video/dialogs/GUIDialogAudioSettings.cpp10
-rw-r--r--xbmc/video/dialogs/GUIDialogAudioSettings.h2
-rw-r--r--xbmc/video/dialogs/GUIDialogCMSSettings.cpp4
-rw-r--r--xbmc/video/dialogs/GUIDialogCMSSettings.h2
-rw-r--r--xbmc/video/dialogs/GUIDialogSubtitleSettings.cpp10
-rw-r--r--xbmc/video/dialogs/GUIDialogSubtitleSettings.h2
-rw-r--r--xbmc/video/dialogs/GUIDialogVideoSettings.cpp8
-rw-r--r--xbmc/video/dialogs/GUIDialogVideoSettings.h2
-rw-r--r--xbmc/video/windows/GUIWindowVideoBase.cpp16
-rw-r--r--xbmc/windowing/win10/WinSystemWin10DX.cpp5
-rw-r--r--xbmc/windowing/win10/WinSystemWin10DX.h1
-rw-r--r--xbmc/windowing/windows/WinSystemWin32DX.cpp5
-rw-r--r--xbmc/windowing/windows/WinSystemWin32DX.h1
155 files changed, 1632 insertions, 374 deletions
diff --git a/addons/metadata.demo.movies/demo.py b/addons/metadata.demo.movies/demo.py
index b96105c01a..e643c769fa 100644
--- a/addons/metadata.demo.movies/demo.py
+++ b/addons/metadata.demo.movies/demo.py
@@ -1,4 +1,4 @@
-#!/usr/bin/env python
+#!/usr/bin/env python3
# -*- coding: UTF-8 -*-
import xbmcplugin,xbmcgui,xbmc,xbmcaddon
@@ -19,7 +19,7 @@ def get_params():
splitparams=pairsofparams[i].split('=')
if (len(splitparams))==2:
param[splitparams[0]]=splitparams[1]
-
+
return param
diff --git a/addons/metadata.demo.tv/demo.py b/addons/metadata.demo.tv/demo.py
index 11b956c8d4..42e50b9b36 100644
--- a/addons/metadata.demo.tv/demo.py
+++ b/addons/metadata.demo.tv/demo.py
@@ -1,4 +1,4 @@
-#!/usr/bin/env python
+#!/usr/bin/env python3
# -*- coding: UTF-8 -*-
import xbmcplugin,xbmcgui,xbmc,xbmcaddon
@@ -19,7 +19,7 @@ def get_params():
splitparams=pairsofparams[i].split('=')
if (len(splitparams))==2:
param[splitparams[0]]=splitparams[1]
-
+
return param
diff --git a/addons/repository.xbmc.org/addon.xml b/addons/repository.xbmc.org/addon.xml
index e9e7a2d8df..436d5e5c97 100644
--- a/addons/repository.xbmc.org/addon.xml
+++ b/addons/repository.xbmc.org/addon.xml
@@ -1,7 +1,7 @@
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<addon id="repository.xbmc.org"
name="Kodi Add-on repository"
- version="3.2.4"
+ version="3.2.5"
provider-name="Team Kodi">
<requires>
<import addon="xbmc.addon" version="12.0.0"/>
@@ -122,7 +122,7 @@
<description lang="sl_SI">Prenos in namestitev dodatkov iz uradnega skladišča Kodi.tv.[CR] Z uporabo uradnega skladišča, boste lahko izkoristili hitrejšo povezavo, ki bo izbrana glede na vašo lokacijo.[CR] Vsi dodatki tega skladišča so bili osnovno stestirani, če pa boste našli pokvarjen ali nedelujoč dodatek, to sporočite ekipi Kodi, da bomo lahko odpravili napake.</description>
<description lang="sr_RS">Преузмите и инсталирајте додатке из Званичног Kodi.tv спремишта додатака.[CR] Коришћењем званичног Спремишта моћићете да искористите предности нашег сервиса копија фајлова који ће вам помоћи приликом бржег преузимања из региона ближег вашој локацији.[CR] Сви додаци у овом спремишту прошли су основно тестирање, у случају да пронађете неисправан додатак молимо вас да то пријавите Kodi тиму који ће затим предузети неопходне мере.</description>
<description lang="sr_RS@latin">Preuzmi i instaliraj dodatne programe iz Zvaničnog Kodi.tv spremišta za dodatne programe.[CR] Korišćenjem zvaničnog Spremišta moći ćete da iskoristite prednosti našeg servisa kopija fajlova koji će vam pomoći prilikom bržeg preuzimanja iz regiona bližeg vašoj lokaciji.[CR] Svi dodatni programi u ovom spremištu prošli su osnovno testiranje, u slučaju da pronađete neispravan dodatni program molimo vas da to prijavite Kodi timu koji će zatim preduzeti neophodne mere.</description>
- <description lang="sv_SE">Ladda ner och installera tillägg från det officiella Kodi.tv tilläggsförrådet.[CR] Genom att använda det officiella förrådet kommer du att få fördelen att kunna använda vår omfattande spegeltjänst som kommer att hjälpa dig till snabbare nedladdningar från en plats nära dig.[CR] Alla tillägg i detta förråd har genomgått grundläggande tester. Hittar du ett trasigt eller icke fungerande tillägg, vänligen meddela detta till Team Kodi så att vi kan vidta nödvändiga åtgärder.</description>
+ <description lang="sv_SE">Hämta och installera tillägg från det officiella Kodi.tv tilläggsförrådet.[CR] Genom att använda det officiella förrådet kommer du att få fördelen att kunna använda vår omfattande spegeltjänst som kommer att hjälpa dig till snabbare hämtningar från en plats nära dig.[CR] Alla tillägg i detta förråd har genomgått grundläggande tester. Hittar du ett trasigt eller icke fungerande tillägg, vänligen meddela detta till Team Kodi så att vi kan vidta nödvändiga åtgärder.</description>
<description lang="szl">Sebiyrej i insztaluj przidŏwki z ôficjalnygo repozytoriōm Kodi.tv.[CR] Przi Używaniu ôficjalnygo repozytoriōm używŏsz serwerōw zdrzadłowych, rozsianych po calistym świecie. Ôbiyrany je tyn, kery je nŏjbliżyj ciebie, co istuje srogõ wartkość skuplowaniŏ.[CR]Wszyjske przidŏwki w tym repozytoriōm sōm testowane, ale mogōm pokŏzać sie popszniōne. Zgłoś wtynczŏs feler, coby ekipa Kodi mogła go sprŏwić.</description>
<description lang="tg_TJ">Барномаҳои иловагиро аз анбори нармафзори Kodi.tv боргирӣ кунед ва насб намоед.[CR] Аз истифодаи анбори нармафзори расмии мо ба шумо имконият пайдо мешавад, ки тавонед шароити мусофидро аз хидмати оинаи файлии васеъ ба даст оред ва нармафзори лозимиро аз сервери минтакаи ба шумо наздиктар бо суръати баланд боргирӣ кунед.[CR] Ҳамаи барномаҳо аз анбори нармафзори мо дар ҳолати санҷишӣ мебошанд, бинобар ин агар ягон барномаи иловагии нуқсондор ё вайроншударо ёбед, лутфан дар бораи он барнома ва нуқсон пайдошуда ба гурӯҳи кории Kodi гузориш диҳед, то ин ки мо тавонем ҳамаи камбудиҳои барномаҳои моро ҳал кунем.</description>
<description lang="th_TH">ดาวน์โหลดและติดตั้งส่วนเสริม จากแหล่งข้อมูลโปรแกรมของ Kodi.tv อย่างเป็นทางการ.[CR] โดยการใช้งานแหล่งข้อมูลโปรแกรมอย่างเป็นทางการ คุณสามารถใช้ประโยชน์จากบริการแฟ้มมิเรอร์ที่กว้างขวางของเรา ที่จะช่วยให้การดาวน์โหลดของคุณเร็วขึ้นจากภูมิภาคที่ใกล้ที่สุด.[CR] ส่วนเสริม ทั้งหมดในแหล่งเก็บข้อมูลนี้ อยู่ภายใต้การทดสอบขั้นพื้นฐานแล้ว ถ้าคุณพบส่วนเสริมที่เสียหายหรือไม่ทำงาน กรุณาแจ้งทีมงาน Kodi เพื่อให้เราสามารถดำเนินการใด ๆ ที่จำเป็น.</description>
diff --git a/addons/resource.language.en_gb/resources/strings.po b/addons/resource.language.en_gb/resources/strings.po
index 6ef9804027..c12198109c 100644
--- a/addons/resource.language.en_gb/resources/strings.po
+++ b/addons/resource.language.en_gb/resources/strings.po
@@ -2039,14 +2039,16 @@ msgctxt "#434"
msgid "From {0:s} at {1:d} {2:s}"
msgstr ""
+#. Headline of a dialog that pops up when a user tries to play a video that is located on an optical disc (Blu-ray, DVD) but the current KODI device doesn't have the according drive
#: xbmc/Application.cpp
msgctxt "#435"
msgid "No optical disc drive detected"
msgstr ""
-#: xbmc/Application.cpp
+#. Message body of a dialog that pops up when a user tries to play a video that is located on an optical disc (Blu-ray, DVD) but the current KODI device doesn't have the according drive
+#: xbmc/storage/MediaManager.cpp
msgctxt "#436"
-msgid "You need an optical disc drive to play this video"
+msgid "This video is stored on an optical disc (e.g. DVD, Blu-ray) and cannot be played as your device does not have an appropriate drive."
msgstr ""
msgctxt "#437"
@@ -9597,7 +9599,11 @@ msgctxt "#19071"
msgid "Update interval"
msgstr ""
-#empty string with id 19072
+#. Dialog warning text for invalid timer setting
+#: xbmc/pvr/dialogs/GUIDialogPVRTimerSettings.cpp
+msgctxt "#19072"
+msgid "In order to add/update a timer the end date and time must be greater than the start date and time."
+msgstr ""
#. pvr settings "delay channel switch" setting label
#: system/settings/settings.xml
diff --git a/addons/screensaver.xbmc.builtin.dim/addon.xml b/addons/screensaver.xbmc.builtin.dim/addon.xml
index 6b56735a18..9549c320cd 100644
--- a/addons/screensaver.xbmc.builtin.dim/addon.xml
+++ b/addons/screensaver.xbmc.builtin.dim/addon.xml
@@ -1,7 +1,7 @@
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<addon id="screensaver.xbmc.builtin.dim"
name="Dim"
- version="1.0.62"
+ version="1.0.63"
provider-name="Team Kodi">
<extension point="xbmc.ui.screensaver" library="dummy.so"/>
<extension point="xbmc.addon.metadata">
@@ -26,7 +26,7 @@
<summary lang="et_EE">Ekraanisäästja, mis hämardab ekraani</summary>
<summary lang="eu_ES">Pantaila iluntzen duen pantaila-babeslea</summary>
<summary lang="fa_IR">محافظ تاریک کننده صفحه نمایش</summary>
- <summary lang="fi_FI">Ruudun himmennys</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="gl_ES">O protector de pantalla atenúa a súa pantalla</summary>
@@ -36,7 +36,7 @@
<summary lang="id_ID">Penyelamat layar yang meredupkan layar Anda</summary>
<summary lang="is_IS">Skjáhvíla sem lækkar birtustigið á skjánum</summary>
<summary lang="it_IT">Salvaschermo che oscura lo schermo</summary>
- <summary lang="ja_JP">画面を薄暗くするスクリーンセーバー</summary>
+ <summary lang="ja_JP">スクリーンセーバー モード</summary>
<summary lang="ko_KR">화면을 어둡게 하는 화면 보호기</summary>
<summary lang="lt_LT">Ekrano vaizdas pritemdantis foną Jūsų ekrane</summary>
<summary lang="lv_LV">Ekrānsaudzētājs, kas aptumšo jūsu ekrānu</summary>
diff --git a/addons/screensaver.xbmc.builtin.dim/resources/language/resource.language.bg_bg/strings.po b/addons/screensaver.xbmc.builtin.dim/resources/language/resource.language.bg_bg/strings.po
index 538ca96e4e..d9d14adc71 100644
--- a/addons/screensaver.xbmc.builtin.dim/resources/language/resource.language.bg_bg/strings.po
+++ b/addons/screensaver.xbmc.builtin.dim/resources/language/resource.language.bg_bg/strings.po
@@ -16,6 +16,14 @@ msgstr ""
"Language: bg_BG\n"
"Plural-Forms: nplurals=2; plural=(n != 1);\n"
+msgctxt "#30000"
+msgid "Brightness level"
+msgstr "Ниво на яркост"
+
+msgctxt "#30001"
+msgid "Level in percent of how strongly the screen remains illuminated."
+msgstr "Ниво (в проценти) на това колко осветен да остане екранът."
+
msgctxt "#30002"
msgid "Preferences"
msgstr "Предпочитания"
diff --git a/addons/screensaver.xbmc.builtin.dim/resources/language/resource.language.en_us/strings.po b/addons/screensaver.xbmc.builtin.dim/resources/language/resource.language.en_us/strings.po
index 0a077a735e..1b6ba4630a 100644
--- a/addons/screensaver.xbmc.builtin.dim/resources/language/resource.language.en_us/strings.po
+++ b/addons/screensaver.xbmc.builtin.dim/resources/language/resource.language.en_us/strings.po
@@ -16,6 +16,14 @@ msgstr ""
"Language: en_US\n"
"Plural-Forms: nplurals=2; plural=(n != 1);\n"
+msgctxt "#30000"
+msgid "Brightness level"
+msgstr "Brightness level"
+
+msgctxt "#30001"
+msgid "Level in percent of how strongly the screen remains illuminated."
+msgstr "Level in percent of how strongly the screen remains illuminated."
+
msgctxt "#30002"
msgid "Preferences"
msgstr "Preferences"
diff --git a/addons/screensaver.xbmc.builtin.dim/resources/language/resource.language.es_es/strings.po b/addons/screensaver.xbmc.builtin.dim/resources/language/resource.language.es_es/strings.po
index 70da4efdab..694522d517 100644
--- a/addons/screensaver.xbmc.builtin.dim/resources/language/resource.language.es_es/strings.po
+++ b/addons/screensaver.xbmc.builtin.dim/resources/language/resource.language.es_es/strings.po
@@ -16,6 +16,14 @@ msgstr ""
"Language: es_ES\n"
"Plural-Forms: nplurals=2; plural=(n != 1);\n"
+msgctxt "#30000"
+msgid "Brightness level"
+msgstr "Nivel de brillo"
+
+msgctxt "#30001"
+msgid "Level in percent of how strongly the screen remains illuminated."
+msgstr "Nivel en porcentaje de cómo de iluminada se queda la pantalla."
+
msgctxt "#30002"
msgid "Preferences"
msgstr "Preferencias"
diff --git a/addons/screensaver.xbmc.builtin.dim/resources/language/resource.language.fi_fi/strings.po b/addons/screensaver.xbmc.builtin.dim/resources/language/resource.language.fi_fi/strings.po
index 6cb65350f6..3d9b78da87 100644
--- a/addons/screensaver.xbmc.builtin.dim/resources/language/resource.language.fi_fi/strings.po
+++ b/addons/screensaver.xbmc.builtin.dim/resources/language/resource.language.fi_fi/strings.po
@@ -16,6 +16,14 @@ msgstr ""
"Language: fi_FI\n"
"Plural-Forms: nplurals=2; plural=(n != 1);\n"
+msgctxt "#30000"
+msgid "Brightness level"
+msgstr "Kirkkauden taso"
+
+msgctxt "#30001"
+msgid "Level in percent of how strongly the screen remains illuminated."
+msgstr "Näytön valaistuksen vahvuuden taso prosenttiarvona."
+
msgctxt "#30002"
msgid "Preferences"
msgstr "Asetukset"
diff --git a/addons/screensaver.xbmc.builtin.dim/resources/language/resource.language.gl_es/strings.po b/addons/screensaver.xbmc.builtin.dim/resources/language/resource.language.gl_es/strings.po
index a2fd969960..cd3c096adf 100644
--- a/addons/screensaver.xbmc.builtin.dim/resources/language/resource.language.gl_es/strings.po
+++ b/addons/screensaver.xbmc.builtin.dim/resources/language/resource.language.gl_es/strings.po
@@ -16,6 +16,14 @@ msgstr ""
"Language: gl_ES\n"
"Plural-Forms: nplurals=2; plural=(n != 1);\n"
+msgctxt "#30000"
+msgid "Brightness level"
+msgstr "Nivel de brillo"
+
+msgctxt "#30001"
+msgid "Level in percent of how strongly the screen remains illuminated."
+msgstr "Nivel de porcentaxe na intensidade na que a pantalla permanece iluminada."
+
msgctxt "#30002"
msgid "Preferences"
msgstr "Preferencias"
diff --git a/addons/screensaver.xbmc.builtin.dim/resources/language/resource.language.hu_hu/strings.po b/addons/screensaver.xbmc.builtin.dim/resources/language/resource.language.hu_hu/strings.po
index 3681cdca4c..e8583272ea 100644
--- a/addons/screensaver.xbmc.builtin.dim/resources/language/resource.language.hu_hu/strings.po
+++ b/addons/screensaver.xbmc.builtin.dim/resources/language/resource.language.hu_hu/strings.po
@@ -16,6 +16,14 @@ msgstr ""
"Language: hu_HU\n"
"Plural-Forms: nplurals=2; plural=(n != 1);\n"
+msgctxt "#30000"
+msgid "Brightness level"
+msgstr "Fényerő szintje"
+
+msgctxt "#30001"
+msgid "Level in percent of how strongly the screen remains illuminated."
+msgstr "A képernyő megvilágításának erőssége százalékosan."
+
msgctxt "#30002"
msgid "Preferences"
msgstr "Beállítások"
diff --git a/addons/screensaver.xbmc.builtin.dim/resources/language/resource.language.is_is/strings.po b/addons/screensaver.xbmc.builtin.dim/resources/language/resource.language.is_is/strings.po
index dad7ffc4b0..20b40d2ea9 100644
--- a/addons/screensaver.xbmc.builtin.dim/resources/language/resource.language.is_is/strings.po
+++ b/addons/screensaver.xbmc.builtin.dim/resources/language/resource.language.is_is/strings.po
@@ -16,6 +16,14 @@ msgstr ""
"Language: is_IS\n"
"Plural-Forms: nplurals=2; plural=(n != 1);\n"
+msgctxt "#30000"
+msgid "Brightness level"
+msgstr "Birtustig"
+
+msgctxt "#30001"
+msgid "Level in percent of how strongly the screen remains illuminated."
+msgstr "Styrkur í prósentum hve skjár verður með mikla birtu."
+
msgctxt "#30002"
msgid "Preferences"
msgstr "Kjörstillingar"
diff --git a/addons/screensaver.xbmc.builtin.dim/resources/language/resource.language.ja_jp/strings.po b/addons/screensaver.xbmc.builtin.dim/resources/language/resource.language.ja_jp/strings.po
index 0b5e48acaa..4ea1fdf591 100644
--- a/addons/screensaver.xbmc.builtin.dim/resources/language/resource.language.ja_jp/strings.po
+++ b/addons/screensaver.xbmc.builtin.dim/resources/language/resource.language.ja_jp/strings.po
@@ -17,5 +17,13 @@ msgstr ""
"Plural-Forms: nplurals=1; plural=0;\n"
msgctxt "#30000"
-msgid "Dim level"
-msgstr "Dim レベル"
+msgid "Brightness level"
+msgstr "輝度"
+
+msgctxt "#30001"
+msgid "Level in percent of how strongly the screen remains illuminated."
+msgstr "画面の輝度レベルをパーセントの比率で表しています。"
+
+msgctxt "#30002"
+msgid "Preferences"
+msgstr "環境設定"
diff --git a/addons/screensaver.xbmc.builtin.dim/resources/language/resource.language.pt_br/strings.po b/addons/screensaver.xbmc.builtin.dim/resources/language/resource.language.pt_br/strings.po
index 989c9557f1..c0d3f149d7 100644
--- a/addons/screensaver.xbmc.builtin.dim/resources/language/resource.language.pt_br/strings.po
+++ b/addons/screensaver.xbmc.builtin.dim/resources/language/resource.language.pt_br/strings.po
@@ -16,6 +16,14 @@ msgstr ""
"Language: pt_BR\n"
"Plural-Forms: nplurals=2; plural=(n > 1);\n"
+msgctxt "#30000"
+msgid "Brightness level"
+msgstr "Nível de brilho"
+
+msgctxt "#30001"
+msgid "Level in percent of how strongly the screen remains illuminated."
+msgstr "Nível em porcentagem de quão fortemente a tela permanece iluminada."
+
msgctxt "#30002"
msgid "Preferences"
msgstr "Preferências"
diff --git a/addons/screensaver.xbmc.builtin.dim/resources/language/resource.language.sl_si/strings.po b/addons/screensaver.xbmc.builtin.dim/resources/language/resource.language.sl_si/strings.po
index d930c5962f..c2a8bc0ecd 100644
--- a/addons/screensaver.xbmc.builtin.dim/resources/language/resource.language.sl_si/strings.po
+++ b/addons/screensaver.xbmc.builtin.dim/resources/language/resource.language.sl_si/strings.po
@@ -17,5 +17,13 @@ msgstr ""
"Plural-Forms: nplurals=4; plural=(n%100==1 ? 0 : n%100==2 ? 1 : n%100==3 || n%100==4 ? 2 : 3);\n"
msgctxt "#30000"
-msgid "Dim level"
-msgstr "Nivo zatemnitve"
+msgid "Brightness level"
+msgstr "Stopnja svetlosti"
+
+msgctxt "#30001"
+msgid "Level in percent of how strongly the screen remains illuminated."
+msgstr "Stopnja jakosti osvetlitve zaslona v procentih."
+
+msgctxt "#30002"
+msgid "Preferences"
+msgstr "Prednostne Nastavitve"
diff --git a/addons/screensaver.xbmc.builtin.dim/resources/language/resource.language.tr_tr/strings.po b/addons/screensaver.xbmc.builtin.dim/resources/language/resource.language.tr_tr/strings.po
index 0684b69023..1575f6c4d8 100644
--- a/addons/screensaver.xbmc.builtin.dim/resources/language/resource.language.tr_tr/strings.po
+++ b/addons/screensaver.xbmc.builtin.dim/resources/language/resource.language.tr_tr/strings.po
@@ -16,6 +16,10 @@ msgstr ""
"Language: tr_TR\n"
"Plural-Forms: nplurals=1; plural=0;\n"
+msgctxt "#30000"
+msgid "Brightness level"
+msgstr "Parlaklık düzeyi"
+
msgctxt "#30002"
msgid "Preferences"
msgstr "Tercihler"
diff --git a/addons/screensaver.xbmc.builtin.dim/resources/language/resource.language.zh_cn/strings.po b/addons/screensaver.xbmc.builtin.dim/resources/language/resource.language.zh_cn/strings.po
index 5475c53f08..8c70c6a6d1 100644
--- a/addons/screensaver.xbmc.builtin.dim/resources/language/resource.language.zh_cn/strings.po
+++ b/addons/screensaver.xbmc.builtin.dim/resources/language/resource.language.zh_cn/strings.po
@@ -16,6 +16,14 @@ msgstr ""
"Language: zh_CN\n"
"Plural-Forms: nplurals=1; plural=0;\n"
+msgctxt "#30000"
+msgid "Brightness level"
+msgstr "亮度等级"
+
+msgctxt "#30001"
+msgid "Level in percent of how strongly the screen remains illuminated."
+msgstr "等级,以百分比表示屏幕保持照明的强度。"
+
msgctxt "#30002"
msgid "Preferences"
msgstr "偏好设置"
diff --git a/addons/service.xbmc.versioncheck/resources/lib/version_check/service.py b/addons/service.xbmc.versioncheck/resources/lib/version_check/service.py
index 32b7322258..70131f3636 100644
--- a/addons/service.xbmc.versioncheck/resources/lib/version_check/service.py
+++ b/addons/service.xbmc.versioncheck/resources/lib/version_check/service.py
@@ -1,4 +1,4 @@
-#!/usr/bin/python
+#!/usr/bin/env python3
# -*- coding: utf-8 -*-
"""
diff --git a/addons/service.xbmc.versioncheck/resources/lib/version_check/viewer.py b/addons/service.xbmc.versioncheck/resources/lib/version_check/viewer.py
index 9f2b00a34f..538f50d1c7 100644
--- a/addons/service.xbmc.versioncheck/resources/lib/version_check/viewer.py
+++ b/addons/service.xbmc.versioncheck/resources/lib/version_check/viewer.py
@@ -1,4 +1,4 @@
-#!/usr/bin/python
+#!/usr/bin/env python3
# -*- coding: utf-8 -*-
"""
diff --git a/addons/skin.estouchy/addon.xml b/addons/skin.estouchy/addon.xml
index eaef6953e9..f5bac2d8c2 100644
--- a/addons/skin.estouchy/addon.xml
+++ b/addons/skin.estouchy/addon.xml
@@ -1,5 +1,5 @@
<?xml version="1.0" encoding="UTF-8"?>
-<addon id="skin.estouchy" version="3.0.4" name="Estouchy" provider-name="Team Kodi">
+<addon id="skin.estouchy" version="3.0.5" name="Estouchy" provider-name="Team Kodi">
<requires>
<import addon="xbmc.gui" version="5.15.0"/>
</requires>
diff --git a/addons/skin.estouchy/language/resource.language.bg_bg/strings.po b/addons/skin.estouchy/language/resource.language.bg_bg/strings.po
index dbd38c1186..48a364eb6c 100644
--- a/addons/skin.estouchy/language/resource.language.bg_bg/strings.po
+++ b/addons/skin.estouchy/language/resource.language.bg_bg/strings.po
@@ -100,6 +100,14 @@ msgctxt "#31039"
msgid "Updated:"
msgstr "Обновено:"
+msgctxt "#31040"
+msgid "Select + X"
+msgstr "Select + X"
+
+msgctxt "#31042"
+msgid "Select + Start"
+msgstr "Select + Start"
+
msgctxt "#31043"
msgid "PAUSED"
msgstr "НА ПАУЗА"
diff --git a/addons/skin.estouchy/language/resource.language.de_de/strings.po b/addons/skin.estouchy/language/resource.language.de_de/strings.po
index e6d50b762f..392b751f72 100644
--- a/addons/skin.estouchy/language/resource.language.de_de/strings.po
+++ b/addons/skin.estouchy/language/resource.language.de_de/strings.po
@@ -56,6 +56,10 @@ msgctxt "#31014"
msgid "Episodes"
msgstr "Episoden"
+msgctxt "#31015"
+msgid "Player info"
+msgstr "Spieler-Information"
+
msgctxt "#31016"
msgid "Albums"
msgstr "Alben"
@@ -96,6 +100,18 @@ msgctxt "#31039"
msgid "Updated:"
msgstr "Aktualisiert:"
+msgctxt "#31040"
+msgid "Select + X"
+msgstr "Select + X"
+
+msgctxt "#31041"
+msgid "Select + B"
+msgstr "Select + B"
+
+msgctxt "#31042"
+msgid "Select + Start"
+msgstr "Select + Start"
+
msgctxt "#31043"
msgid "PAUSED"
msgstr "PAUSE"
diff --git a/addons/skin.estouchy/language/resource.language.gl_es/strings.po b/addons/skin.estouchy/language/resource.language.gl_es/strings.po
index cc57729d86..cb75189c06 100644
--- a/addons/skin.estouchy/language/resource.language.gl_es/strings.po
+++ b/addons/skin.estouchy/language/resource.language.gl_es/strings.po
@@ -100,6 +100,18 @@ msgctxt "#31039"
msgid "Updated:"
msgstr "Actualizado:"
+msgctxt "#31040"
+msgid "Select + X"
+msgstr "Select + X"
+
+msgctxt "#31041"
+msgid "Select + B"
+msgstr "Select + B"
+
+msgctxt "#31042"
+msgid "Select + Start"
+msgstr "Select + Inicio"
+
msgctxt "#31043"
msgid "PAUSED"
msgstr "EN PAUSA"
@@ -198,7 +210,7 @@ msgstr "Teletexto"
msgctxt "#31390"
msgid "Skin default"
-msgstr "Pel por defecto"
+msgstr "Pel predefinida"
msgctxt "#31391"
msgid "Arial based"
diff --git a/addons/skin.estouchy/language/resource.language.is_is/strings.po b/addons/skin.estouchy/language/resource.language.is_is/strings.po
index bf299864cb..62a0124396 100644
--- a/addons/skin.estouchy/language/resource.language.is_is/strings.po
+++ b/addons/skin.estouchy/language/resource.language.is_is/strings.po
@@ -100,6 +100,18 @@ msgctxt "#31039"
msgid "Updated:"
msgstr "Uppfært:"
+msgctxt "#31040"
+msgid "Select + X"
+msgstr "Val + X"
+
+msgctxt "#31041"
+msgid "Select + B"
+msgstr "Val + B"
+
+msgctxt "#31042"
+msgid "Select + Start"
+msgstr "Val + Start"
+
msgctxt "#31043"
msgid "PAUSED"
msgstr "Í BIÐ"
diff --git a/addons/skin.estouchy/language/resource.language.ja_jp/strings.po b/addons/skin.estouchy/language/resource.language.ja_jp/strings.po
index 81a8b6cf4c..b68c1f5506 100644
--- a/addons/skin.estouchy/language/resource.language.ja_jp/strings.po
+++ b/addons/skin.estouchy/language/resource.language.ja_jp/strings.po
@@ -104,6 +104,10 @@ msgctxt "#31040"
msgid "Select + X"
msgstr "セレクト + X"
+msgctxt "#31041"
+msgid "Select + B"
+msgstr "セレクト + B"
+
msgctxt "#31042"
msgid "Select + Start"
msgstr "セレクト + スタート"
diff --git a/addons/skin.estouchy/language/resource.language.sv_se/strings.po b/addons/skin.estouchy/language/resource.language.sv_se/strings.po
index f02d74e5b5..31251e4cb8 100644
--- a/addons/skin.estouchy/language/resource.language.sv_se/strings.po
+++ b/addons/skin.estouchy/language/resource.language.sv_se/strings.po
@@ -46,7 +46,7 @@ msgstr "Arbetar..."
msgctxt "#31011"
msgid "Recent"
-msgstr "Senaste"
+msgstr "Nyligen"
msgctxt "#31013"
msgid "Movies"
@@ -190,7 +190,7 @@ msgstr "Videomeny"
msgctxt "#31356"
msgid "Download Subtitles"
-msgstr "Ladda ner undertexter"
+msgstr "Hämta undertexter"
msgctxt "#31358"
msgid "Teletext"
@@ -222,11 +222,11 @@ msgstr "Hantera dina installerade tillägg · Bläddra efter och installera till
msgctxt "#31408"
msgid "Configure actions that can be used during playback · Configure how media content is played"
-msgstr "Konfigurera åtgärder som kan användas under uppspelning · Konfigurera hur medieinnehåll spelas"
+msgstr "Konfigurera åtgärder som kan användas under uppspelning · Konfigurera hur mediainnehåll spelas"
msgctxt "#31409"
msgid "Configure library sources · Show the media lists display content · Configure how library lists are navigated"
-msgstr "Konfigurera bibliotekskällor · Visa medielistor displayinnehåll · Konfigurera hur bibliotekslistor navigeras"
+msgstr "Konfigurera bibliotekskällor · Visa medialistor displayinnehåll · Konfigurera hur bibliotekslistor navigeras"
msgctxt "#31410"
msgid "Configure skin · Configure region · Configure control · Configure screensaver · Configure master lock"
@@ -306,7 +306,7 @@ msgstr "Döp om grupp"
msgctxt "#31563"
msgid "Delete Group"
-msgstr "Radera grupp"
+msgstr "Ta bort grupp"
msgctxt "#31564"
msgid "Show hidden"
diff --git a/addons/skin.estuary/addon.xml b/addons/skin.estuary/addon.xml
index b946bb81e3..45c0ded857 100644
--- a/addons/skin.estuary/addon.xml
+++ b/addons/skin.estuary/addon.xml
@@ -1,5 +1,5 @@
<?xml version="1.0" encoding="UTF-8"?>
-<addon id="skin.estuary" version="3.0.3" name="Estuary" provider-name="phil65, Ichabod Fletchman">
+<addon id="skin.estuary" version="3.0.4" name="Estuary" provider-name="phil65, Ichabod Fletchman">
<requires>
<import addon="xbmc.gui" version="5.15.0"/>
</requires>
diff --git a/addons/skin.estuary/language/resource.language.bg_bg/strings.po b/addons/skin.estuary/language/resource.language.bg_bg/strings.po
index d6b8b7276a..caed7eac4f 100644
--- a/addons/skin.estuary/language/resource.language.bg_bg/strings.po
+++ b/addons/skin.estuary/language/resource.language.bg_bg/strings.po
@@ -124,6 +124,10 @@ msgctxt "#31026"
msgid "Timeshift"
msgstr "Изместване във времето"
+msgctxt "#31027"
+msgid "Next aired"
+msgstr "Следващо излъчване"
+
msgctxt "#31028"
msgid "Show fanart"
msgstr "Фен-арт"
@@ -208,6 +212,14 @@ msgctxt "#31053"
msgid "Arial based"
msgstr "Основан на Arial"
+msgctxt "#31054"
+msgid "Press [B]Left[/B] to step back, or [B]Right[/B] to step forward"
+msgstr "Натиснете [B]Наляво[/B] за стъпка назад или [B]Надясно[/B] – за напред"
+
+msgctxt "#31055"
+msgid "Press [B]Right[/B] to frame advance"
+msgstr "Натиснете [B]Надясно[/B], за да преминете към следващия кадър"
+
msgctxt "#31056"
msgid "Go to playlist"
msgstr "Към плейлиста"
@@ -220,6 +232,14 @@ msgctxt "#31058"
msgid "Automatic Login on startup"
msgstr "Автоматично влизане след стартиране"
+msgctxt "#31059"
+msgid "Select + X"
+msgstr "Select + X"
+
+msgctxt "#31060"
+msgid "Select + Start"
+msgstr "Select + Start"
+
msgctxt "#31061"
msgid "Main menu items"
msgstr "Елементи в менюто"
@@ -448,6 +468,10 @@ msgctxt "#31134"
msgid "Remaining"
msgstr "Остава"
+msgctxt "#31135"
+msgid "Binary"
+msgstr "Двоично"
+
msgctxt "#31136"
msgid "Click here to see latest changes..."
msgstr "Последни промени…"
@@ -488,6 +512,14 @@ msgctxt "#31145"
msgid "Search add-ons"
msgstr "Търси в добавките"
+msgctxt "#31146"
+msgid "In cinemas"
+msgstr "В кината"
+
+msgctxt "#31147"
+msgid "In cinemas soon"
+msgstr "Скоро в кината"
+
msgctxt "#31148"
msgid "Categories"
msgstr "Категории"
@@ -496,6 +528,10 @@ msgctxt "#31149"
msgid "Select genre fanart pack"
msgstr "Избор на пакет с фен-арт за категориите "
+msgctxt "#31150"
+msgid "Origin"
+msgstr "Произход"
+
msgctxt "#31151"
msgid "Unwatched music videos"
msgstr "Негледани музикални клипове"
@@ -563,3 +599,11 @@ msgstr "Снимка на профила"
msgctxt "#31167"
msgid "Animate background"
msgstr "Анимиране на фон"
+
+msgctxt "#31168"
+msgid "Show posters instead of thumbs for musicvideos"
+msgstr "Показване на плакати вместо миниатюри за музикалните видеа"
+
+msgctxt "#31169"
+msgid "Artwork related settings."
+msgstr "Категорията съдържа настройки свързани с изображенията."
diff --git a/addons/skin.estuary/language/resource.language.de_de/strings.po b/addons/skin.estuary/language/resource.language.de_de/strings.po
index 57203702e0..10f723a65d 100644
--- a/addons/skin.estuary/language/resource.language.de_de/strings.po
+++ b/addons/skin.estuary/language/resource.language.de_de/strings.po
@@ -124,6 +124,10 @@ msgctxt "#31026"
msgid "Timeshift"
msgstr "Timeshift"
+msgctxt "#31027"
+msgid "Next aired"
+msgstr "Nächste Folgen"
+
msgctxt "#31028"
msgid "Show fanart"
msgstr "Fanart zeigen"
@@ -160,6 +164,10 @@ msgctxt "#31036"
msgid "items"
msgstr "Einträge"
+msgctxt "#31037"
+msgid "Selected track"
+msgstr "Ausgwählter Titel"
+
msgctxt "#31038"
msgid "Rewind"
msgstr "Rücklauf"
@@ -204,6 +212,14 @@ msgctxt "#31053"
msgid "Arial based"
msgstr "Arial-basiert"
+msgctxt "#31054"
+msgid "Press [B]Left[/B] to step back, or [B]Right[/B] to step forward"
+msgstr "[B]Links[/B] für einen Schritt zurück, [B]Rechts[/B] für einen Schritt vorwärts drücken"
+
+msgctxt "#31055"
+msgid "Press [B]Right[/B] to frame advance"
+msgstr "[B]Rechts[/B] für einen Frame weiter drücken"
+
msgctxt "#31056"
msgid "Go to playlist"
msgstr "Zur Wiedergabeliste ..."
@@ -216,6 +232,14 @@ msgctxt "#31058"
msgid "Automatic Login on startup"
msgstr "Automatischer Login beim Programmstart"
+msgctxt "#31059"
+msgid "Select + X"
+msgstr "Select + X"
+
+msgctxt "#31060"
+msgid "Select + Start"
+msgstr "Select + Start"
+
msgctxt "#31061"
msgid "Main menu items"
msgstr "Hauptmenüeinträge"
@@ -444,6 +468,10 @@ msgctxt "#31134"
msgid "Remaining"
msgstr "Restzeit"
+msgctxt "#31135"
+msgid "Binary"
+msgstr "Binär"
+
msgctxt "#31136"
msgid "Click here to see latest changes..."
msgstr "Hier klicken, um die letzten Änderungen zu sehen ..."
@@ -484,6 +512,14 @@ msgctxt "#31145"
msgid "Search add-ons"
msgstr "Addons durchsuchen"
+msgctxt "#31146"
+msgid "In cinemas"
+msgstr "In den Kinos"
+
+msgctxt "#31147"
+msgid "In cinemas soon"
+msgstr "Demnächst in den Kinos"
+
msgctxt "#31148"
msgid "Categories"
msgstr "Kategorien"
@@ -492,6 +528,10 @@ msgctxt "#31149"
msgid "Select genre fanart pack"
msgstr "Genre-Fanart-Pack auswählen"
+msgctxt "#31150"
+msgid "Origin"
+msgstr "Herkunft"
+
msgctxt "#31151"
msgid "Unwatched music videos"
msgstr "Ungesehene Musikvideos"
@@ -559,3 +599,11 @@ msgstr "Profil-Avatar"
msgctxt "#31167"
msgid "Animate background"
msgstr "Hintergrund animieren"
+
+msgctxt "#31168"
+msgid "Show posters instead of thumbs for musicvideos"
+msgstr "Für Musikvideos Poster anstelle von Vorschaulbildern zeigen"
+
+msgctxt "#31169"
+msgid "Artwork related settings."
+msgstr "Einstellungen für Artwork"
diff --git a/addons/skin.estuary/language/resource.language.en_us/strings.po b/addons/skin.estuary/language/resource.language.en_us/strings.po
index 9f4ed8bca8..2df0959841 100644
--- a/addons/skin.estuary/language/resource.language.en_us/strings.po
+++ b/addons/skin.estuary/language/resource.language.en_us/strings.po
@@ -212,6 +212,14 @@ msgctxt "#31053"
msgid "Arial based"
msgstr "Arial based"
+msgctxt "#31054"
+msgid "Press [B]Left[/B] to step back, or [B]Right[/B] to step forward"
+msgstr "Press [B]Left[/B] to step back, or [B]Right[/B] to step forward"
+
+msgctxt "#31055"
+msgid "Press [B]Right[/B] to frame advance"
+msgstr "Press [B]Right[/B] to frame advance"
+
msgctxt "#31056"
msgid "Go to playlist"
msgstr "Go to playlist"
@@ -460,6 +468,10 @@ msgctxt "#31134"
msgid "Remaining"
msgstr "Remaining"
+msgctxt "#31135"
+msgid "Binary"
+msgstr "Binary"
+
msgctxt "#31136"
msgid "Click here to see latest changes..."
msgstr "Click here to see latest changes..."
@@ -516,6 +528,10 @@ msgctxt "#31149"
msgid "Select genre fanart pack"
msgstr "Select genre fanart pack"
+msgctxt "#31150"
+msgid "Origin"
+msgstr "Origin"
+
msgctxt "#31151"
msgid "Unwatched music videos"
msgstr "Unwatched music videos"
@@ -583,3 +599,11 @@ msgstr "Profile avatar"
msgctxt "#31167"
msgid "Animate background"
msgstr "Animate background"
+
+msgctxt "#31168"
+msgid "Show posters instead of thumbs for musicvideos"
+msgstr "Show posters instead of thumbs for musicvideos"
+
+msgctxt "#31169"
+msgid "Artwork related settings."
+msgstr "Artwork related settings."
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 44e2b692e6..939447d08a 100644
--- a/addons/skin.estuary/language/resource.language.es_es/strings.po
+++ b/addons/skin.estuary/language/resource.language.es_es/strings.po
@@ -212,6 +212,14 @@ msgctxt "#31053"
msgid "Arial based"
msgstr "Basada en Arial"
+msgctxt "#31054"
+msgid "Press [B]Left[/B] to step back, or [B]Right[/B] to step forward"
+msgstr "Presione [B]Izquierda[/B] para retroceder, o [B]Derecha[/B] para avanzar"
+
+msgctxt "#31055"
+msgid "Press [B]Right[/B] to frame advance"
+msgstr "Presione [B]Derecha[/B] para avanzar"
+
msgctxt "#31056"
msgid "Go to playlist"
msgstr "Ir a lista de reproducción"
@@ -246,7 +254,7 @@ msgstr "Secciones"
msgctxt "#31065"
msgid "Video playlist"
-msgstr "Lista de reproducción de video"
+msgstr "Lista de reproducción de vídeo"
msgctxt "#31066"
msgid "Music playlist"
@@ -310,7 +318,7 @@ msgstr "Grupos disponibles"
msgctxt "#31092"
msgid "Video menu"
-msgstr "Menú de video"
+msgstr "Menú de vídeo"
msgctxt "#31093"
msgid "Show weather info in top bar"
@@ -330,7 +338,7 @@ msgstr "Opciones de canal"
msgctxt "#31098"
msgid "Select your Kodi user profile[CR]to login and continue"
-msgstr "Seleccione su perfil de usuario de Kodi[CR]para ingresar y continuar"
+msgstr "Seleccione su perfil de usuario de Kodi[CR]para iniciar sesión y continuar"
msgctxt "#31099"
msgid "IconWall"
@@ -354,11 +362,11 @@ msgstr "Introduzca el texto aquí..."
msgctxt "#31104"
msgid "Your library is currently empty. In order to populate it with your personal media, enter \"Files\" section, add a media source and configure it. After the source has been added and indexed you will be able to browse your library."
-msgstr "Su colección se encuentra vacía. Para proveerla de contenidos, entre en la sección \"Archivos\", añada un origen de contenido y configúrelo. Después de que se añada e indexe esta nueva fuente, podrá navegar por su colección."
+msgstr "Su biblioteca está actualmente vacía. Para llenarlo con sus medios personales, ingrese a la sección \"Archivos\", agregue una fuente de medios y configúrelo. Una vez agregada e indexada la fuente, podrá navegar por su biblioteca."
msgctxt "#31105"
msgid "Add video sources and set the appropriate content type in order to populate your video libraries."
-msgstr "Añada fuentes de vídeo y configure el tipo de contenido apropiado para poblar las colecciones de vídeo."
+msgstr "Agregue fuentes de video y establezca el tipo de contenido apropiado para llenar sus bibliotecas de vídeo."
msgctxt "#31106"
msgid "Teletext"
@@ -460,6 +468,10 @@ msgctxt "#31134"
msgid "Remaining"
msgstr "Restante"
+msgctxt "#31135"
+msgid "Binary"
+msgstr "Binario"
+
msgctxt "#31136"
msgid "Click here to see latest changes..."
msgstr "Pulse aquí para ver los cambios más recientes..."
@@ -516,6 +528,10 @@ msgctxt "#31149"
msgid "Select genre fanart pack"
msgstr "Elegir pack de fanart para los géneros"
+msgctxt "#31150"
+msgid "Origin"
+msgstr "Origen"
+
msgctxt "#31151"
msgid "Unwatched music videos"
msgstr "Vídeos musicales no vistos"
@@ -550,11 +566,11 @@ msgstr "Modo táctil"
msgctxt "#31159"
msgid "Artwork"
-msgstr "Grafismo"
+msgstr "Ilustraciones"
msgctxt "#31160"
msgid "Show media flags"
-msgstr "Mostrar marcas de contenido"
+msgstr "Mostrar indicadores de contenido"
msgctxt "#31161"
msgid "Numeric pad"
@@ -583,3 +599,11 @@ msgstr "Avatar de perfil"
msgctxt "#31167"
msgid "Animate background"
msgstr "Animar fondo"
+
+msgctxt "#31168"
+msgid "Show posters instead of thumbs for musicvideos"
+msgstr "Mostrar carteles en lugar de miniaturas para vídeos musicales"
+
+msgctxt "#31169"
+msgid "Artwork related settings."
+msgstr "Ajustes relacionado con ilustraciones"
diff --git a/addons/skin.estuary/language/resource.language.et_ee/strings.po b/addons/skin.estuary/language/resource.language.et_ee/strings.po
index aa8b45757e..402bdebeb3 100644
--- a/addons/skin.estuary/language/resource.language.et_ee/strings.po
+++ b/addons/skin.estuary/language/resource.language.et_ee/strings.po
@@ -70,7 +70,7 @@ msgstr "Juhuslik album"
msgctxt "#31013"
msgid "Random artists"
-msgstr "Juhuslik artist"
+msgstr "Juhuslik esitaja"
msgctxt "#31014"
msgid "Unplayed albums"
@@ -152,6 +152,10 @@ msgctxt "#31033"
msgid "Your rating"
msgstr "Minu hinne"
+msgctxt "#31034"
+msgid "Extended info"
+msgstr "Laiendatud info"
+
msgctxt "#31035"
msgid "Pages"
msgstr "Lehed"
@@ -208,6 +212,10 @@ msgctxt "#31053"
msgid "Arial based"
msgstr "Arial-il põhinev"
+msgctxt "#31054"
+msgid "Press [B]Left[/B] to step back, or [B]Right[/B] to step forward"
+msgstr "Tagasihüppeks vajuta [B]vasakut[/B] või edasihüppeks [B]paremat[/B] klahvi"
+
msgctxt "#31056"
msgid "Go to playlist"
msgstr "Mine esitusloendisse"
@@ -522,7 +530,7 @@ msgstr "Juhuslik muusikavideo"
msgctxt "#31153"
msgid "You do not have any add-ons of this type installed. Enter the add-on browser to download add-ons created by our community."
-msgstr "Seda tüüpi lisamooduleid pole paigaldatud. Meie kasutajate poolt loodud lisamoodulite alla laadimiseks, mine lisamoodulite brauserisse."
+msgstr "Seda tüüpi lisamooduleid pole paigaldatud. Meie kasutajate poolt loodud lisamoodulite allalaadimiseks mine lisamoodulite brauserisse."
msgctxt "#31154"
msgid "Press OK to switch between locations"
@@ -579,3 +587,7 @@ msgstr "Profiili avatar"
msgctxt "#31167"
msgid "Animate background"
msgstr "Tausta animeerimine"
+
+msgctxt "#31168"
+msgid "Show posters instead of thumbs for musicvideos"
+msgstr "Kuva muusikavideote jaoks postereid mitte pisipilte"
diff --git a/addons/skin.estuary/language/resource.language.fi_fi/strings.po b/addons/skin.estuary/language/resource.language.fi_fi/strings.po
index 68f6465c12..e1dbbe1ac6 100644
--- a/addons/skin.estuary/language/resource.language.fi_fi/strings.po
+++ b/addons/skin.estuary/language/resource.language.fi_fi/strings.po
@@ -212,6 +212,14 @@ msgctxt "#31053"
msgid "Arial based"
msgstr "Arial-pohjainen"
+msgctxt "#31054"
+msgid "Press [B]Left[/B] to step back, or [B]Right[/B] to step forward"
+msgstr "Paina [B]Vasen[/B] palataksesi takaisinpäin tai [B]Oikea[/B] edetäksesi eteenpäin"
+
+msgctxt "#31055"
+msgid "Press [B]Right[/B] to frame advance"
+msgstr "Paina [B]Oikea[/B] edetäksesi kuva kerrallaan"
+
msgctxt "#31056"
msgid "Go to playlist"
msgstr "Avaa toistolista"
@@ -460,6 +468,10 @@ msgctxt "#31134"
msgid "Remaining"
msgstr "Jäljellä"
+msgctxt "#31135"
+msgid "Binary"
+msgstr "Binääri"
+
msgctxt "#31136"
msgid "Click here to see latest changes..."
msgstr "Valitse nähdäksesi viimeisimmät muutokset..."
@@ -516,6 +528,10 @@ msgctxt "#31149"
msgid "Select genre fanart pack"
msgstr "Valitse lajityyppien taustakuvapaketti"
+msgctxt "#31150"
+msgid "Origin"
+msgstr "Alkuperä"
+
msgctxt "#31151"
msgid "Unwatched music videos"
msgstr "Katsomattomat musiikkivideot"
@@ -583,3 +599,11 @@ msgstr "Profiilin kuva"
msgctxt "#31167"
msgid "Animate background"
msgstr "Animoitu taustakuva"
+
+msgctxt "#31168"
+msgid "Show posters instead of thumbs for musicvideos"
+msgstr "Näytä musiikkivideoille julisteet pienkuvien sijaan"
+
+msgctxt "#31169"
+msgid "Artwork related settings."
+msgstr "Mediakuvitukseen liittyvät asetukset."
diff --git a/addons/skin.estuary/language/resource.language.fr_fr/strings.po b/addons/skin.estuary/language/resource.language.fr_fr/strings.po
index 802e7ab4e8..5d2c8ee8db 100644
--- a/addons/skin.estuary/language/resource.language.fr_fr/strings.po
+++ b/addons/skin.estuary/language/resource.language.fr_fr/strings.po
@@ -234,7 +234,7 @@ msgstr "Identification auto. au démarrage"
msgctxt "#31059"
msgid "Select + X"
-msgstr "Sélectionner"
+msgstr "Sélectionner + X"
msgctxt "#31060"
msgid "Select + Start"
diff --git a/addons/skin.estuary/language/resource.language.gl_es/strings.po b/addons/skin.estuary/language/resource.language.gl_es/strings.po
index 60830d2aeb..d7717fa745 100644
--- a/addons/skin.estuary/language/resource.language.gl_es/strings.po
+++ b/addons/skin.estuary/language/resource.language.gl_es/strings.po
@@ -124,6 +124,10 @@ msgctxt "#31026"
msgid "Timeshift"
msgstr "Timeshift"
+msgctxt "#31027"
+msgid "Next aired"
+msgstr "Vindeira emisión"
+
msgctxt "#31028"
msgid "Show fanart"
msgstr "Amosar fanart"
@@ -160,6 +164,10 @@ msgctxt "#31036"
msgid "items"
msgstr "Elementos"
+msgctxt "#31037"
+msgid "Selected track"
+msgstr "Seleccionar pista"
+
msgctxt "#31038"
msgid "Rewind"
msgstr "Atrás"
@@ -204,6 +212,14 @@ msgctxt "#31053"
msgid "Arial based"
msgstr "Baseado en Arial"
+msgctxt "#31054"
+msgid "Press [B]Left[/B] to step back, or [B]Right[/B] to step forward"
+msgstr "Premer [B]Esquerda[/B] para rebobinar, ou [B]Dereita[/B] para avanzar"
+
+msgctxt "#31055"
+msgid "Press [B]Right[/B] to frame advance"
+msgstr "Premer [B]Dereita[/B] para avanzar un marco"
+
msgctxt "#31056"
msgid "Go to playlist"
msgstr "Ir á listaxe de reprodución"
@@ -216,6 +232,14 @@ msgctxt "#31058"
msgid "Automatic Login on startup"
msgstr "Amosar o inicio de sesión ao arrancar"
+msgctxt "#31059"
+msgid "Select + X"
+msgstr "Select + X"
+
+msgctxt "#31060"
+msgid "Select + Start"
+msgstr "Select + Inicio"
+
msgctxt "#31061"
msgid "Main menu items"
msgstr "Elementos do menú principal"
@@ -256,6 +280,10 @@ msgctxt "#31072"
msgid "Power Options"
msgstr "Opcións de enerxía"
+msgctxt "#31073"
+msgid "Total length"
+msgstr "Duración total"
+
msgctxt "#31074"
msgid "Total duration"
msgstr "Duración total"
@@ -440,6 +468,10 @@ msgctxt "#31134"
msgid "Remaining"
msgstr "Restante"
+msgctxt "#31135"
+msgid "Binary"
+msgstr "Binario"
+
msgctxt "#31136"
msgid "Click here to see latest changes..."
msgstr "Premer aquí para ver os últimos cambios..."
@@ -480,6 +512,14 @@ msgctxt "#31145"
msgid "Search add-ons"
msgstr "Buscar complementos"
+msgctxt "#31146"
+msgid "In cinemas"
+msgstr "Nos cinemas"
+
+msgctxt "#31147"
+msgid "In cinemas soon"
+msgstr "Nos cinemas proximamente"
+
msgctxt "#31148"
msgid "Categories"
msgstr "Categorías"
@@ -488,6 +528,10 @@ msgctxt "#31149"
msgid "Select genre fanart pack"
msgstr "Seleccionar o paquete fanart de xéneros"
+msgctxt "#31150"
+msgid "Origin"
+msgstr "Orixe"
+
msgctxt "#31151"
msgid "Unwatched music videos"
msgstr "Vídeos musicais sen ver"
@@ -555,3 +599,11 @@ msgstr "Avatar do perfil"
msgctxt "#31167"
msgid "Animate background"
msgstr "Animar o fondo"
+
+msgctxt "#31168"
+msgid "Show posters instead of thumbs for musicvideos"
+msgstr "Amosar pósters no canto de miniaturas para musicvideos"
+
+msgctxt "#31169"
+msgid "Artwork related settings."
+msgstr "Axustes relacionados cas Imaxes"
diff --git a/addons/skin.estuary/language/resource.language.hu_hu/strings.po b/addons/skin.estuary/language/resource.language.hu_hu/strings.po
index 7a46c77882..99aec02b6a 100644
--- a/addons/skin.estuary/language/resource.language.hu_hu/strings.po
+++ b/addons/skin.estuary/language/resource.language.hu_hu/strings.po
@@ -212,6 +212,14 @@ msgctxt "#31053"
msgid "Arial based"
msgstr "Arial betűkészlet"
+msgctxt "#31054"
+msgid "Press [B]Left[/B] to step back, or [B]Right[/B] to step forward"
+msgstr "Nyomja meg a [B]Bal[/B] gombot a vissza-, vagy a [B]Jobb[/B] gombot az előrelépéshez"
+
+msgctxt "#31055"
+msgid "Press [B]Right[/B] to frame advance"
+msgstr "Nyomja meg a [B]Jobb[/B] gombot a képkocka léptetéséhez"
+
msgctxt "#31056"
msgid "Go to playlist"
msgstr "Lejátszólistához"
@@ -460,6 +468,10 @@ msgctxt "#31134"
msgid "Remaining"
msgstr "Hátralévő"
+msgctxt "#31135"
+msgid "Binary"
+msgstr "Bináris"
+
msgctxt "#31136"
msgid "Click here to see latest changes..."
msgstr "Legfrissebb változtatások..."
@@ -516,6 +528,10 @@ msgctxt "#31149"
msgid "Select genre fanart pack"
msgstr "Műfaj illusztrációs csomag kiválasztása"
+msgctxt "#31150"
+msgid "Origin"
+msgstr "Eredet"
+
msgctxt "#31151"
msgid "Unwatched music videos"
msgstr "Nem látott videóklipek"
@@ -583,3 +599,11 @@ msgstr "Profil avatar"
msgctxt "#31167"
msgid "Animate background"
msgstr "Animált háttér"
+
+msgctxt "#31168"
+msgid "Show posters instead of thumbs for musicvideos"
+msgstr "Poszterek megjelenítése bélyegképek helyett a zenei videóknál"
+
+msgctxt "#31169"
+msgid "Artwork related settings."
+msgstr "Illusztrációval kapcsolatos beállítások."
diff --git a/addons/skin.estuary/language/resource.language.is_is/strings.po b/addons/skin.estuary/language/resource.language.is_is/strings.po
index 6a4dddb6c4..f5f04cd14f 100644
--- a/addons/skin.estuary/language/resource.language.is_is/strings.po
+++ b/addons/skin.estuary/language/resource.language.is_is/strings.po
@@ -124,6 +124,10 @@ msgctxt "#31026"
msgid "Timeshift"
msgstr "Tímaflakk"
+msgctxt "#31027"
+msgid "Next aired"
+msgstr "Næst sýnt"
+
msgctxt "#31028"
msgid "Show fanart"
msgstr "Birta aðdáendamyndir"
@@ -160,6 +164,10 @@ msgctxt "#31036"
msgid "items"
msgstr "atriði"
+msgctxt "#31037"
+msgid "Selected track"
+msgstr "Valin rás"
+
msgctxt "#31038"
msgid "Rewind"
msgstr "Til baka"
@@ -204,6 +212,10 @@ msgctxt "#31053"
msgid "Arial based"
msgstr "Byggt á Arial"
+msgctxt "#31054"
+msgid "Press [B]Left[/B] to step back, or [B]Right[/B] to step forward"
+msgstr "Ýttu á [B]Vinstri[/B] til að hoppa til baka, eða [B]Hægri[/B] til að hoppa áfram"
+
msgctxt "#31056"
msgid "Go to playlist"
msgstr "Fara í spilunarlista"
@@ -216,6 +228,14 @@ msgctxt "#31058"
msgid "Automatic Login on startup"
msgstr "Sjálfvirk innskráning í ræsingu"
+msgctxt "#31059"
+msgid "Select + X"
+msgstr "Val + X"
+
+msgctxt "#31060"
+msgid "Select + Start"
+msgstr "Val + Start"
+
msgctxt "#31061"
msgid "Main menu items"
msgstr "Atriði í aðalvalmynd"
@@ -256,6 +276,10 @@ msgctxt "#31072"
msgid "Power Options"
msgstr "Valkostir orkustýringar"
+msgctxt "#31073"
+msgid "Total length"
+msgstr "Heildarlengd"
+
msgctxt "#31074"
msgid "Total duration"
msgstr "Heildar tímalengd"
@@ -480,6 +504,14 @@ msgctxt "#31145"
msgid "Search add-ons"
msgstr "Leita að viðbótum"
+msgctxt "#31146"
+msgid "In cinemas"
+msgstr "Í kvikmyndahúsum"
+
+msgctxt "#31147"
+msgid "In cinemas soon"
+msgstr "Bráðlega í kvikmyndahúsum"
+
msgctxt "#31148"
msgid "Categories"
msgstr "Flokkar"
diff --git a/addons/skin.estuary/language/resource.language.ja_jp/strings.po b/addons/skin.estuary/language/resource.language.ja_jp/strings.po
index 111b27a1ab..fb154e25e2 100644
--- a/addons/skin.estuary/language/resource.language.ja_jp/strings.po
+++ b/addons/skin.estuary/language/resource.language.ja_jp/strings.po
@@ -212,6 +212,14 @@ msgctxt "#31053"
msgid "Arial based"
msgstr "Arialベース"
+msgctxt "#31054"
+msgid "Press [B]Left[/B] to step back, or [B]Right[/B] to step forward"
+msgstr "[B]左[/B] を押してバックか、[B右[/B] を押してフォワード"
+
+msgctxt "#31055"
+msgid "Press [B]Right[/B] to frame advance"
+msgstr "[B]右[/B] を押してフレームを進める"
+
msgctxt "#31056"
msgid "Go to playlist"
msgstr "プレイリストに移動"
@@ -460,6 +468,10 @@ msgctxt "#31134"
msgid "Remaining"
msgstr "残り"
+msgctxt "#31135"
+msgid "Binary"
+msgstr "バイナリー"
+
msgctxt "#31136"
msgid "Click here to see latest changes..."
msgstr "ここをクリックして最近の変更を見る..."
@@ -516,6 +528,10 @@ msgctxt "#31149"
msgid "Select genre fanart pack"
msgstr "ジャンルのファンアートパック選択"
+msgctxt "#31150"
+msgid "Origin"
+msgstr "オリジン"
+
msgctxt "#31151"
msgid "Unwatched music videos"
msgstr "未視聴なミュージックビデオ"
@@ -583,3 +599,11 @@ msgstr "プロファイルアバター"
msgctxt "#31167"
msgid "Animate background"
msgstr "アニメーション背景"
+
+msgctxt "#31168"
+msgid "Show posters instead of thumbs for musicvideos"
+msgstr "ミュージックビデオのサムネイルの代わりにポスターを表示する"
+
+msgctxt "#31169"
+msgid "Artwork related settings."
+msgstr "アートワーク関連の設定。"
diff --git a/addons/skin.estuary/language/resource.language.pt_br/strings.po b/addons/skin.estuary/language/resource.language.pt_br/strings.po
index 12e594734c..6577bb2162 100644
--- a/addons/skin.estuary/language/resource.language.pt_br/strings.po
+++ b/addons/skin.estuary/language/resource.language.pt_br/strings.po
@@ -212,6 +212,14 @@ msgctxt "#31053"
msgid "Arial based"
msgstr "Baseado na Arial"
+msgctxt "#31054"
+msgid "Press [B]Left[/B] to step back, or [B]Right[/B] to step forward"
+msgstr "Pressione [B]Esquerda[/B] para recuar ou [B]Direita[/B] para avançar"
+
+msgctxt "#31055"
+msgid "Press [B]Right[/B] to frame advance"
+msgstr "Pressione [B]Direita[/B] para avançar quadro"
+
msgctxt "#31056"
msgid "Go to playlist"
msgstr "Ir para playlist"
@@ -460,6 +468,10 @@ msgctxt "#31134"
msgid "Remaining"
msgstr "Remanescente"
+msgctxt "#31135"
+msgid "Binary"
+msgstr "Binário"
+
msgctxt "#31136"
msgid "Click here to see latest changes..."
msgstr "Clique aqui para visualizar as últimas alterações..."
@@ -516,6 +528,10 @@ msgctxt "#31149"
msgid "Select genre fanart pack"
msgstr "Selecione o pacote de fanart de gêneros"
+msgctxt "#31150"
+msgid "Origin"
+msgstr "Origem"
+
msgctxt "#31151"
msgid "Unwatched music videos"
msgstr "Videoclipes a assistir"
@@ -583,3 +599,11 @@ msgstr "Imagem do perfil"
msgctxt "#31167"
msgid "Animate background"
msgstr "Pano de Fundo animado"
+
+msgctxt "#31168"
+msgid "Show posters instead of thumbs for musicvideos"
+msgstr "Mostrar pôsteres ao invés de miniaturas para concertos"
+
+msgctxt "#31169"
+msgid "Artwork related settings."
+msgstr "Ajustes relacionados a artes"
diff --git a/addons/skin.estuary/language/resource.language.sl_si/strings.po b/addons/skin.estuary/language/resource.language.sl_si/strings.po
index 67da8f9557..aaf7da4f3e 100644
--- a/addons/skin.estuary/language/resource.language.sl_si/strings.po
+++ b/addons/skin.estuary/language/resource.language.sl_si/strings.po
@@ -128,6 +128,10 @@ msgctxt "#31053"
msgid "Arial based"
msgstr "Arial"
+msgctxt "#31066"
+msgid "Music playlist"
+msgstr "Seznam predvajanja glasbe"
+
msgctxt "#31067"
msgid "Event log"
msgstr "Zapisnik dogodkov"
diff --git a/addons/skin.estuary/language/resource.language.sv_se/strings.po b/addons/skin.estuary/language/resource.language.sv_se/strings.po
index 9a5f5e2a04..dabf26cf01 100644
--- a/addons/skin.estuary/language/resource.language.sv_se/strings.po
+++ b/addons/skin.estuary/language/resource.language.sv_se/strings.po
@@ -54,7 +54,7 @@ msgstr "Aktivera gränssnittskomponenter för kategorier"
msgctxt "#31009"
msgid "Download icons"
-msgstr "Ladda ner ikoner"
+msgstr "Hämtar ikoner"
msgctxt "#31010"
msgid "In progress movies"
@@ -82,7 +82,7 @@ msgstr "Nya inspelningar"
msgctxt "#31016"
msgid "Recently played channels"
-msgstr "Senast spelade kanaler"
+msgstr "Nyligen spelade kanaler"
msgctxt "#31017"
msgid "Rated"
@@ -90,7 +90,7 @@ msgstr "Betygsatt"
msgctxt "#31018"
msgid "Recently played channels"
-msgstr "Senast spelade kanaler"
+msgstr "Nyligen spelade kanaler"
msgctxt "#31019"
msgid "Forecast"
@@ -166,7 +166,7 @@ msgstr "objekt"
msgctxt "#31037"
msgid "Selected track"
-msgstr "Valda spår"
+msgstr "Markerat spår"
msgctxt "#31038"
msgid "Rewind"
@@ -198,7 +198,7 @@ msgstr "Byt namn på grupp"
msgctxt "#31046"
msgid "Delete group"
-msgstr "Radera grupp"
+msgstr "Ta bort grupp"
msgctxt "#31048"
msgid "Available"
@@ -246,7 +246,7 @@ msgstr "Spellista för musik"
msgctxt "#31067"
msgid "Event log"
-msgstr "Eventlogg"
+msgstr "Händelselogg"
msgctxt "#31068"
msgid "Choose presets"
@@ -286,11 +286,11 @@ msgstr "Slutar"
msgctxt "#31082"
msgid "Lyrics add-on"
-msgstr "Sångtexter tillägg"
+msgstr "Tillägg för sångtexter"
msgctxt "#31083"
msgid "Lyrics add-on settings"
-msgstr "Sångtexter tilläggsinställningar"
+msgstr "Inställningar för sångtexttillägg"
msgctxt "#31084"
msgid "Visualisation settings"
@@ -366,7 +366,7 @@ msgstr "Gå till filsektionen"
msgctxt "#31111"
msgid "View your personal pictures or download one of the many image add-ons from the official repository."
-msgstr "Visa dina personliga bilder eller ladda ner en av de många bild tilläggen från det officiella förrådet."
+msgstr "Visa dina personliga bilder eller hämta en av de många bild tilläggen från det officiella förrådet."
msgctxt "#31112"
msgid "Toggle audio stream"
@@ -394,7 +394,7 @@ msgstr "Gå till tilläggsutforskaren"
msgctxt "#31119"
msgid "You do not have any add-ons installed yet. Visit our add-on browser to browse through our collection and improve your Kodi experience."
-msgstr "Du har inte några tillägg installerade ännu. Besök vår tilläggsutforskare för att bläddra igenom vår samling och förbättra din Kodi upplevelse."
+msgstr "Du har inte några tillägg installerade ännu. Besök vår tilläggsutforskare för att bläddra igenom vår samling och förbättra din Kodi-upplevelse."
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."
@@ -452,6 +452,10 @@ msgctxt "#31134"
msgid "Remaining"
msgstr "Återstående"
+msgctxt "#31135"
+msgid "Binary"
+msgstr "Binär"
+
msgctxt "#31136"
msgid "Click here to see latest changes..."
msgstr "Klicka här för att se de senaste ändringarna..."
@@ -554,7 +558,7 @@ msgstr "Numerisk knappsats"
msgctxt "#31162"
msgid "Play your personal games or download one of the many game add-ons from the official repository."
-msgstr "Spela dina egna spel eller ladda ned någon av de många speltillägg från det officiella förrådet."
+msgstr "Spela dina egna spel eller hämta någon av de många speltilläggen från det officiella förrådet."
msgctxt "#31163"
msgid "Show Fanart background"
@@ -575,3 +579,7 @@ msgstr "Profil avatar"
msgctxt "#31167"
msgid "Animate background"
msgstr "Animera bakgrund"
+
+msgctxt "#31169"
+msgid "Artwork related settings."
+msgstr "Inställningar för omslag."
diff --git a/addons/skin.estuary/language/resource.language.zh_cn/strings.po b/addons/skin.estuary/language/resource.language.zh_cn/strings.po
index 581fe86652..7454334eb7 100644
--- a/addons/skin.estuary/language/resource.language.zh_cn/strings.po
+++ b/addons/skin.estuary/language/resource.language.zh_cn/strings.po
@@ -212,6 +212,14 @@ msgctxt "#31053"
msgid "Arial based"
msgstr "基于 Arial 字体"
+msgctxt "#31054"
+msgid "Press [B]Left[/B] to step back, or [B]Right[/B] to step forward"
+msgstr "按[B]左[/B]后退,或按[B]右[/B]快进"
+
+msgctxt "#31055"
+msgid "Press [B]Right[/B] to frame advance"
+msgstr "按[B]右[/B]以帧快进"
+
msgctxt "#31056"
msgid "Go to playlist"
msgstr "进入播放列表"
@@ -516,6 +524,10 @@ msgctxt "#31149"
msgid "Select genre fanart pack"
msgstr "选择类型同人画包"
+msgctxt "#31150"
+msgid "Origin"
+msgstr "原始"
+
msgctxt "#31151"
msgid "Unwatched music videos"
msgstr "未观看音乐电视"
@@ -583,3 +595,11 @@ msgstr "用户配置头像"
msgctxt "#31167"
msgid "Animate background"
msgstr "动态背景"
+
+msgctxt "#31168"
+msgid "Show posters instead of thumbs for musicvideos"
+msgstr "对于音乐电视,显示海报而不是缩略图"
+
+msgctxt "#31169"
+msgid "Artwork related settings."
+msgstr "艺术图片相关的设置。"
diff --git a/addons/skin.estuary/xml/MusicVisualisation.xml b/addons/skin.estuary/xml/MusicVisualisation.xml
index 23a2da5411..fbfd03770b 100644
--- a/addons/skin.estuary/xml/MusicVisualisation.xml
+++ b/addons/skin.estuary/xml/MusicVisualisation.xml
@@ -94,7 +94,7 @@
<orientation>horizontal</orientation>
<itemgap>20</itemgap>
<control type="label">
- <width>90</width>
+ <width>100</width>
<height>40</height>
<label>$INFO[MusicPlayer.Year]</label>
<font>font37</font>
diff --git a/docs/manpages/TexturePacker.1 b/docs/manpages/TexturePacker.1
new file mode 100644
index 0000000000..553625b8c1
--- /dev/null
+++ b/docs/manpages/TexturePacker.1
@@ -0,0 +1,24 @@
+.TH TexturePacker 1
+.SH NAME
+TexturePacker \- Compile all images used in a XBMC / Kodi skin into a single file
+.SH SYNOPSIS
+.B TexturePacker
+[\fB\-dupecheck\fR]
+[\fB\-\-input\fR \fIDIRECTORY\fR]
+[\fB\-\-output\fR \fIFILE.xbt\fR]
+.SH DESCRIPTION
+Kodi uses a tool named TexturePacker to compile all images used in a skin into a single file. The benefit of it is that images inside the Textures.xbt will load faster in the skin. This is done by converting all images into a format that take less processing by Kodi when they need to be rendered onto the screen.
+
+A common misconception is that TexturPacker will just compress the images into a single file. This if far from the truth, so don't be surprised if the Textures.xbt file is much larger than the total size of all the individual images.
+
+The optional -dupecheck option is useful if you have included the same image multiple times in your media folder. For example, if your skin includes a lot of studio logos, most likely a lot of them are included multiple times but with a slightly different filename. The '-dupecheck' option will make sure each unique image is included only once in the Textures.xbt file, thus keeping the size of it as small as possible.
+.SH OPTIONS
+.TP
+.BR \-dupecheck
+Check for image duplicates first
+.TP
+.BR \-input
+fully-qualified name of input directory with images
+.TP
+.BR \-output
+fully-qualified name of resulting compressed XBT file
diff --git a/docs/manpages/kodi-wiiremote.1 b/docs/manpages/kodi-wiiremote.1
index 7b0ced839a..b947c93ef2 100644
--- a/docs/manpages/kodi-wiiremote.1
+++ b/docs/manpages/kodi-wiiremote.1
@@ -1,5 +1,5 @@
.\" DO NOT MODIFY THIS FILE! It was generated by help2man 1.36.
-.TH KODI-WIIREMOTE "1" "October 20014" "kodi-wiiremote " "User Commands"
+.TH KODI-WIIREMOTE "1" "October 2014" "kodi-wiiremote " "User Commands"
.SH NAME
kodi-wiiremote \- Wiimote Remote Control Client for Kodi
.SH DESCRIPTION
diff --git a/docs/manpages/kodi.bin.1 b/docs/manpages/kodi.bin.1
index 80ef889212..35c8702d1b 100644
--- a/docs/manpages/kodi.bin.1
+++ b/docs/manpages/kodi.bin.1
@@ -20,12 +20,14 @@ enables network settings.
\fB\-p\fR or \fB\-\-portable\fR
Kodi will look for configurations in install folder instead of ~/.kodi
.TP
-\fB\-\-legacy\-res\fR
-Enables screen resolutions such as PAL, NTSC, etc.
+\fB\-\-version\fR
+Print version information.
.TP
-\fB\-l\fR or \fB\-\-lircdev\fR
-LircDevice to use. See \-\-help output for the default.
+\fB\-\-test\fR [\fIFILE\fR]
+Enable test mode. \fIFILE\fR must be readable.
.TP
-\fB\-n\fR or \fB\-\-nolirc\fR
-do not use Lirc, aka no remote input.
-.PP
+\fB\-\-settings=\fR<\fIfilename\fR>
+Loads specified file after advancedsettings.xml replacing any settings specified. The \fIfilename\fR must exist in special://xbmc/system/.
+.TP
+\fB\-\-windowing=\fR<\fIsystem\fR>
+Select which windowing method to use. Available window systems are: x11 wayland gbm
diff --git a/system/shaders/guishader_common.hlsl b/system/shaders/guishader_common.hlsl
index 0f2a7a7c47..1d8fa10e56 100644
--- a/system/shaders/guishader_common.hlsl
+++ b/system/shaders/guishader_common.hlsl
@@ -47,8 +47,39 @@ cbuffer cbWorld : register(b0)
float4x4 worldViewProj;
float blackLevel;
float colorRange;
+ int PQ;
};
+inline float3 transferPQ(float3 x)
+{
+ static const float ST2084_m1 = 2610.0f / (4096.0f * 4.0f);
+ static const float ST2084_m2 = (2523.0f / 4096.0f) * 128.0f;
+ static const float ST2084_c1 = 3424.0f / 4096.0f;
+ static const float ST2084_c2 = (2413.0f / 4096.0f) * 32.0f;
+ static const float ST2084_c3 = (2392.0f / 4096.0f) * 32.0f;
+ static const float SDR_peak_lum = 100.0f;
+ static const float3x3 matx =
+ {
+ 0.627402, 0.329292, 0.043306,
+ 0.069095, 0.919544, 0.011360,
+ 0.016394, 0.088028, 0.895578
+ };
+ // REC.709 to linear
+ x = pow(x, 1.0f / 0.45f);
+ // REC.709 to BT.2020
+ x = mul(matx, x);
+ // linear to PQ
+ x = pow(x / SDR_peak_lum, ST2084_m1);
+ x = (ST2084_c1 + ST2084_c2 * x) / (1.0f + ST2084_c3 * x);
+ x = pow(x, ST2084_m2);
+ return x;
+}
+
+inline float4 tonemapHDR(float4 color)
+{
+ return (PQ) ? float4(transferPQ(color.rgb), color.a) : color;
+}
+
inline float4 adjustColorRange(float4 color)
{
return float4(blackLevel + colorRange * color.rgb, color.a);
diff --git a/system/shaders/guishader_default.hlsl b/system/shaders/guishader_default.hlsl
index cf4183a0f9..82b6510c77 100644
--- a/system/shaders/guishader_default.hlsl
+++ b/system/shaders/guishader_default.hlsl
@@ -22,7 +22,7 @@
float4 PS(PS_INPUT input) : SV_TARGET
{
- return adjustColorRange(input.color);
+ return tonemapHDR(adjustColorRange(input.color));
}
diff --git a/system/shaders/guishader_fonts.hlsl b/system/shaders/guishader_fonts.hlsl
index def887d162..59c2ffec90 100644
--- a/system/shaders/guishader_fonts.hlsl
+++ b/system/shaders/guishader_fonts.hlsl
@@ -25,7 +25,7 @@ Texture2D texFont : register(t0);
float4 PS(PS_INPUT input) : SV_TARGET
{
input.color.a *= texFont.Sample(LinearSampler, input.tex).r;
- return adjustColorRange(input.color);
+ return tonemapHDR(adjustColorRange(input.color));
}
diff --git a/system/shaders/guishader_multi_texture_blend.hlsl b/system/shaders/guishader_multi_texture_blend.hlsl
index 33f1f0fbd3..77c2e79255 100644
--- a/system/shaders/guishader_multi_texture_blend.hlsl
+++ b/system/shaders/guishader_multi_texture_blend.hlsl
@@ -24,8 +24,8 @@ Texture2D txDiffuse[2] : register(t0);
float4 PS(PS_INPUT input) : SV_TARGET
{
- return adjustColorRange(input.color * txDiffuse[0].Sample(LinearSampler, input.tex)
- * txDiffuse[1].Sample(LinearSampler, input.tex2));
+ return tonemapHDR(adjustColorRange(input.color * txDiffuse[0].Sample(LinearSampler, input.tex) *
+ txDiffuse[1].Sample(LinearSampler, input.tex2)));
}
diff --git a/system/shaders/guishader_texture.hlsl b/system/shaders/guishader_texture.hlsl
index 845747ec41..665aff0abb 100644
--- a/system/shaders/guishader_texture.hlsl
+++ b/system/shaders/guishader_texture.hlsl
@@ -24,7 +24,7 @@ Texture2D texMain : register(t0);
float4 PS(PS_INPUT input) : SV_TARGET
{
- return adjustColorRange(input.color * texMain.Sample(LinearSampler, input.tex));
+ return tonemapHDR(adjustColorRange(input.color * texMain.Sample(LinearSampler, input.tex)));
}
diff --git a/tools/EventClients/Clients/KodiSend/kodi-send.py b/tools/EventClients/Clients/KodiSend/kodi-send.py
index 09bd4f145e..e685ba92b2 100755
--- a/tools/EventClients/Clients/KodiSend/kodi-send.py
+++ b/tools/EventClients/Clients/KodiSend/kodi-send.py
@@ -1,4 +1,4 @@
-#!/usr/bin/python3
+#!/usr/bin/env python3
#
# XBMC Media Center
# XBMC Send
diff --git a/tools/EventClients/Clients/PS3BDRemote/ps3_remote.py b/tools/EventClients/Clients/PS3BDRemote/ps3_remote.py
index a9f99fb2e3..72ae71a22d 100755
--- a/tools/EventClients/Clients/PS3BDRemote/ps3_remote.py
+++ b/tools/EventClients/Clients/PS3BDRemote/ps3_remote.py
@@ -1,4 +1,4 @@
-#!/usr/bin/python
+#!/usr/bin/env python3
# -*- coding: utf-8 -*-
# Copyright (C) 2008-2013 Team XBMC
diff --git a/tools/EventClients/Clients/PS3SixaxisController/ps3d.py b/tools/EventClients/Clients/PS3SixaxisController/ps3d.py
index f961cf8d33..32ed361b9e 100755
--- a/tools/EventClients/Clients/PS3SixaxisController/ps3d.py
+++ b/tools/EventClients/Clients/PS3SixaxisController/ps3d.py
@@ -1,4 +1,4 @@
-#!/usr/bin/python
+#!/usr/bin/env python3
# -*- coding: utf-8 -*-
# Copyright (C) 2008-2013 Team XBMC
diff --git a/tools/EventClients/examples/c#/XBMCDemoClient1.cs b/tools/EventClients/examples/c#/XBMCDemoClient1.cs
index c837ab1a83..df74dea41f 100644
--- a/tools/EventClients/examples/c#/XBMCDemoClient1.cs
+++ b/tools/EventClients/examples/c#/XBMCDemoClient1.cs
@@ -1,5 +1,6 @@
using System;
using System.Collections.Generic;
+using System.IO;
using System.Windows.Forms;
using XBMC;
@@ -13,11 +14,22 @@ namespace XBMCEventClientDemo
[STAThread]
static void Main()
{
- EventClient eventClient = new EventClient();
- eventClient.Connect("127.0.0.1", 9777);
- eventClient.SendHelo("XBMC Client Demo", IconType.ICON_PNG, "icon.png");
+ EventClient eventClient = new EventClient();
+ eventClient.Connect("127.0.0.1", 9777);
+
+ string iconFile = @"../../icons/icon.png";
+ IconType iconType = IconType.ICON_PNG;
+
+ if !File.Exists(iconFile) {
+ iconFile = @"/usr/share/xbmc/media/icon.png";
+ if !File.Exists(iconFile) {
+ iconType = IconType.ICON_NONE;
+ }
+ }
+
+ eventClient.SendHelo("XBMC Client Demo", iconType, iconFile);
System.Threading.Thread.Sleep(1000);
- eventClient.SendNotification("XBMC Client Demo", "Notification Message", IconType.ICON_PNG, "/usr/share/xbmc/media/icon.png");
+ eventClient.SendNotification("XBMC Client Demo", "Notification Message", iconType, iconFile);
System.Threading.Thread.Sleep(1000);
eventClient.SendButton("dpadup", "XG", ButtonFlagsType.BTN_DOWN | ButtonFlagsType.BTN_NO_REPEAT, 0);
System.Threading.Thread.Sleep(1000);
diff --git a/tools/EventClients/examples/c++/example_button1.cpp b/tools/EventClients/examples/c++/example_button1.cpp
index a980e3da24..d96f2681f3 100644
--- a/tools/EventClients/examples/c++/example_button1.cpp
+++ b/tools/EventClients/examples/c++/example_button1.cpp
@@ -2,6 +2,11 @@
#include <stdio.h>
#include <string.h>
#include <sys/socket.h>
+#ifdef _WIN32
+#include <Windows.h> // for sleep
+#else
+#include <unistd.h>
+#endif
int main(int argc, char **argv)
{
@@ -19,7 +24,29 @@ int main(int argc, char **argv)
my_addr.Bind(sockfd);
- CPacketHELO HeloPackage("Example Remote", ICON_PNG, "../../icons/bluetooth.png");
+ std::string sIconFile = "../../icons/bluetooth.png";
+ unsigned short usIconType = ICON_PNG;
+
+ std::ifstream file (sIconFile, std::ios::in|std::ios::binary|std::ios::ate);
+ if (!file.is_open())
+ {
+ sIconFile = "/usr/share/pixmaps/kodi/bluetooth.png";
+ file.open(sIconFile, std::ios::in|std::ios::binary|std::ios::ate);
+
+ if (!file.is_open()) {
+ usIconType = ICON_NONE;
+ }
+ else
+ {
+ file.close();
+ }
+ }
+ else
+ {
+ file.close();
+ }
+
+ CPacketHELO HeloPackage("Example Remote", usIconType, sIconFile.c_str());
HeloPackage.Send(sockfd, my_addr);
sleep(5);
diff --git a/tools/EventClients/examples/c++/example_button2.cpp b/tools/EventClients/examples/c++/example_button2.cpp
index 852e49f9a2..ddb55be644 100644
--- a/tools/EventClients/examples/c++/example_button2.cpp
+++ b/tools/EventClients/examples/c++/example_button2.cpp
@@ -2,6 +2,11 @@
#include <stdio.h>
#include <string.h>
#include <sys/socket.h>
+#ifdef _WIN32
+#include <Windows.h> // for sleep
+#else
+#include <unistd.h>
+#endif
int main(int argc, char **argv)
{
@@ -19,22 +24,44 @@ int main(int argc, char **argv)
my_addr.Bind(sockfd);
- CPacketHELO HeloPackage("Example Remote", ICON_PNG, "../../icons/bluetooth.png");
+ std::string sIconFile = "../../icons/bluetooth.png";
+ unsigned short usIconType = ICON_PNG;
+
+ std::ifstream file (sIconFile, std::ios::in|std::ios::binary|std::ios::ate);
+ if (!file.is_open())
+ {
+ sIconFile = "/usr/share/pixmaps/kodi/bluetooth.png";
+ file.open(sIconFile, std::ios::in|std::ios::binary|std::ios::ate);
+
+ if (!file.is_open()) {
+ usIconType = ICON_NONE;
+ }
+ else
+ {
+ file.close();
+ }
+ }
+ else
+ {
+ file.close();
+ }
+
+ CPacketHELO HeloPackage("Example Remote", usIconType, sIconFile.c_str());
HeloPackage.Send(sockfd, my_addr);
sleep(5);
// Note that we have foo(BUTTON, DEVICEMAP);
- CPacketBUTTON btn1("dpadup", "XG");
+ CPacketBUTTON btn1("dpadup", "XG", 0);
btn1.Send(sockfd, my_addr);
sleep(5);
- CPacketBUTTON btn2(0x28);
+ CPacketBUTTON btn2(0x28, 0);
btn2.Send(sockfd, my_addr);
sleep(5);
- CPacketBUTTON btn3("right", "KB");
+ CPacketBUTTON btn3("right", "KB", 0);
btn3.Send(sockfd, my_addr);
sleep(5);
diff --git a/tools/EventClients/examples/c++/example_log.cpp b/tools/EventClients/examples/c++/example_log.cpp
index 6194ed9c51..ca61cb04fd 100644
--- a/tools/EventClients/examples/c++/example_log.cpp
+++ b/tools/EventClients/examples/c++/example_log.cpp
@@ -2,6 +2,11 @@
#include <stdio.h>
#include <string.h>
#include <sys/socket.h>
+#ifdef _WIN32
+#include <Windows.h> // for sleep
+#else
+#include <unistd.h>
+#endif
int main(int argc, char **argv)
{
diff --git a/tools/EventClients/examples/c++/example_mouse.cpp b/tools/EventClients/examples/c++/example_mouse.cpp
index 23f40d3de8..a0c583285c 100644
--- a/tools/EventClients/examples/c++/example_mouse.cpp
+++ b/tools/EventClients/examples/c++/example_mouse.cpp
@@ -2,6 +2,11 @@
#include <stdio.h>
#include <string.h>
#include <sys/socket.h>
+#ifdef _WIN32
+#include <Windows.h> // for sleep
+#else
+#include <unistd.h>
+#endif
int main(int argc, char **argv)
{
@@ -19,7 +24,29 @@ int main(int argc, char **argv)
my_addr.Bind(sockfd);
- CPacketHELO HeloPackage("Example Mouse", ICON_PNG, "../../icons/mouse.png");
+ std::string sIconFile = "../../icons/mouse.png";
+ unsigned short usIconType = ICON_PNG;
+
+ std::ifstream file (sIconFile, std::ios::in|std::ios::binary|std::ios::ate);
+ if (!file.is_open())
+ {
+ sIconFile = "/usr/share/pixmaps/kodi/mouse.png";
+ file.open(sIconFile, std::ios::in|std::ios::binary|std::ios::ate);
+
+ if (!file.is_open()) {
+ usIconType = ICON_NONE;
+ }
+ else
+ {
+ file.close();
+ }
+ }
+ else
+ {
+ file.close();
+ }
+
+ CPacketHELO HeloPackage("Example Mouse", usIconType, sIconFile.c_str());
HeloPackage.Send(sockfd, my_addr);
sleep(5);
diff --git a/tools/EventClients/examples/c++/example_notification.cpp b/tools/EventClients/examples/c++/example_notification.cpp
index dc51075b85..5cd0657444 100644
--- a/tools/EventClients/examples/c++/example_notification.cpp
+++ b/tools/EventClients/examples/c++/example_notification.cpp
@@ -2,6 +2,11 @@
#include <stdio.h>
#include <string.h>
#include <sys/socket.h>
+#ifdef _WIN32
+#include <Windows.h> // for sleep
+#else
+#include <unistd.h>
+#endif
int main(int argc, char **argv)
{
@@ -20,6 +25,28 @@ int main(int argc, char **argv)
my_addr.Bind(sockfd);
+ std::string sIconFile = "../../icons/mail.png";
+ unsigned short usIconType = ICON_PNG;
+
+ std::ifstream file (sIconFile, std::ios::in|std::ios::binary|std::ios::ate);
+ if (!file.is_open())
+ {
+ sIconFile = "/usr/share/pixmaps/kodi/mail.png";
+ file.open(sIconFile, std::ios::in|std::ios::binary|std::ios::ate);
+
+ if (!file.is_open()) {
+ usIconType = ICON_NONE;
+ }
+ else
+ {
+ file.close();
+ }
+ }
+ else
+ {
+ file.close();
+ }
+
CPacketHELO HeloPackage("Email Notifier", ICON_NONE);
HeloPackage.Send(sockfd, my_addr);
@@ -27,8 +54,8 @@ int main(int argc, char **argv)
CPacketNOTIFICATION packet("New Mail!", // caption
"RE: Check this out", // message
- ICON_PNG, // optional icon type
- "../../icons/mail.png"); // icon file (local)
+ usIconType, // optional icon type
+ sIconFile.c_str()); // icon file (local)
packet.Send(sockfd, my_addr);
// BYE is not required since XBMC would have shut down
diff --git a/tools/EventClients/examples/java/XBMCDemoClient1.java b/tools/EventClients/examples/java/XBMCDemoClient1.java
index 922d4d64ed..5bb2821eb4 100644
--- a/tools/EventClients/examples/java/XBMCDemoClient1.java
+++ b/tools/EventClients/examples/java/XBMCDemoClient1.java
@@ -1,5 +1,6 @@
package org.xbmc.eventclient.demo;
+import java.io.File;
import java.io.IOException;
import java.net.Inet4Address;
import java.net.InetAddress;
@@ -18,10 +19,27 @@ public class XBMCDemoClient1 {
* @param args
*/
public static void main(String[] args) throws IOException, InterruptedException {
- InetAddress host = Inet4Address.getByAddress(new byte[] { (byte)192, (byte)168, 0, 20 } );
+ InetAddress host = Inet4Address.getByAddress(new byte[] { (byte)127, 0, 0, 1 } );
Thread.sleep(20000);
- XBMCClient oXBMCClient = new XBMCClient(host, 9777, "My Client", "/usr/share/xbmc/media/icon.png");
+
+ String iconFile = "/usr/share/xbmc/media/icon.png";
+
+ if (! new File(iconFile).exists()) {
+ iconFile = "../../icons/icon.png";
+
+ if (! new File(iconFile).exists()) {
+ iconFile = "";
+ }
+ }
+
+ XBMCClient oXBMCClient = null;
+
+ if (iconFile != "") {
+ oXBMCClient = new XBMCClient(host, 9777, "My Client", iconFile);
+ } else {
+ oXBMCClient = new XBMCClient(host, 9777, "My Client");
+ }
Thread.sleep(7000);
diff --git a/tools/EventClients/examples/python/example_action.py b/tools/EventClients/examples/python/example_action.py
index 16b270c235..b87fc297bb 100755
--- a/tools/EventClients/examples/python/example_action.py
+++ b/tools/EventClients/examples/python/example_action.py
@@ -1,13 +1,24 @@
-#!/usr/bin/python
+#!/usr/bin/env python3
# This is a simple example showing how you can send a key press event
# to XBMC using the XBMCClient class
+import os
+from socket import *
import sys
-sys.path.append("../../lib/python")
-import time
-from xbmcclient import XBMCClient,ACTION_EXECBUILTIN,ACTION_BUTTON
+if os.path.exists("../../lib/python"):
+ # try loading modules from source directory
+ sys.path.append("../../lib/python")
+
+ from xbmcclient import *
+
+ ICON_PATH = "../../icons/"
+else:
+ # fallback to system wide modules
+
+ from kodi.xbmcclient import *
+ from kodi.defs import *
def main():
@@ -15,7 +26,7 @@ def main():
port = 9777
# Create an XBMCClient object and connect
- xbmc = XBMCClient("Example Remote", "../../icons/bluetooth.png")
+ xbmc = XBMCClient("Example Remote", ICON_PATH + "/bluetooth.png")
xbmc.connect()
# send a up key press using the xbox gamepad map "XG" and button
diff --git a/tools/EventClients/examples/python/example_button1.py b/tools/EventClients/examples/python/example_button1.py
index dd524a3788..abdfe49342 100755
--- a/tools/EventClients/examples/python/example_button1.py
+++ b/tools/EventClients/examples/python/example_button1.py
@@ -1,4 +1,4 @@
-#!/usr/bin/python
+#!/usr/bin/env python3
# This is a simple example showing how you can send 2 button events
# to XBMC in a queued fashion to shut it down.
@@ -20,11 +20,22 @@
# import the XBMC client library
# NOTE: The library is not complete yet but is usable at this stage.
+import os
+from socket import *
import sys
-sys.path.append("../../lib/python")
-from xbmcclient import *
-from socket import *
+if os.path.exists("../../lib/python"):
+ # try loading modules from source directory
+ sys.path.append("../../lib/python")
+
+ from xbmcclient import *
+
+ ICON_PATH = "../../icons/"
+else:
+ # fallback to system wide modules
+
+ from kodi.xbmcclient import *
+ from kodi.defs import *
def main():
import time
@@ -43,7 +54,7 @@ def main():
# 'icon_type' can be one of ICON_NONE, ICON_PNG, ICON_JPG or ICON_GIF
packet = PacketHELO(devicename="Example Remote",
icon_type=ICON_PNG,
- icon_file="../../icons/bluetooth.png")
+ icon_file=ICON_PATH + "/bluetooth.png")
packet.send(sock, addr)
# IMPORTANT: After a HELO packet is sent, the client needs to "ping" XBMC
diff --git a/tools/EventClients/examples/python/example_button2.py b/tools/EventClients/examples/python/example_button2.py
index e2ec759bb4..bb91704d06 100755
--- a/tools/EventClients/examples/python/example_button2.py
+++ b/tools/EventClients/examples/python/example_button2.py
@@ -1,4 +1,4 @@
-#!/usr/bin/python
+#!/usr/bin/env python3
# This is a simple example showing how you can send a key press event
# to XBMC in a non-queued fashion to achieve a button pressed down
@@ -10,11 +10,22 @@
# NOTE: Read the comments in 'example_button1.py' for a more detailed
# explanation.
+import os
+from socket import *
import sys
-sys.path.append("../../lib/python")
-from xbmcclient import *
-from socket import *
+if os.path.exists("../../lib/python"):
+ # try loading modules from source directory
+ sys.path.append("../../lib/python")
+
+ from xbmcclient import *
+
+ ICON_PATH = "../../icons/"
+else:
+ # fallback to system wide modules
+
+ from kodi.xbmcclient import *
+ from kodi.defs import *
def main():
import time
@@ -28,7 +39,7 @@ def main():
# First packet must be HELO and can contain an icon
packet = PacketHELO("Example Remote", ICON_PNG,
- "../../icons/bluetooth.png")
+ ICON_PATH + "/bluetooth.png")
packet.send(sock, addr)
# wait for notification window to close (in XBMC)
diff --git a/tools/EventClients/examples/python/example_mouse.py b/tools/EventClients/examples/python/example_mouse.py
index 10d7f61ba7..7c43782428 100755
--- a/tools/EventClients/examples/python/example_mouse.py
+++ b/tools/EventClients/examples/python/example_mouse.py
@@ -1,4 +1,4 @@
-#!/usr/bin/python
+#!/usr/bin/env python3
# This is a simple example showing how you can send mouse movement
# events to XBMC.
@@ -6,11 +6,22 @@
# NOTE: Read the comments in 'example_button1.py' for a more detailed
# explanation.
+import os
+from socket import *
import sys
-sys.path.append("../../lib/python")
-from xbmcclient import *
-from socket import *
+if os.path.exists("../../lib/python"):
+ # try loading modules from source directory
+ sys.path.append("../../lib/python")
+
+ from xbmcclient import *
+
+ ICON_PATH = "../../icons/"
+else:
+ # fallback to system wide modules
+
+ from kodi.xbmcclient import *
+ from kodi.defs import *
def main():
import time
@@ -24,7 +35,7 @@ def main():
# First packet must be HELO and can contain an icon
packet = PacketHELO("Example Mouse", ICON_PNG,
- "../../icons/mouse.png")
+ ICON_PATH + "/mouse.png")
packet.send(sock, addr)
# wait for notification window to close (in XBMC)
diff --git a/tools/EventClients/examples/python/example_notification.py b/tools/EventClients/examples/python/example_notification.py
index 72c0bbcb8d..fd1a82e319 100755
--- a/tools/EventClients/examples/python/example_notification.py
+++ b/tools/EventClients/examples/python/example_notification.py
@@ -1,14 +1,25 @@
-#!/usr/bin/python
+#!/usr/bin/env python3
# This is a simple example showing how you can show a notification
# window with a custom icon inside XBMC. It could be used by mail
# monitoring apps, calendar apps, etc.
+import os
+from socket import *
import sys
-sys.path.append("../../lib/python")
-from xbmcclient import *
-from socket import *
+if os.path.exists("../../lib/python"):
+ # try loading modules from source directory
+ sys.path.append("../../lib/python")
+
+ from xbmcclient import *
+
+ ICON_PATH = "../../icons/"
+else:
+ # fallback to system wide modules
+
+ from kodi.xbmcclient import *
+ from kodi.defs import *
def main():
import time
@@ -25,10 +36,10 @@ def main():
# wait for 5 seconds
time.sleep (5)
- packet = PacketNOTIFICATION("New Mail!", # caption
- "RE: Check this out", # message
- ICON_PNG, # optional icon type
- "../../icons/mail.png") # icon file (local)
+ packet = PacketNOTIFICATION("New Mail!", # caption
+ "RE: Check this out", # message
+ ICON_PNG, # optional icon type
+ ICON_PATH + "/mail.png") # icon file (local)
packet.send(sock, addr)
packet = PacketBYE()
diff --git a/tools/EventClients/examples/python/example_simple.py b/tools/EventClients/examples/python/example_simple.py
index f28b002841..2d807e884e 100755
--- a/tools/EventClients/examples/python/example_simple.py
+++ b/tools/EventClients/examples/python/example_simple.py
@@ -1,13 +1,25 @@
-#!/usr/bin/python
+#!/usr/bin/env python3
# This is a simple example showing how you can send a key press event
# to XBMC using the XBMCClient class
+import os
+from socket import *
import sys
-sys.path.append("../../lib/python")
-
import time
-from xbmcclient import XBMCClient
+
+if os.path.exists("../../lib/python"):
+ # try loading modules from source directory
+ sys.path.append("../../lib/python")
+
+ from xbmcclient import *
+
+ ICON_PATH = "../../icons/"
+else:
+ # fallback to system wide modules
+
+ from kodi.xbmcclient import *
+ from kodi.defs import *
def main():
@@ -15,7 +27,7 @@ def main():
port = 9777
# Create an XBMCClient object and connect
- xbmc = XBMCClient("Example Remote", "../../icons/bluetooth.png")
+ xbmc = XBMCClient("Example Remote", ICON_PATH + "/bluetooth.png")
xbmc.connect()
# wait for notification window to close (in XBMC) (optional)
diff --git a/tools/EventClients/lib/python/ps3/sixaxis.py b/tools/EventClients/lib/python/ps3/sixaxis.py
index c690283078..b4899f6329 100644
--- a/tools/EventClients/lib/python/ps3/sixaxis.py
+++ b/tools/EventClients/lib/python/ps3/sixaxis.py
@@ -1,4 +1,4 @@
-#!/usr/bin/python
+#!/usr/bin/env python3
# -*- coding: utf-8 -*-
# Copyright (C) 2008-2013 Team XBMC
diff --git a/tools/EventClients/lib/python/ps3/sixpair.py b/tools/EventClients/lib/python/ps3/sixpair.py
index 2fa8cae0e0..01f11c86ee 100755
--- a/tools/EventClients/lib/python/ps3/sixpair.py
+++ b/tools/EventClients/lib/python/ps3/sixpair.py
@@ -1,4 +1,4 @@
-#!/usr/bin/python
+#!/usr/bin/env python3
# -*- coding: utf-8 -*-
import sys
diff --git a/tools/EventClients/lib/python/ps3/sixwatch.py b/tools/EventClients/lib/python/ps3/sixwatch.py
index f913c00cef..553829bc04 100755
--- a/tools/EventClients/lib/python/ps3/sixwatch.py
+++ b/tools/EventClients/lib/python/ps3/sixwatch.py
@@ -1,4 +1,4 @@
-#!/usr/bin/python
+#!/usr/bin/env python3
# -*- coding: utf-8 -*-
import pyudev
diff --git a/tools/EventClients/lib/python/xbmcclient.py b/tools/EventClients/lib/python/xbmcclient.py
index bce68e13b4..1aa743b6ca 100644
--- a/tools/EventClients/lib/python/xbmcclient.py
+++ b/tools/EventClients/lib/python/xbmcclient.py
@@ -1,4 +1,4 @@
-#!/usr/bin/python
+#!/usr/bin/env python3
# -*- coding: utf-8 -*-
# Copyright (C) 2008-2013 Team XBMC
diff --git a/tools/EventClients/lib/python/zeroconf.py b/tools/EventClients/lib/python/zeroconf.py
index 7f78aca1e4..ee2af14e8f 100644
--- a/tools/EventClients/lib/python/zeroconf.py
+++ b/tools/EventClients/lib/python/zeroconf.py
@@ -1,4 +1,4 @@
-#!/usr/bin/env python
+#!/usr/bin/env python3
# -*- coding: utf-8 -*-
# Copyright (C) 2008-2013 Team XBMC
@@ -26,12 +26,13 @@ __version__ = "0.1"
try:
import time
- import dbus, gobject, avahi
+ import dbus, avahi
from dbus import DBusException
from dbus.mainloop.glib import DBusGMainLoop
+ from gi.repository import GLib
except Exception as e:
print("Zeroconf support disabled. To enable, install the following Python modules:")
- print(" dbus, gobject, avahi")
+ print(" dbus, gi, avahi")
pass
SERVICE_FOUND = 1
@@ -78,10 +79,10 @@ class Browser:
def run(self):
"""
- Run the gobject event loop
+ Run the GLib event loop
"""
# Don't use loop.run() because Python's GIL will block all threads
- loop = gobject.MainLoop()
+ loop = GLib.MainLoop()
context = loop.get_context()
while not self._stop:
if context.pending():
@@ -91,7 +92,7 @@ class Browser:
def stop(self):
"""
- Stop the gobject event loop
+ Stop the GLib event loop
"""
self._stop = True
diff --git a/tools/Linux/kodi-xsession.desktop.in b/tools/Linux/kodi-xsession.desktop.in
index 022fac8225..c9f8c43a8d 100644
--- a/tools/Linux/kodi-xsession.desktop.in
+++ b/tools/Linux/kodi-xsession.desktop.in
@@ -4,3 +4,5 @@ Comment=This session will start @APP_NAME@ media center
Exec=@APP_NAME_LC@-standalone
TryExec=@APP_NAME_LC@-standalone
Type=Application
+Keywords=audio;video;media;center;tv;movies;series;songs;remote;
+Icon=@APP_NAME_LC@
diff --git a/tools/Linux/kodi.desktop.in b/tools/Linux/kodi.desktop.in
index 71d3f7d7f2..80e5a493be 100644
--- a/tools/Linux/kodi.desktop.in
+++ b/tools/Linux/kodi.desktop.in
@@ -11,6 +11,7 @@ Icon=@APP_NAME_LC@
Terminal=false
Type=Application
Categories=AudioVideo;Video;Player;TV;
+Keywords=audio;video;media;center;tv;movies;series;songs;remote;
Actions=Fullscreen;Standalone;
diff --git a/tools/buildsteps/jenkins_docs/README.mac b/tools/buildsteps/jenkins_docs/README.mac
index e399dfed68..edbf52c761 100644
--- a/tools/buildsteps/jenkins_docs/README.mac
+++ b/tools/buildsteps/jenkins_docs/README.mac
@@ -4,13 +4,13 @@ This are the steps to be done for configuring a mac for being a build slave to t
1. setup user jenkins as follows:
# create jenkins group
-NEXT_GID=$((`dscl /Local/Default list /Groups gid | awk '{ print $2 }' | sort -n | grep -v ^[5-9] | tail -n1` + 1))
+NEXT_GID=$((`dscl /Local/Default list /Groups gid | awk '{ print $2 }' | sort -n | grep -v '^[5-9]' | tail -n1` + 1))
sudo dscl /Local/Default create /Groups/jenkins
sudo dscl /Local/Default create /Groups/jenkins PrimaryGroupID $NEXT_GID
sudo dscl /Local/Default create /Groups/jenkins Password \*
sudo dscl /Local/Default create /Groups/jenkins RealName 'Jenkins Node Service'
# create jenkins user
-NEXT_UID=$((`dscl /Local/Default list /Users uid | awk '{ print $2 }' | sort -n | grep -v ^[5-9] | tail -n1` + 1))
+NEXT_UID=$((`dscl /Local/Default list /Users uid | awk '{ print $2 }' | sort -n | grep -v '^[5-9]' | tail -n1` + 1))
sudo dscl /Local/Default create /Users/jenkins
sudo dscl /Local/Default create /Users/jenkins UniqueID $NEXT_UID
sudo dscl /Local/Default create /Users/jenkins PrimaryGroupID $NEXT_GID
@@ -78,23 +78,23 @@ java -Djava.awt.headless=true -jar slave.jar -jar-cache /Users/Shared/jenkins/ca
</dict>
</plist>
-13. sudo cp /Users/Shared/jenkins/slave/org.jenkins-ci.slave.jnlp.plist /Library/LaunchDaemons/org.jenkins-ci.slave.jnlp.plist
+13. sudo mv /Users/Shared/jenkins/slave/org.jenkins-ci.slave.jnlp.plist /Library/LaunchDaemons/org.jenkins-ci.slave.jnlp.plist
14. sudo nano /etc/profile and add PATH=$PATH:/usr/local/bin
-15. curl http://jenkins.kodi.tv/jnlpJars/slave.jar -o /Users/Shared/jenkins/slave.jar
+15. curl http://jenkins.kodi.tv/jnlpJars/slave.jar -Lo /Users/Shared/jenkins/slave.jar
-16. install java JDK
+16. install java JDK 8
-17. Install xcode 10.2 to /Applications/Xcode10.2.app (get it from developer.apple.com -> Downloads) and start it once (accept license)
+17. Install Xcode (get it from developer.apple.com -> Downloads) and start it once (accept license):
+- 10.2 to /Applications/Xcode10.2.app - for macOS and iOS builds
+- 11.3.1 to /Applications/Xcode11.3.1.app - for tvOS builds
-18. Install xcode 9.0 to /Applications/Xcode9.0.app (get it from developer.apple.com -> Downloads) and start it once (accept license)
+18. install brew
-19. install brew
+19. install ccache via brew (brew install ccache)
-20. install ccache via brew (brew install ccache)
+20. edit /var/lib/jenkins/.ccache/ccache.conf and set max_size to 20.0G (this file might just appear after the first build done on the node)
-21. edit /var/lib/jenkins/.ccache/ccache.conf and set max_size to 15.0G (this file might just appear after the first build done on the node)
-
-22. load service:
+21. load service:
sudo launchctl load /Library/LaunchDaemons/org.jenkins-ci.slave.jnlp.plist
diff --git a/tools/darwin/Support/GenerateMissingImages-tvos.py b/tools/darwin/Support/GenerateMissingImages-tvos.py
index cc71376b8e..158186e838 100755
--- a/tools/darwin/Support/GenerateMissingImages-tvos.py
+++ b/tools/darwin/Support/GenerateMissingImages-tvos.py
@@ -1,4 +1,4 @@
-#!/usr/bin/python
+#!/usr/bin/env python3
import sys, os, json
from subprocess import call
@@ -25,5 +25,5 @@ generateImage(sys.argv[3] + '.launchimage', True, 3840, 2160)
generateImage(os.path.join(brandAssetsDir, 'topshelf_wide.imageset'), True, 4640, 1440)
appIconSmall = os.path.join(brandAssetsDir, 'icon.imagestack')
-for i in xrange(1, 5):
+for i in range(1, 5):
generateImage(os.path.join(appIconSmall, 'Layer{}.imagestacklayer'.format(i), 'Content.imageset'), False, 400, 240)
diff --git a/tools/depends/target/dav1d/DAV1D-VERSION b/tools/depends/target/dav1d/DAV1D-VERSION
index d8cc5be271..2521fb8f0b 100644
--- a/tools/depends/target/dav1d/DAV1D-VERSION
+++ b/tools/depends/target/dav1d/DAV1D-VERSION
@@ -1,3 +1,3 @@
LIBNAME=dav1d
-VERSION=0.7.0
+VERSION=0.8.1
ARCHIVE=$(LIBNAME)-$(VERSION).tar.gz
diff --git a/xbmc/Application.cpp b/xbmc/Application.cpp
index 0d1104880a..e8fd212f15 100644
--- a/xbmc/Application.cpp
+++ b/xbmc/Application.cpp
@@ -37,6 +37,7 @@
#include "music/MusicLibraryQueue.h"
#include "network/EventServer.h"
#include "network/Network.h"
+#include "platform/Environment.h"
#include "playlists/PlayListFactory.h"
#include "threads/SystemClock.h"
#include "utils/JobManager.h"
@@ -545,6 +546,23 @@ bool CApplication::Create(const CAppParamParser &params)
return false;
}
+ // set user defined CA trust bundle
+ std::string caCert =
+ CSpecialProtocol::TranslatePath(m_pSettingsComponent->GetAdvancedSettings()->m_caTrustFile);
+ if (!caCert.empty())
+ {
+ if (XFILE::CFile::Exists(caCert))
+ {
+ CEnvironment::setenv("SSL_CERT_FILE", caCert.c_str(), 1);
+ CLog::Log(LOGDEBUG, "CApplication::Create - SSL_CERT_FILE: {}", caCert);
+ }
+ else
+ {
+ CLog::Log(LOGDEBUG, "CApplication::Create - Error reading SSL_CERT_FILE: {} -> ignored",
+ caCert);
+ }
+ }
+
CUtil::InitRandomSeed();
m_lastRenderTime = XbmcThreads::SystemClockMillis();
diff --git a/xbmc/addons/AddonDatabase.cpp b/xbmc/addons/AddonDatabase.cpp
index f78db4c5de..6de470a9a0 100644
--- a/xbmc/addons/AddonDatabase.cpp
+++ b/xbmc/addons/AddonDatabase.cpp
@@ -169,7 +169,7 @@ void CAddonDatabaseSerializer::DeserializeExtensions(const CVariant& variant,
for (auto content = (*value)["content"].begin_array();
content != (*value)["content"].end_array(); ++content)
{
- extValues.emplace_back((*content)["key"].asString(), (*content)["value"].asString());
+ extValues.emplace_back((*content)["key"].asString(), SExtValue{(*content)["value"].asString()});
}
addonType.m_values.emplace_back(id, extValues);
diff --git a/xbmc/addons/gui/GUIDialogAddonSettings.h b/xbmc/addons/gui/GUIDialogAddonSettings.h
index 42c8c5ca67..88cdcb70ed 100644
--- a/xbmc/addons/gui/GUIDialogAddonSettings.h
+++ b/xbmc/addons/gui/GUIDialogAddonSettings.h
@@ -36,7 +36,7 @@ protected:
// implementation of CGUIDialogSettingsManagerBase
bool AllowResettingSettings() const override { return false; }
- void Save() override {}
+ bool Save() override { return true; }
CSettingsManager* GetSettingsManager() const override;
// implementation of ISettingCallback
diff --git a/xbmc/addons/kodi-dev-kit/include/kodi/addon-instance/PVR.h b/xbmc/addons/kodi-dev-kit/include/kodi/addon-instance/PVR.h
index 9b5088dd70..61e294fcd5 100644
--- a/xbmc/addons/kodi-dev-kit/include/kodi/addon-instance/PVR.h
+++ b/xbmc/addons/kodi-dev-kit/include/kodi/addon-instance/PVR.h
@@ -1477,22 +1477,39 @@ public:
//----------------------------------------------------------------------------
//============================================================================
- /// @brief Tell the client the time frame to use when notifying epg events back to Kodi
+ /// @brief Tell the client the past time frame to use when notifying epg events back to Kodi
///
/// The client might push epg events asynchronously to Kodi using the callback function
/// @ref EpgEventStateChange. To be able to only push events that are actually of
- /// interest for Kodi, client needs to know about the epg time frame Kodi uses. Kodi
- /// supplies the current epg time frame value in @ref EpgMaxDays() when creating the
- /// addon and calls @ref SetEPGTimeFrame later whenever Kodi's epg time frame value
- /// changes.
+ /// interest for Kodi, client needs to know about the epg time frame Kodi uses. Kodi supplies
+ /// the current epg max past time frame value @ref EpgMaxPastDays() when creating the addon
+ /// and calls @ref SetEPGMaxPastDays later whenever Kodi's epg time frame value changes.
///
- /// @param[in] days number of days from "now". @ref EPG_TIMEFRAME_UNLIMITED means that Kodi
- /// is interested in all epg events, regardless of event times.
+ /// @param[in] pastDays number of days before "now". @ref EPG_TIMEFRAME_UNLIMITED means that Kodi
+ /// is interested in all epg events, regardless of event times.
/// @return @ref PVR_ERROR_NO_ERROR if new value was successfully set.
///
/// @remarks Required if @ref PVRCapabilities::SetSupportsEPG "supportsEPG" is set to true.
///
- virtual PVR_ERROR SetEPGTimeFrame(int days) { return PVR_ERROR_NOT_IMPLEMENTED; }
+ virtual PVR_ERROR SetEPGMaxPastDays(int pastDays) { return PVR_ERROR_NOT_IMPLEMENTED; }
+ //----------------------------------------------------------------------------
+
+ //============================================================================
+ /// @brief Tell the client the future time frame to use when notifying epg events back to Kodi
+ ///
+ /// The client might push epg events asynchronously to Kodi using the callback function
+ /// @ref EpgEventStateChange. To be able to only push events that are actually of
+ /// interest for Kodi, client needs to know about the epg time frame Kodi uses. Kodi supplies
+ /// the current epg max future time frame value @ref EpgMaxFutureDays() when creating the addon
+ /// and calls @ref SetEPGMaxFutureDays later whenever Kodi's epg time frame value changes.
+ ///
+ /// @param[in] futureDays number of days from "now". @ref EPG_TIMEFRAME_UNLIMITED means that Kodi
+ /// is interested in all epg events, regardless of event times.
+ /// @return @ref PVR_ERROR_NO_ERROR if new value was successfully set.
+ ///
+ /// @remarks Required if @ref PVRCapabilities::SetSupportsEPG "supportsEPG" is set to true.
+ ///
+ virtual PVR_ERROR SetEPGMaxFutureDays(int futureDays) { return PVR_ERROR_NOT_IMPLEMENTED; }
//----------------------------------------------------------------------------
//==========================================================================
@@ -1518,15 +1535,28 @@ public:
//==========================================================================
/// @brief **Callback to Kodi Function**\n
- /// Get the Max days handled by Kodi.
+ /// Get the Max past days handled by Kodi.
///
- /// If > @ref EPG_TIMEFRAME_UNLIMITED, in async epg mode, deliver only events
- /// in the range from 'end time > now' to 'start time < now + EpgMaxDays().
+ /// If > @ref EPG_TIMEFRAME_UNLIMITED, in async epg mode, deliver only events in the
+ /// range from 'end time > now - EpgMaxPastDays()' to 'start time < now + EpgMaxFutureDays().
/// @ref EPG_TIMEFRAME_UNLIMITED, notify all events.
///
- /// @return The Max days handled by Kodi
+ /// @return The Max past days handled by Kodi
///
- inline int EpgMaxDays() const { return m_instanceData->props->iEpgMaxDays; }
+ inline int EpgMaxPastDays() const { return m_instanceData->props->iEpgMaxPastDays; }
+ //----------------------------------------------------------------------------
+
+ //==========================================================================
+ /// @brief **Callback to Kodi Function**\n
+ /// Get the Max future days handled by Kodi.
+ ///
+ /// If > @ref EPG_TIMEFRAME_UNLIMITED, in async epg mode, deliver only events in the
+ /// range from 'end time > now - EpgMaxPastDays()' to 'start time < now + EpgMaxFutureDays().
+ /// @ref EPG_TIMEFRAME_UNLIMITED, notify all events.
+ ///
+ /// @return The Max future days handled by Kodi
+ ///
+ inline int EpgMaxFutureDays() const { return m_instanceData->props->iEpgMaxFutureDays; }
//----------------------------------------------------------------------------
//==========================================================================
@@ -2662,7 +2692,8 @@ private:
m_instanceData->toAddon->IsEPGTagPlayable = ADDON_IsEPGTagPlayable;
m_instanceData->toAddon->GetEPGTagEdl = ADDON_GetEPGTagEdl;
m_instanceData->toAddon->GetEPGTagStreamProperties = ADDON_GetEPGTagStreamProperties;
- m_instanceData->toAddon->SetEPGTimeFrame = ADDON_SetEPGTimeFrame;
+ m_instanceData->toAddon->SetEPGMaxPastDays = ADDON_SetEPGMaxPastDays;
+ m_instanceData->toAddon->SetEPGMaxFutureDays = ADDON_SetEPGMaxFutureDays;
m_instanceData->toAddon->CallEPGMenuHook = ADDON_CallEPGMenuHook;
//--==----==----==----==----==----==----==----==----==----==----==----==----==
m_instanceData->toAddon->GetRecordingsAmount = ADDON_GetRecordingsAmount;
@@ -2998,10 +3029,17 @@ private:
return error;
}
- inline static PVR_ERROR ADDON_SetEPGTimeFrame(const AddonInstance_PVR* instance, int days)
+ inline static PVR_ERROR ADDON_SetEPGMaxPastDays(const AddonInstance_PVR* instance, int pastDays)
+ {
+ return static_cast<CInstancePVRClient*>(instance->toAddon->addonInstance)
+ ->SetEPGMaxPastDays(pastDays);
+ }
+
+ inline static PVR_ERROR ADDON_SetEPGMaxFutureDays(const AddonInstance_PVR* instance,
+ int futureDays)
{
return static_cast<CInstancePVRClient*>(instance->toAddon->addonInstance)
- ->SetEPGTimeFrame(days);
+ ->SetEPGMaxFutureDays(futureDays);
}
inline static PVR_ERROR ADDON_CallEPGMenuHook(const AddonInstance_PVR* instance,
diff --git a/xbmc/addons/kodi-dev-kit/include/kodi/c-api/addon-instance/pvr.h b/xbmc/addons/kodi-dev-kit/include/kodi/c-api/addon-instance/pvr.h
index 3a185cbc87..cc24e5db50 100644
--- a/xbmc/addons/kodi-dev-kit/include/kodi/c-api/addon-instance/pvr.h
+++ b/xbmc/addons/kodi-dev-kit/include/kodi/c-api/addon-instance/pvr.h
@@ -65,7 +65,8 @@ extern "C"
{
const char* strUserPath;
const char* strClientPath;
- int iEpgMaxDays;
+ int iEpgMaxFutureDays;
+ int iEpgMaxPastDays;
} AddonProperties_PVR;
/*!
@@ -208,7 +209,8 @@ extern "C"
const struct EPG_TAG*,
struct PVR_NAMED_VALUE*,
unsigned int*);
- enum PVR_ERROR(__cdecl* SetEPGTimeFrame)(const struct AddonInstance_PVR*, int);
+ enum PVR_ERROR(__cdecl* SetEPGMaxPastDays)(const struct AddonInstance_PVR*, int);
+ enum PVR_ERROR(__cdecl* SetEPGMaxFutureDays)(const struct AddonInstance_PVR*, int);
enum PVR_ERROR(__cdecl* CallEPGMenuHook)(const struct AddonInstance_PVR*,
const struct PVR_MENUHOOK*,
const struct EPG_TAG*);
diff --git a/xbmc/addons/kodi-dev-kit/include/kodi/versions.h b/xbmc/addons/kodi-dev-kit/include/kodi/versions.h
index 6ece41d2bc..e3431eb6e4 100644
--- a/xbmc/addons/kodi-dev-kit/include/kodi/versions.h
+++ b/xbmc/addons/kodi-dev-kit/include/kodi/versions.h
@@ -129,8 +129,8 @@
#define ADDON_INSTANCE_VERSION_PERIPHERAL_DEPENDS "addon-instance/Peripheral.h" \
"addon-instance/PeripheralUtils.h"
-#define ADDON_INSTANCE_VERSION_PVR "7.0.2"
-#define ADDON_INSTANCE_VERSION_PVR_MIN "7.0.2"
+#define ADDON_INSTANCE_VERSION_PVR "7.1.0"
+#define ADDON_INSTANCE_VERSION_PVR_MIN "7.1.0"
#define ADDON_INSTANCE_VERSION_PVR_XML_ID "kodi.binary.instance.pvr"
#define ADDON_INSTANCE_VERSION_PVR_DEPENDS "c-api/addon-instance/pvr.h" \
"c-api/addon-instance/pvr/pvr_channel_groups.h" \
diff --git a/xbmc/addons/kodi-dev-kit/tools/doxygen-header-class-list-creator.py b/xbmc/addons/kodi-dev-kit/tools/doxygen-header-class-list-creator.py
index 497a4b63d7..0b0590e993 100755
--- a/xbmc/addons/kodi-dev-kit/tools/doxygen-header-class-list-creator.py
+++ b/xbmc/addons/kodi-dev-kit/tools/doxygen-header-class-list-creator.py
@@ -1,4 +1,4 @@
-#!/usr/bin/python3
+#!/usr/bin/env python3
from optparse import OptionParser
import glob
diff --git a/xbmc/addons/settings/AddonSettings.cpp b/xbmc/addons/settings/AddonSettings.cpp
index e44db52570..8e355c2702 100644
--- a/xbmc/addons/settings/AddonSettings.cpp
+++ b/xbmc/addons/settings/AddonSettings.cpp
@@ -170,6 +170,10 @@ void CAddonSettings::OnSettingAction(const std::shared_ptr<const CSetting>& sett
auto settingAction = std::dynamic_pointer_cast<const CSettingAction>(setting);
if (settingAction != nullptr && settingAction->HasData())
actionData = settingAction->GetData();
+ // replace $CWD with the url of the add-on
+ StringUtils::Replace(actionData, "$CWD", m_addonPath);
+ // replace $ID with the id of the add-on
+ StringUtils::Replace(actionData, "$ID", m_addonId);
}
// check if the setting control's is a button and its format is action
diff --git a/xbmc/dbwrappers/mysqldataset.cpp b/xbmc/dbwrappers/mysqldataset.cpp
index 54f36484ad..0198b73c09 100644
--- a/xbmc/dbwrappers/mysqldataset.cpp
+++ b/xbmc/dbwrappers/mysqldataset.cpp
@@ -6,17 +6,18 @@
* See LICENSES/README.md for more information.
*/
-#include <iostream>
-#include <string>
-#include <set>
-#include <algorithm>
+#include "mysqldataset.h"
-#include "utils/log.h"
-#include "network/WakeOnAccess.h"
#include "Util.h"
+#include "network/DNSNameCache.h"
+#include "network/WakeOnAccess.h"
#include "utils/StringUtils.h"
+#include "utils/log.h"
-#include "mysqldataset.h"
+#include <algorithm>
+#include <iostream>
+#include <set>
+#include <string>
#ifdef HAS_MYSQL
#include <mysql/errmsg.h>
#elif defined(HAS_MARIADB)
@@ -145,7 +146,13 @@ int MysqlDatabase::connect(bool create_new) {
if (host.empty() || db.empty())
return DB_CONNECTION_NONE;
- //CLog::Log(LOGDEBUG, "Connecting to mysql:%s:%s", host.c_str(), db.c_str());
+ std::string resolvedHost;
+ if (CDNSNameCache::Lookup(host, resolvedHost))
+ {
+ CLog::Log(LOGDEBUG, "{} replacing configured host {} with resolved host {}", __FUNCTION__, host,
+ resolvedHost);
+ host = resolvedHost;
+ }
try
{
diff --git a/xbmc/dialogs/GUIDialogMediaFilter.h b/xbmc/dialogs/GUIDialogMediaFilter.h
index dd87b034e7..41bfa5590d 100644
--- a/xbmc/dialogs/GUIDialogMediaFilter.h
+++ b/xbmc/dialogs/GUIDialogMediaFilter.h
@@ -59,7 +59,7 @@ protected:
// specialization of CGUIDialogSettingsBase
bool AllowResettingSettings() const override { return false; }
- void Save() override { }
+ bool Save() override { return true; }
unsigned int GetDelayMs() const override { return 500; }
// specialization of CGUIDialogSettingsManualBase
diff --git a/xbmc/dialogs/GUIDialogYesNo.cpp b/xbmc/dialogs/GUIDialogYesNo.cpp
index 9b689b0254..b2aaaf005e 100644
--- a/xbmc/dialogs/GUIDialogYesNo.cpp
+++ b/xbmc/dialogs/GUIDialogYesNo.cpp
@@ -179,7 +179,7 @@ int CGUIDialogYesNo::ShowAndGetInput(const CVariant& heading,
dialog->SetHeading(heading);
dialog->SetText(text);
- if (autoCloseTime)
+ if (autoCloseTime > 0)
dialog->SetAutoClose(autoCloseTime);
dialog->m_bCanceled = false;
dialog->m_bCustom = false;
diff --git a/xbmc/filesystem/CurlFile.cpp b/xbmc/filesystem/CurlFile.cpp
index 222ef42ee5..7cad6f4888 100644
--- a/xbmc/filesystem/CurlFile.cpp
+++ b/xbmc/filesystem/CurlFile.cpp
@@ -12,6 +12,8 @@
#include "ServiceBroker.h"
#include "URL.h"
#include "Util.h"
+#include "filesystem/SpecialProtocol.h"
+#include "network/DNSNameCache.h"
#include "settings/AdvancedSettings.h"
#include "settings/Settings.h"
#include "settings/SettingsComponent.h"
@@ -450,6 +452,10 @@ void CCurlFile::Close()
m_opened = false;
m_forWrite = false;
m_inError = false;
+
+ if (m_dnsCacheList)
+ g_curlInterface.slist_free_all(m_dnsCacheList);
+ m_dnsCacheList = nullptr;
}
void CCurlFile::SetCommonOptions(CReadState* state, bool failOnError /* = true */)
@@ -471,6 +477,9 @@ void CCurlFile::SetCommonOptions(CReadState* state, bool failOnError /* = true *
g_curlInterface.easy_setopt(h, CURLOPT_READDATA, state);
g_curlInterface.easy_setopt(h, CURLOPT_READFUNCTION, read_callback);
+ // use DNS cache
+ g_curlInterface.easy_setopt(h, CURLOPT_RESOLVE, m_dnsCacheList);
+
// make sure headers are separated from the data stream
g_curlInterface.easy_setopt(h, CURLOPT_WRITEHEADER, state);
g_curlInterface.easy_setopt(h, CURLOPT_HEADERFUNCTION, header_callback);
@@ -645,6 +654,13 @@ void CCurlFile::SetCommonOptions(CReadState* state, bool failOnError /* = true *
else
// enable HTTP2 support. default: CURL_HTTP_VERSION_1_1. Curl >= 7.62.0 defaults to CURL_HTTP_VERSION_2TLS
g_curlInterface.easy_setopt(h, CURLOPT_HTTP_VERSION, CURL_HTTP_VERSION_2TLS);
+
+ // set CA bundle file
+ std::string caCert = CSpecialProtocol::TranslatePath(
+ CServiceBroker::GetSettingsComponent()->GetAdvancedSettings()->m_caTrustFile);
+ if (!caCert.empty() && XFILE::CFile::Exists(caCert))
+ g_curlInterface.easy_setopt(h, CURLOPT_CAINFO, caCert.c_str());
+
}
void CCurlFile::SetRequestHeaders(CReadState* state)
@@ -694,6 +710,33 @@ void CCurlFile::ParseAndCorrectUrl(CURL &url2)
std::string strProtocol = url2.GetTranslatedProtocol();
url2.SetProtocol(strProtocol);
+ // lookup host in DNS cache
+ std::string resolvedHost;
+ if (CDNSNameCache::Lookup(url2.GetHostName(), resolvedHost))
+ {
+ struct curl_slist* tempCache;
+ int entryPort = url2.GetPort();
+
+ if (entryPort == 0)
+ {
+ if (strProtocol == "http")
+ entryPort = 80;
+ else if (strProtocol == "https")
+ entryPort = 443;
+ else if (strProtocol == "ftp")
+ entryPort = 21;
+ else if (strProtocol == "ftps")
+ entryPort = 990;
+ }
+
+ std::string entryString =
+ url2.GetHostName() + ":" + std::to_string(entryPort) + ":" + resolvedHost;
+ tempCache = g_curlInterface.slist_append(m_dnsCacheList, entryString.c_str());
+
+ if (tempCache)
+ m_dnsCacheList = tempCache;
+ }
+
if( url2.IsProtocol("ftp")
|| url2.IsProtocol("ftps") )
{
diff --git a/xbmc/filesystem/CurlFile.h b/xbmc/filesystem/CurlFile.h
index 8a5dbe688f..59d2c83c6c 100644
--- a/xbmc/filesystem/CurlFile.h
+++ b/xbmc/filesystem/CurlFile.h
@@ -185,6 +185,7 @@ namespace XFILE
bool m_allowRetry;
bool m_verifyPeer = true;
bool m_failOnError = true;
+ curl_slist* m_dnsCacheList = nullptr;
CRingBuffer m_buffer; // our ringhold buffer
char* m_overflowBuffer; // in the rare case we would overflow the above buffer
diff --git a/xbmc/guilib/GUIShaderDX.cpp b/xbmc/guilib/GUIShaderDX.cpp
index 64ec0814db..2476ee9ae7 100644
--- a/xbmc/guilib/GUIShaderDX.cpp
+++ b/xbmc/guilib/GUIShaderDX.cpp
@@ -337,6 +337,7 @@ void CGUIShaderDX::ApplyChanges(void)
buffer->wvp = worldViewProj;
buffer->blackLevel = (DX::Windowing()->UseLimitedColor() ? 16.f / 255.f : 0.f);
buffer->colorRange = (DX::Windowing()->UseLimitedColor() ? (235.f - 16.f) / 255.f : 1.0f);
+ buffer->PQ = (DX::Windowing()->IsTransferPQ() ? 1 : 0);
pContext->Unmap(m_pWVPBuffer.Get(), 0);
m_bIsWVPDirty = false;
diff --git a/xbmc/guilib/GUIShaderDX.h b/xbmc/guilib/GUIShaderDX.h
index 6fbee21b6d..1f0ec5eac5 100644
--- a/xbmc/guilib/GUIShaderDX.h
+++ b/xbmc/guilib/GUIShaderDX.h
@@ -106,6 +106,7 @@ private:
DirectX::XMMATRIX wvp;
float blackLevel;
float colorRange;
+ int PQ;
};
void Release(void);
diff --git a/xbmc/interfaces/json-rpc/schema/version.txt b/xbmc/interfaces/json-rpc/schema/version.txt
index 735ba49936..575fd3194e 100644
--- a/xbmc/interfaces/json-rpc/schema/version.txt
+++ b/xbmc/interfaces/json-rpc/schema/version.txt
@@ -1 +1 @@
-JSONRPC_VERSION 11.21.1
+JSONRPC_VERSION 12.0.0
diff --git a/xbmc/interfaces/legacy/Dialog.cpp b/xbmc/interfaces/legacy/Dialog.cpp
index d1c641a3dc..00ac78077c 100644
--- a/xbmc/interfaces/legacy/Dialog.cpp
+++ b/xbmc/interfaces/legacy/Dialog.cpp
@@ -45,32 +45,37 @@ namespace XBMCAddon
bool Dialog::yesno(const String& heading, const String& message,
const String& nolabel,
const String& yeslabel,
- const String& customlabel,
int autoclose)
{
- DelayedCallGuard dcguard(languageHook);
- CGUIDialogYesNo* pDialog = CServiceBroker::GetGUI()->GetWindowManager().GetWindow<CGUIDialogYesNo>(WINDOW_DIALOG_YES_NO);
- if (pDialog == NULL)
- throw WindowException("Error: Window is NULL, this is not possible :-)");
-
- if (!heading.empty())
- pDialog->SetHeading(CVariant{heading});
- if (!message.empty())
- pDialog->SetText(CVariant{message});
-
- if (!nolabel.empty())
- pDialog->SetChoice(0, CVariant{nolabel});
- if (!yeslabel.empty())
- pDialog->SetChoice(1, CVariant{yeslabel});
- if (!customlabel.empty())
- pDialog->SetChoice(2, CVariant{customlabel});
+ return yesNoCustomInternal(heading, message, nolabel, yeslabel, emptyString, autoclose) == 1;
+ }
- if (autoclose > 0)
- pDialog->SetAutoClose(autoclose);
+ int Dialog::yesnocustom(const String& heading,
+ const String& message,
+ const String& customlabel,
+ const String& nolabel,
+ const String& yeslabel,
+ int autoclose)
+ {
+ return yesNoCustomInternal(heading, message, nolabel, yeslabel, customlabel, autoclose);
+ }
- pDialog->Open();
+ int Dialog::yesNoCustomInternal(const String& heading,
+ const String& message,
+ const String& nolabel,
+ const String& yeslabel,
+ const String& customlabel,
+ int autoclose)
+ {
+ DelayedCallGuard dcguard(languageHook);
+ CGUIDialogYesNo* pDialog =
+ CServiceBroker::GetGUI()->GetWindowManager().GetWindow<CGUIDialogYesNo>(
+ WINDOW_DIALOG_YES_NO);
+ if (pDialog == nullptr)
+ throw WindowException("Error: Window is null");
- return pDialog->IsConfirmed();
+ return pDialog->ShowAndGetInput(CVariant{heading}, CVariant{message}, CVariant{nolabel},
+ CVariant{yeslabel}, CVariant{customlabel}, autoclose);
}
bool Dialog::info(const ListItem* item)
diff --git a/xbmc/interfaces/legacy/Dialog.h b/xbmc/interfaces/legacy/Dialog.h
index 81c571d675..1ffb7fc804 100644
--- a/xbmc/interfaces/legacy/Dialog.h
+++ b/xbmc/interfaces/legacy/Dialog.h
@@ -52,7 +52,7 @@ constexpr int ALPHANUM_HIDE_INPUT{2};
#ifdef DOXYGEN_SHOULD_USE_THIS
///
/// \ingroup python_Dialog
- /// \python_func{ xbmcgui.Dialog().yesno(heading, message, nolabel, yeslabel, customlabel, autoclose]) }
+ /// \python_func{ xbmcgui.Dialog().yesno(heading, message, [nolabel, yeslabel, autoclose]) }
/// **Yes / no dialog**
///
/// The Yes / No dialog can be used to inform the user about questions and
@@ -62,7 +62,6 @@ constexpr int ALPHANUM_HIDE_INPUT{2};
/// @param message string or unicode - message text.
/// @param nolabel [opt] label to put on the no button.
/// @param yeslabel [opt] label to put on the yes button.
- /// @param customlabel [opt] label to put on the custom button.
/// @param autoclose [opt] integer - milliseconds to autoclose dialog. (default=do not autoclose)
/// @return Returns True if 'Yes' was pressed, else False.
///
@@ -73,7 +72,6 @@ constexpr int ALPHANUM_HIDE_INPUT{2};
/// @python_v19 Renamed option **line1** to **message**.
/// @python_v19 Removed option **line2**.
/// @python_v19 Removed option **line3**.
- /// @python_v19 Added new option **customlabel**.
///
/// **Example:**
/// ~~~~~~~~~~~~~{.py}
@@ -88,13 +86,53 @@ constexpr int ALPHANUM_HIDE_INPUT{2};
bool yesno(const String& heading, const String& message,
const String& nolabel = emptyString,
const String& yeslabel = emptyString,
- const String& customlabel = emptyString,
int autoclose = 0);
#endif
#ifdef DOXYGEN_SHOULD_USE_THIS
///
/// \ingroup python_Dialog
+ /// \python_func{ xbmcgui.Dialog().yesnocustom(heading, message, customlabel, [nolabel, yeslabel, autoclose]) }
+ /// **Yes / no / custom dialog**
+ ///
+ /// The YesNoCustom dialog can be used to inform the user about questions and
+ /// get the answer. The dialog provides a third button appart from yes and no.
+ /// Button labels are fully customizable.
+ ///
+ /// @param heading string or unicode - dialog heading.
+ /// @param message string or unicode - message text.
+ /// @param customlabel string or unicode - label to put on the custom button.
+ /// @param nolabel [opt] label to put on the no button.
+ /// @param yeslabel [opt] label to put on the yes button.
+ /// @param autoclose [opt] integer - milliseconds to autoclose dialog. (default=do not autoclose)
+ /// @return Returns the integer value for the selected button (-1:cancelled, 0:no, 1:yes, 2:custom)
+ ///
+ ///
+ ///
+ ///------------------------------------------------------------------------
+ /// @python_v19 New function added.
+ ///
+ /// **Example:**
+ /// ~~~~~~~~~~~~~{.py}
+ /// ..
+ /// dialog = xbmcgui.Dialog()
+ /// ret = dialog.yesnocustom('Kodi', 'Question?', 'Maybe')
+ /// ..
+ /// ~~~~~~~~~~~~~
+ ///
+ yesnocustom(...);
+#else
+ int yesnocustom(const String& heading,
+ const String& message,
+ const String& customlabel,
+ const String& nolabel = emptyString,
+ const String& yeslabel = emptyString,
+ int autoclose = 0);
+#endif
+
+#ifdef DOXYGEN_SHOULD_USE_THIS
+ ///
+ /// \ingroup python_Dialog
/// \python_func{ xbmcgui.Dialog().info(listitem) }
/// **Info dialog**
///
@@ -582,6 +620,17 @@ constexpr int ALPHANUM_HIDE_INPUT{2};
int option = 0,
int autoclose = 0);
#endif
+
+ private:
+#ifndef DOXYGEN_SHOULD_SKIP_THIS
+ // used by both yesno() and yesnocustom()
+ int yesNoCustomInternal(const String& heading,
+ const String& message,
+ const String& nolabel,
+ const String& yeslabel,
+ const String& customlabel,
+ int autoclose);
+#endif
};
//@}
diff --git a/xbmc/interfaces/python/LanguageHook.cpp b/xbmc/interfaces/python/LanguageHook.cpp
index 1fc4b03017..99a2f9923a 100644
--- a/xbmc/interfaces/python/LanguageHook.cpp
+++ b/xbmc/interfaces/python/LanguageHook.cpp
@@ -14,6 +14,7 @@
#include "ServiceBroker.h"
#include "XBPython.h"
#include "interfaces/legacy/AddonUtils.h"
+#include "utils/log.h"
namespace XBMCAddon
{
@@ -120,6 +121,11 @@ namespace XBMCAddon
// Get a reference to the main module
// and global dictionary
PyObject* main_module = PyImport_AddModule("__main__");
+ if (!main_module)
+ {
+ CLog::Log(LOGDEBUG, "PythonLanguageHook::{}: __main__ returns null", __FUNCTION__);
+ return "";
+ }
PyObject* global_dict = PyModule_GetDict(main_module);
// Extract a reference to the function "func_name"
// from the global dictionary
@@ -135,6 +141,11 @@ namespace XBMCAddon
// Get a reference to the main module
// and global dictionary
PyObject* main_module = PyImport_AddModule("__main__");
+ if (!main_module)
+ {
+ CLog::Log(LOGDEBUG, "PythonLanguageHook::{}: __main__ returns null", __FUNCTION__);
+ return "";
+ }
PyObject* global_dict = PyModule_GetDict(main_module);
// Extract a reference to the function "func_name"
// from the global dictionary
@@ -151,6 +162,11 @@ namespace XBMCAddon
// Get a reference to the main module
// and global dictionary
PyObject* main_module = PyImport_AddModule("__main__");
+ if (!main_module)
+ {
+ CLog::Log(LOGDEBUG, "PythonLanguageHook::{}: __main__ returns null", __FUNCTION__);
+ return -1;
+ }
PyObject* global_dict = PyModule_GetDict(main_module);
// Extract a reference to the function "func_name"
// from the global dictionary
diff --git a/xbmc/music/dialogs/GUIDialogInfoProviderSettings.cpp b/xbmc/music/dialogs/GUIDialogInfoProviderSettings.cpp
index 8f63fc66ef..97c3709922 100644
--- a/xbmc/music/dialogs/GUIDialogInfoProviderSettings.cpp
+++ b/xbmc/music/dialogs/GUIDialogInfoProviderSettings.cpp
@@ -242,10 +242,10 @@ void CGUIDialogInfoProviderSettings::OnSettingAction(const std::shared_ptr<const
}
}
-void CGUIDialogInfoProviderSettings::Save()
+bool CGUIDialogInfoProviderSettings::Save()
{
if (m_showSingleScraper)
- return; //Save done by caller of ::Show
+ return true; //Save done by caller of ::Show
// Save default settings for fetching additional information and art
CLog::Log(LOGINFO, "%s called", __FUNCTION__);
@@ -260,6 +260,8 @@ void CGUIDialogInfoProviderSettings::Save()
// Save artist information folder
settings->SetString(CSettings::SETTING_MUSICLIBRARY_ARTISTSFOLDER, m_strArtistInfoPath);
settings->Save();
+
+ return true;
}
void CGUIDialogInfoProviderSettings::SetupView()
diff --git a/xbmc/music/dialogs/GUIDialogInfoProviderSettings.h b/xbmc/music/dialogs/GUIDialogInfoProviderSettings.h
index 7a9cb7d268..effa51db52 100644
--- a/xbmc/music/dialogs/GUIDialogInfoProviderSettings.h
+++ b/xbmc/music/dialogs/GUIDialogInfoProviderSettings.h
@@ -62,7 +62,7 @@ protected:
// specialization of CGUIDialogSettingsBase
bool AllowResettingSettings() const override { return false; }
- void Save() override;
+ bool Save() override;
void SetupView() override;
// specialization of CGUIDialogSettingsManualBase
diff --git a/xbmc/network/GUIDialogNetworkSetup.h b/xbmc/network/GUIDialogNetworkSetup.h
index 1758766475..c4f6959d0e 100644
--- a/xbmc/network/GUIDialogNetworkSetup.h
+++ b/xbmc/network/GUIDialogNetworkSetup.h
@@ -47,7 +47,7 @@ protected:
// specialization of CGUIDialogSettingsBase
bool AllowResettingSettings() const override { return false; }
- void Save() override { }
+ bool Save() override { return true; }
void SetupView() override;
// specialization of CGUIDialogSettingsManualBase
diff --git a/xbmc/peripherals/dialogs/GUIDialogPeripheralSettings.cpp b/xbmc/peripherals/dialogs/GUIDialogPeripheralSettings.cpp
index 56fcd28a92..d44ae883b3 100644
--- a/xbmc/peripherals/dialogs/GUIDialogPeripheralSettings.cpp
+++ b/xbmc/peripherals/dialogs/GUIDialogPeripheralSettings.cpp
@@ -77,16 +77,18 @@ void CGUIDialogPeripheralSettings::OnSettingChanged(const std::shared_ptr<const
itSetting->second->FromString(setting->ToString());
}
-void CGUIDialogPeripheralSettings::Save()
+bool CGUIDialogPeripheralSettings::Save()
{
if (m_item == NULL || m_initialising)
- return;
+ return true;
PeripheralPtr peripheral = CServiceBroker::GetPeripherals().GetByPath(m_item->GetPath());
if (!peripheral)
- return;
+ return true;
peripheral->PersistSettings();
+
+ return true;
}
void CGUIDialogPeripheralSettings::OnResetSettings()
diff --git a/xbmc/peripherals/dialogs/GUIDialogPeripheralSettings.h b/xbmc/peripherals/dialogs/GUIDialogPeripheralSettings.h
index d94d53dada..89022aa85f 100644
--- a/xbmc/peripherals/dialogs/GUIDialogPeripheralSettings.h
+++ b/xbmc/peripherals/dialogs/GUIDialogPeripheralSettings.h
@@ -31,7 +31,7 @@ protected:
// specialization of CGUIDialogSettingsBase
bool AllowResettingSettings() const override { return false; }
- void Save() override;
+ bool Save() override;
void OnResetSettings() override;
void SetupView() override;
diff --git a/xbmc/platform/posix/filesystem/SMBDirectory.cpp b/xbmc/platform/posix/filesystem/SMBDirectory.cpp
index ef8300f448..d94742eab7 100644
--- a/xbmc/platform/posix/filesystem/SMBDirectory.cpp
+++ b/xbmc/platform/posix/filesystem/SMBDirectory.cpp
@@ -217,7 +217,7 @@ int CSMBDirectory::OpenDir(const CURL& url, std::string& strAuth)
int fd = -1;
/* make a writeable copy */
- CURL urlIn(url);
+ CURL urlIn = CSMB::GetResolvedUrl(url);
CPasswordManager::GetInstance().AuthenticateURL(urlIn);
strAuth = smb.URLEncode(urlIn);
@@ -273,7 +273,7 @@ bool CSMBDirectory::Create(const CURL& url2)
CSingleLock lock(smb);
smb.Init();
- CURL url(url2);
+ CURL url = CSMB::GetResolvedUrl(url2);
CPasswordManager::GetInstance().AuthenticateURL(url);
std::string strFileName = smb.URLEncode(url);
@@ -290,7 +290,7 @@ bool CSMBDirectory::Remove(const CURL& url2)
CSingleLock lock(smb);
smb.Init();
- CURL url(url2);
+ CURL url = CSMB::GetResolvedUrl(url2);
CPasswordManager::GetInstance().AuthenticateURL(url);
std::string strFileName = smb.URLEncode(url);
@@ -310,7 +310,7 @@ bool CSMBDirectory::Exists(const CURL& url2)
CSingleLock lock(smb);
smb.Init();
- CURL url(url2);
+ CURL url = CSMB::GetResolvedUrl(url2);
CPasswordManager::GetInstance().AuthenticateURL(url);
std::string strFileName = smb.URLEncode(url);
diff --git a/xbmc/platform/posix/filesystem/SMBFile.cpp b/xbmc/platform/posix/filesystem/SMBFile.cpp
index 76480b4feb..a66a5f91ac 100644
--- a/xbmc/platform/posix/filesystem/SMBFile.cpp
+++ b/xbmc/platform/posix/filesystem/SMBFile.cpp
@@ -18,6 +18,7 @@
#include "Util.h"
#include "commons/Exception.h"
#include "filesystem/SpecialProtocol.h"
+#include "network/DNSNameCache.h"
#include "settings/AdvancedSettings.h"
#include "settings/Settings.h"
#include "settings/SettingsComponent.h"
@@ -322,6 +323,17 @@ void CSMB::AddIdleConnection()
m_IdleTimeout = 180;
}
+CURL CSMB::GetResolvedUrl(const CURL& url)
+{
+ CURL tmpUrl(url);
+ std::string resolvedHostName;
+
+ if (CDNSNameCache::Lookup(tmpUrl.GetHostName(), resolvedHostName))
+ tmpUrl.SetHostName(resolvedHostName);
+
+ return tmpUrl;
+}
+
CSMB smb;
CSMBFile::CSMBFile()
@@ -434,7 +446,7 @@ int CSMBFile::OpenFile(const CURL &url, std::string& strAuth)
int fd = -1;
smb.Init();
- strAuth = GetAuthenticatedPath(url);
+ strAuth = GetAuthenticatedPath(CSMB::GetResolvedUrl(url));
std::string strPath = strAuth;
{
@@ -455,7 +467,7 @@ bool CSMBFile::Exists(const CURL& url)
if (!IsValidFile(url.GetFileName())) return false;
smb.Init();
- std::string strFileName = GetAuthenticatedPath(url);
+ std::string strFileName = GetAuthenticatedPath(CSMB::GetResolvedUrl(url));
struct stat info;
@@ -482,7 +494,7 @@ int CSMBFile::Stat(struct __stat64* buffer)
int CSMBFile::Stat(const CURL& url, struct __stat64* buffer)
{
smb.Init();
- std::string strFileName = GetAuthenticatedPath(url);
+ std::string strFileName = GetAuthenticatedPath(CSMB::GetResolvedUrl(url));
CSingleLock lock(smb);
struct stat tmpBuffer = {0};
@@ -586,7 +598,7 @@ ssize_t CSMBFile::Write(const void* lpBuf, size_t uiBufSize)
bool CSMBFile::Delete(const CURL& url)
{
smb.Init();
- std::string strFile = GetAuthenticatedPath(url);
+ std::string strFile = GetAuthenticatedPath(CSMB::GetResolvedUrl(url));
CSingleLock lock(smb);
@@ -601,8 +613,8 @@ bool CSMBFile::Delete(const CURL& url)
bool CSMBFile::Rename(const CURL& url, const CURL& urlnew)
{
smb.Init();
- std::string strFile = GetAuthenticatedPath(url);
- std::string strFileNew = GetAuthenticatedPath(urlnew);
+ std::string strFile = GetAuthenticatedPath(CSMB::GetResolvedUrl(url));
+ std::string strFileNew = GetAuthenticatedPath(CSMB::GetResolvedUrl(urlnew));
CSingleLock lock(smb);
int result = smbc_rename(strFile.c_str(), strFileNew.c_str());
@@ -618,11 +630,12 @@ bool CSMBFile::OpenForWrite(const CURL& url, bool bOverWrite)
m_fileSize = 0;
Close();
+
// we can't open files like smb://file.f or smb://server/file.f
// if a file matches the if below return false, it can't exist on a samba share.
if (!IsValidFile(url.GetFileName())) return false;
- std::string strFileName = GetAuthenticatedPath(url);
+ std::string strFileName = GetAuthenticatedPath(CSMB::GetResolvedUrl(url));
CSingleLock lock(smb);
if (bOverWrite)
@@ -657,7 +670,7 @@ bool CSMBFile::IsValidFile(const std::string& strFileName)
std::string CSMBFile::GetAuthenticatedPath(const CURL &url)
{
- CURL authURL(url);
+ CURL authURL(CSMB::GetResolvedUrl(url));
CPasswordManager::GetInstance().AuthenticateURL(authURL);
return smb.URLEncode(authURL);
}
diff --git a/xbmc/platform/posix/filesystem/SMBFile.h b/xbmc/platform/posix/filesystem/SMBFile.h
index 469458908a..d4334f459f 100644
--- a/xbmc/platform/posix/filesystem/SMBFile.h
+++ b/xbmc/platform/posix/filesystem/SMBFile.h
@@ -43,6 +43,8 @@ public:
std::string URLEncode(const CURL &url);
DWORD ConvertUnixToNT(int error);
+ static CURL GetResolvedUrl(const CURL& url);
+
private:
SMBCCTX *m_context;
int m_OpenConnections;
diff --git a/xbmc/profiles/dialogs/GUIDialogLockSettings.h b/xbmc/profiles/dialogs/GUIDialogLockSettings.h
index 4ad482a6bd..bdcaed7107 100644
--- a/xbmc/profiles/dialogs/GUIDialogLockSettings.h
+++ b/xbmc/profiles/dialogs/GUIDialogLockSettings.h
@@ -28,7 +28,7 @@ protected:
// specialization of CGUIDialogSettingsBase
bool AllowResettingSettings() const override { return false; }
- void Save() override { }
+ bool Save() override { return true; }
void OnCancel() override;
void SetupView() override;
diff --git a/xbmc/profiles/dialogs/GUIDialogProfileSettings.h b/xbmc/profiles/dialogs/GUIDialogProfileSettings.h
index a17ccaa844..5b6f14e24f 100644
--- a/xbmc/profiles/dialogs/GUIDialogProfileSettings.h
+++ b/xbmc/profiles/dialogs/GUIDialogProfileSettings.h
@@ -31,7 +31,7 @@ protected:
// specialization of CGUIDialogSettingsBase
bool AllowResettingSettings() const override { return false; }
- void Save() override { }
+ bool Save() override { return true; }
void OnCancel() override;
void SetupView() override;
diff --git a/xbmc/pvr/PVRManager.h b/xbmc/pvr/PVRManager.h
index c22dcea95b..eb195e4ad1 100644
--- a/xbmc/pvr/PVRManager.h
+++ b/xbmc/pvr/PVRManager.h
@@ -75,6 +75,7 @@ namespace PVR
EpgContainer,
EpgItemUpdate,
EpgUpdatePending,
+ EpgDeleted,
// Item events
CurrentItem,
diff --git a/xbmc/pvr/addons/PVRClient.cpp b/xbmc/pvr/addons/PVRClient.cpp
index 226df1955b..1b8141edb1 100644
--- a/xbmc/pvr/addons/PVRClient.cpp
+++ b/xbmc/pvr/addons/PVRClient.cpp
@@ -121,7 +121,9 @@ void CPVRClient::ResetProperties(int iClientId /* = PVR_INVALID_CLIENT_ID */)
m_struct.props->strUserPath = m_strUserPath.c_str();
m_struct.props->strClientPath = m_strClientPath.c_str();
- m_struct.props->iEpgMaxDays =
+ m_struct.props->iEpgMaxPastDays =
+ CServiceBroker::GetPVRManager().EpgContainer().GetPastDaysToDisplay();
+ m_struct.props->iEpgMaxFutureDays =
CServiceBroker::GetPVRManager().EpgContainer().GetFutureDaysToDisplay();
m_struct.toKodi->kodiInstance = this;
@@ -683,11 +685,23 @@ PVR_ERROR CPVRClient::GetEPGForChannel(int iChannelUid, CPVREpg* epg, time_t sta
m_clientCapabilities.SupportsEPG());
}
-PVR_ERROR CPVRClient::SetEPGTimeFrame(int iDays)
+PVR_ERROR CPVRClient::SetEPGMaxPastDays(int iPastDays)
{
return DoAddonCall(
__func__,
- [iDays](const AddonInstance* addon) { return addon->toAddon->SetEPGTimeFrame(addon, iDays); },
+ [iPastDays](const AddonInstance* addon) {
+ return addon->toAddon->SetEPGMaxPastDays(addon, iPastDays);
+ },
+ m_clientCapabilities.SupportsEPG());
+}
+
+PVR_ERROR CPVRClient::SetEPGMaxFutureDays(int iFutureDays)
+{
+ return DoAddonCall(
+ __func__,
+ [iFutureDays](const AddonInstance* addon) {
+ return addon->toAddon->SetEPGMaxFutureDays(addon, iFutureDays);
+ },
m_clientCapabilities.SupportsEPG());
}
diff --git a/xbmc/pvr/addons/PVRClient.h b/xbmc/pvr/addons/PVRClient.h
index f85af4d0fc..a724cffd43 100644
--- a/xbmc/pvr/addons/PVRClient.h
+++ b/xbmc/pvr/addons/PVRClient.h
@@ -479,18 +479,36 @@ public:
PVR_ERROR GetEPGForChannel(int iChannelUid, CPVREpg* epg, time_t start, time_t end);
/*!
- * @brief Tell the client the time frame to use when notifying epg events back
+ * @brief Tell the client the past time frame to use when notifying epg events back
* to Kodi.
*
* The client might push epg events asynchronously to Kodi using the callback
* function EpgEventStateChange. To be able to only push events that are
- * actually of interest for Kodi, client needs to know about the epg time
+ * actually of interest for Kodi, client needs to know about the past epg time
* frame Kodi uses.
*
- * @param iDays number of days from "now". EPG_TIMEFRAME_UNLIMITED means that Kodi is interested in all epg events, regardless of event times.
+ * @param[in] iPastDays number of days before "now".
+ @ref EPG_TIMEFRAME_UNLIMITED means that Kodi is interested in all epg events,
+ regardless of event times.
* @return PVR_ERROR_NO_ERROR if new value was successfully set.
*/
- PVR_ERROR SetEPGTimeFrame(int iDays);
+ PVR_ERROR SetEPGMaxPastDays(int iPastDays);
+
+ /*!
+ * @brief Tell the client the future time frame to use when notifying epg events back
+ * to Kodi.
+ *
+ * The client might push epg events asynchronously to Kodi using the callback
+ * function EpgEventStateChange. To be able to only push events that are
+ * actually of interest for Kodi, client needs to know about the future epg time
+ * frame Kodi uses.
+ *
+ * @param[in] iFutureDays number of days after "now".
+ @ref EPG_TIMEFRAME_UNLIMITED means that Kodi is interested in all epg events,
+ regardless of event times.
+ * @return PVR_ERROR_NO_ERROR if new value was successfully set.
+ */
+ PVR_ERROR SetEPGMaxFutureDays(int iFutureDays);
//@}
/** @name PVR channel group methods */
diff --git a/xbmc/pvr/addons/PVRClients.cpp b/xbmc/pvr/addons/PVRClients.cpp
index 04e054db44..109c481f7a 100644
--- a/xbmc/pvr/addons/PVRClients.cpp
+++ b/xbmc/pvr/addons/PVRClients.cpp
@@ -529,10 +529,17 @@ PVR_ERROR CPVRClients::DeleteAllRecordingsFromTrash()
});
}
-PVR_ERROR CPVRClients::SetEPGTimeFrame(int iDays)
+PVR_ERROR CPVRClients::SetEPGMaxPastDays(int iPastDays)
{
- return ForCreatedClients(__FUNCTION__, [iDays](const std::shared_ptr<CPVRClient>& client) {
- return client->SetEPGTimeFrame(iDays);
+ return ForCreatedClients(__FUNCTION__, [iPastDays](const std::shared_ptr<CPVRClient>& client) {
+ return client->SetEPGMaxPastDays(iPastDays);
+ });
+}
+
+PVR_ERROR CPVRClients::SetEPGMaxFutureDays(int iFutureDays)
+{
+ return ForCreatedClients(__FUNCTION__, [iFutureDays](const std::shared_ptr<CPVRClient>& client) {
+ return client->SetEPGMaxFutureDays(iFutureDays);
});
}
diff --git a/xbmc/pvr/addons/PVRClients.h b/xbmc/pvr/addons/PVRClients.h
index 560cd0dc54..a9c54774d8 100644
--- a/xbmc/pvr/addons/PVRClients.h
+++ b/xbmc/pvr/addons/PVRClients.h
@@ -219,13 +219,34 @@ namespace PVR
//@{
/*!
- * Tell all clients the time frame to use when notifying epg events back to Kodi. The clients might push epg events asynchronously
- * to Kodi using the callback function EpgEventStateChange. To be able to only push events that are actually of interest for Kodi,
- * clients need to know about the epg time frame Kodi uses.
- * @param iDays number of days from "now". EPG_TIMEFRAME_UNLIMITED means that Kodi is interested in all epg events, regardless of event times.
- * @return PVR_ERROR_NO_ERROR if the operation succeeded, the respective PVR_ERROR value otherwise.
- */
- PVR_ERROR SetEPGTimeFrame(int iDays);
+ * @brief Tell all clients the past time frame to use when notifying epg events back to Kodi.
+ *
+ * The clients might push epg events asynchronously to Kodi using the callback function
+ * EpgEventStateChange. To be able to only push events that are actually of interest for Kodi,
+ * clients need to know about the future epg time frame Kodi uses.
+ *
+ * @param[in] iPastDays number of days before "now".
+ * @ref EPG_TIMEFRAME_UNLIMITED means that Kodi is interested in all
+ * epg events, regardless of event times.
+ * @return @ref PVR_ERROR_NO_ERROR if the operation succeeded, the respective @ref PVR_ERROR
+ * value otherwise.
+ */
+ PVR_ERROR SetEPGMaxPastDays(int iPastDays);
+
+ /*!
+ * @brief Tell all clients the future time frame to use when notifying epg events back to Kodi.
+ *
+ * The clients might push epg events asynchronously to Kodi using the callback function
+ * EpgEventStateChange. To be able to only push events that are actually of interest for Kodi,
+ * clients need to know about the future epg time frame Kodi uses.
+ *
+ * @param[in] iFutureDays number of days from "now".
+ * @ref EPG_TIMEFRAME_UNLIMITED means that Kodi is interested in all
+ * epg events, regardless of event times.
+ * @return @ref PVR_ERROR_NO_ERROR if the operation succeeded, the respective @ref PVR_ERROR
+ * value otherwise.
+ */
+ PVR_ERROR SetEPGMaxFutureDays(int iFutureDays);
//@}
diff --git a/xbmc/pvr/channels/PVRChannel.cpp b/xbmc/pvr/channels/PVRChannel.cpp
index 7798653929..7a8169baa6 100644
--- a/xbmc/pvr/channels/PVRChannel.cpp
+++ b/xbmc/pvr/channels/PVRChannel.cpp
@@ -41,7 +41,12 @@ bool CPVRChannel::operator!=(const CPVRChannel& right) const
return !(*this == right);
}
-CPVRChannel::CPVRChannel(bool bRadio /* = false */)
+CPVRChannel::CPVRChannel()
+{
+ UpdateEncryptionName();
+}
+
+CPVRChannel::CPVRChannel(bool bRadio)
: m_bIsRadio(bRadio)
{
UpdateEncryptionName();
@@ -67,6 +72,11 @@ CPVRChannel::CPVRChannel(const PVR_CHANNEL& channel, unsigned int iClientId)
UpdateEncryptionName();
}
+CPVRChannel::~CPVRChannel()
+{
+ ResetEPG();
+}
+
void CPVRChannel::Serialize(CVariant& value) const
{
value["channelid"] = m_iChannelId;
@@ -99,8 +109,6 @@ void CPVRChannel::Serialize(CVariant& value) const
value["clientid"] = m_iClientId;
}
-/********** XBMC related channel methods **********/
-
bool CPVRChannel::QueueDelete()
{
bool bReturn = false;
@@ -110,12 +118,7 @@ bool CPVRChannel::QueueDelete()
const std::shared_ptr<CPVREpg> epg = GetEPG();
if (epg)
- {
- CServiceBroker::GetPVRManager().EpgContainer().QueueDeleteEpg(epg);
-
- CSingleLock lock(m_critSection);
- m_epg.reset();
- }
+ ResetEPG();
bReturn = database->QueueDeleteQuery(*this);
return bReturn;
@@ -147,12 +150,39 @@ bool CPVRChannel::CreateEPG()
m_iEpgId = m_epg->EpgID();
m_bChanged = true;
}
+
+ // Subscribe for EPG delete event
+ m_epg->Events().Subscribe(this, &CPVRChannel::Notify);
return true;
}
}
return false;
}
+void CPVRChannel::Notify(const PVREvent& event)
+{
+ if (event == PVREvent::EpgDeleted)
+ {
+ ResetEPG();
+ }
+}
+
+void CPVRChannel::ResetEPG()
+{
+ std::shared_ptr<CPVREpg> epgToUnsubscribe;
+ {
+ CSingleLock lock(m_critSection);
+ if (m_epg)
+ {
+ epgToUnsubscribe = m_epg;
+ m_epg.reset();
+ }
+ }
+
+ if (epgToUnsubscribe)
+ epgToUnsubscribe->Events().Unsubscribe(this);
+}
+
bool CPVRChannel::UpdateFromClient(const std::shared_ptr<CPVRChannel>& channel)
{
SetClientID(channel->ClientID());
diff --git a/xbmc/pvr/channels/PVRChannel.h b/xbmc/pvr/channels/PVRChannel.h
index ff489197f6..ef4b6f4bbf 100644
--- a/xbmc/pvr/channels/PVRChannel.h
+++ b/xbmc/pvr/channels/PVRChannel.h
@@ -23,6 +23,8 @@ class CDateTime;
namespace PVR
{
+ enum class PVREvent;
+
class CPVREpg;
class CPVREpgInfoTag;
class CPVRRadioRDSInfoTag;
@@ -32,10 +34,10 @@ namespace PVR
friend class CPVRDatabase;
public:
- explicit CPVRChannel(bool bRadio = false);
+ explicit CPVRChannel(bool bRadio);
CPVRChannel(const PVR_CHANNEL& channel, unsigned int iClientId);
- virtual ~CPVRChannel() = default;
+ virtual ~CPVRChannel();
bool operator ==(const CPVRChannel& right) const;
bool operator !=(const CPVRChannel& right) const;
@@ -444,8 +446,25 @@ namespace PVR
*/
void SetClientOrder(int iOrder);
+ /*!
+ * @brief CEventStream callback for PVR events.
+ * @param event The event.
+ */
+ void Notify(const PVREvent& event);
+
+ /*!
+ * @brief Lock the instance. No other thread gets access to this channel until Unlock was called.
+ */
+ void Lock() { m_critSection.lock(); }
+
+ /*!
+ * @brief Unlock the instance. Other threads may get access to this channel again.
+ */
+ void Unlock() { m_critSection.unlock(); }
+
//@}
private:
+ CPVRChannel();
CPVRChannel(const CPVRChannel& tag) = delete;
CPVRChannel& operator=(const CPVRChannel& channel) = delete;
@@ -454,6 +473,11 @@ namespace PVR
*/
void UpdateEncryptionName();
+ /*!
+ * @brief Reset the EPG instance pointer.
+ */
+ void ResetEPG();
+
/*! @name XBMC related channel data
*/
//@{
diff --git a/xbmc/pvr/channels/PVRChannelGroupInternal.cpp b/xbmc/pvr/channels/PVRChannelGroupInternal.cpp
index fe21c30975..74bc4c560d 100644
--- a/xbmc/pvr/channels/PVRChannelGroupInternal.cpp
+++ b/xbmc/pvr/channels/PVRChannelGroupInternal.cpp
@@ -17,7 +17,6 @@
#include "pvr/addons/PVRClients.h"
#include "pvr/channels/PVRChannel.h"
#include "pvr/epg/EpgContainer.h"
-#include "pvr/epg/EpgDatabase.h"
#include "utils/Variant.h"
#include "utils/log.h"
@@ -282,46 +281,52 @@ bool CPVRChannelGroupInternal::AddAndUpdateChannels(const CPVRChannelGroup& chan
std::vector<std::shared_ptr<CPVRChannel>> CPVRChannelGroupInternal::RemoveDeletedChannels(const CPVRChannelGroup& channels)
{
std::vector<std::shared_ptr<CPVRChannel>> removedChannels = CPVRChannelGroup::RemoveDeletedChannels(channels);
-
- bool channelsDeleted = false;
-
- const std::shared_ptr<CPVRDatabase> database = CServiceBroker::GetPVRManager().GetTVDatabase();
- const std::shared_ptr<CPVREpgDatabase> epgDatabase =
- CServiceBroker::GetPVRManager().EpgContainer().GetEpgDatabase();
- if (!database || !epgDatabase)
- {
- CLog::LogF(LOGERROR, "No TV or EPG database");
- }
- else
+ if (!removedChannels.empty())
{
- // Note: We must lock the dbs the whole time, otherwise races may occur.
- database->Lock();
- epgDatabase->Lock();
+ bool channelsDeleted = false;
- for (const auto& channel : removedChannels)
+ const std::shared_ptr<CPVRDatabase> database = CServiceBroker::GetPVRManager().GetTVDatabase();
+ if (!database)
{
- // since channel was not found in the internal group, it was deleted from the backend
- channelsDeleted |= channel->QueueDelete();
+ CLog::LogF(LOGERROR, "No TV database");
+ }
+ else
+ {
+ std::vector<std::shared_ptr<CPVREpg>> epgsToRemove;
+
+ for (const auto& channel : removedChannels)
+ {
+ const auto epg = channel->GetEPG();
+ if (epg)
+ epgsToRemove.emplace_back(epg);
- size_t queryCount = epgDatabase->GetDeleteQueriesCount();
- if (queryCount > EPG_COMMIT_QUERY_COUNT_LIMIT)
- epgDatabase->CommitDeleteQueries();
+ // Note: We need to obtain a lock for every channel instance before we can lock
+ // the TV db. This order is important. Otherwise deadlocks may occur.
+ channel->Lock();
+ }
+
+ // Note: We must lock the db the whole time, otherwise races may occur.
+ database->Lock();
+ for (const auto& channel : removedChannels)
+ {
+ // since channel was not found in the internal group, it was deleted from the backend
+ channelsDeleted |= channel->QueueDelete();
+ channel->Unlock();
+
+ size_t queryCount = database->GetDeleteQueriesCount();
+ if (queryCount > CHANNEL_COMMIT_QUERY_COUNT_LIMIT)
+ database->CommitDeleteQueries();
+ }
- queryCount = database->GetDeleteQueriesCount();
- if (queryCount > CHANNEL_COMMIT_QUERY_COUNT_LIMIT)
+ if (channelsDeleted)
database->CommitDeleteQueries();
- }
- if (channelsDeleted)
- {
- epgDatabase->CommitDeleteQueries();
- database->CommitDeleteQueries();
- }
+ database->Unlock();
- epgDatabase->Unlock();
- database->Unlock();
+ // delete the EPG data for the removed channels
+ CServiceBroker::GetPVRManager().EpgContainer().QueueDeleteEpgs(epgsToRemove);
+ }
}
-
return removedChannels;
}
diff --git a/xbmc/pvr/dialogs/GUIDialogPVRClientPriorities.cpp b/xbmc/pvr/dialogs/GUIDialogPVRClientPriorities.cpp
index 5e9ac641d9..faedba85d7 100644
--- a/xbmc/pvr/dialogs/GUIDialogPVRClientPriorities.cpp
+++ b/xbmc/pvr/dialogs/GUIDialogPVRClientPriorities.cpp
@@ -89,7 +89,7 @@ void CGUIDialogPVRClientPriorities::OnSettingChanged(const std::shared_ptr<const
m_changedValues[setting->GetId()] = std::static_pointer_cast<const CSettingInt>(setting)->GetValue();
}
-void CGUIDialogPVRClientPriorities::Save()
+bool CGUIDialogPVRClientPriorities::Save()
{
for (const auto& changedClient : m_changedValues)
{
@@ -98,4 +98,6 @@ void CGUIDialogPVRClientPriorities::Save()
if (clientEntry != m_clients.end())
clientEntry->second->SetPriority(changedClient.second);
}
+
+ return true;
}
diff --git a/xbmc/pvr/dialogs/GUIDialogPVRClientPriorities.h b/xbmc/pvr/dialogs/GUIDialogPVRClientPriorities.h
index 6cd9ce2c3d..a6ca62dd6f 100644
--- a/xbmc/pvr/dialogs/GUIDialogPVRClientPriorities.h
+++ b/xbmc/pvr/dialogs/GUIDialogPVRClientPriorities.h
@@ -28,7 +28,7 @@ namespace PVR
// specialization of CGUIDialogSettingsBase
std::string GetSettingsLabel(const std::shared_ptr<ISetting>& pSetting) override;
bool AllowResettingSettings() const override { return false; }
- void Save() override;
+ bool Save() override;
void SetupView() override;
// specialization of CGUIDialogSettingsManualBase
diff --git a/xbmc/pvr/dialogs/GUIDialogPVRRecordingSettings.cpp b/xbmc/pvr/dialogs/GUIDialogPVRRecordingSettings.cpp
index d08999cce4..e9ae166be0 100644
--- a/xbmc/pvr/dialogs/GUIDialogPVRRecordingSettings.cpp
+++ b/xbmc/pvr/dialogs/GUIDialogPVRRecordingSettings.cpp
@@ -168,7 +168,7 @@ void CGUIDialogPVRRecordingSettings::OnSettingChanged(
}
}
-void CGUIDialogPVRRecordingSettings::Save()
+bool CGUIDialogPVRRecordingSettings::Save()
{
// Name
m_recording->m_strTitle = m_strTitle;
@@ -178,6 +178,8 @@ void CGUIDialogPVRRecordingSettings::Save()
// Lifetime
m_recording->m_iLifetime = m_iLifetime;
+
+ return true;
}
void CGUIDialogPVRRecordingSettings::LifetimesFiller(const SettingConstPtr& setting,
diff --git a/xbmc/pvr/dialogs/GUIDialogPVRRecordingSettings.h b/xbmc/pvr/dialogs/GUIDialogPVRRecordingSettings.h
index f5dd9566ce..11c88a6917 100644
--- a/xbmc/pvr/dialogs/GUIDialogPVRRecordingSettings.h
+++ b/xbmc/pvr/dialogs/GUIDialogPVRRecordingSettings.h
@@ -38,7 +38,7 @@ namespace PVR
// specialization of CGUIDialogSettingsBase
bool AllowResettingSettings() const override { return false; }
- void Save() override;
+ bool Save() override;
void SetupView() override;
// specialization of CGUIDialogSettingsManualBase
diff --git a/xbmc/pvr/dialogs/GUIDialogPVRTimerSettings.cpp b/xbmc/pvr/dialogs/GUIDialogPVRTimerSettings.cpp
index 0c9cbec447..c328b22d4b 100644
--- a/xbmc/pvr/dialogs/GUIDialogPVRTimerSettings.cpp
+++ b/xbmc/pvr/dialogs/GUIDialogPVRTimerSettings.cpp
@@ -12,6 +12,7 @@
#include "dialogs/GUIDialogNumeric.h"
#include "guilib/GUIMessage.h"
#include "guilib/LocalizeStrings.h"
+#include "messaging/helpers/DialogOKHelper.h"
#include "pvr/PVRManager.h"
#include "pvr/addons/PVRClient.h"
#include "pvr/addons/PVRClients.h"
@@ -36,6 +37,7 @@
#include <vector>
using namespace PVR;
+using namespace KODI::MESSAGING;
#define SETTING_TMR_TYPE "timer.type"
#define SETTING_TMR_ACTIVE "timer.active"
@@ -526,8 +528,41 @@ void CGUIDialogPVRTimerSettings::OnSettingAction(const std::shared_ptr<const CSe
}
}
-void CGUIDialogPVRTimerSettings::Save()
+bool CGUIDialogPVRTimerSettings::Validate()
{
+ bool bStartAnyTime = m_bStartAnyTime;
+ bool bEndAnyTime = m_bEndAnyTime;
+
+ if (!m_timerType->SupportsStartAnyTime() ||
+ !m_timerType->IsEpgBased()) // Start anytime toggle is not displayed
+ bStartAnyTime = false; // Assume start time change needs checking for
+
+ if (!m_timerType->SupportsEndAnyTime() ||
+ !m_timerType->IsEpgBased()) // End anytime toggle is not displayed
+ bEndAnyTime = false; // Assume end time change needs checking for
+
+ // Begin and end time
+ if (!bStartAnyTime && !bEndAnyTime)
+ {
+ if (!(m_timerType->SupportsStartTime() && // has start clock entry
+ m_timerType->SupportsEndTime() && // and end clock entry
+ m_timerType->IsTimerRule()) && // but no associated start/end day spinners
+ m_endLocalTime < m_startLocalTime)
+ {
+ HELPERS::ShowOKDialogText(CVariant{19065}, // "Timer settings"
+ CVariant{19072}); // In order to add/update a timer
+ return false;
+ }
+ }
+
+ return true;
+}
+
+bool CGUIDialogPVRTimerSettings::Save()
+{
+ if (!Validate())
+ return false;
+
// Timer type
m_timerInfoTag->SetTimerType(m_timerType);
@@ -585,9 +620,9 @@ void CGUIDialogPVRTimerSettings::Save()
}
}
}
- else if (m_endLocalTime < m_startLocalTime) // Assume the user knows what they are doing, but log a warning just in case
+ else if (m_endLocalTime < m_startLocalTime)
{
- CLog::Log(LOGWARNING, "Timer settings dialog: Specified recording end time < start time: expect errors!");
+ // this case will fail validation so this can't be reached.
}
m_timerInfoTag->SetStartFromLocalTime(m_startLocalTime);
m_timerInfoTag->SetEndFromLocalTime(m_endLocalTime);
@@ -638,6 +673,8 @@ void CGUIDialogPVRTimerSettings::Save()
// Update summary
m_timerInfoTag->UpdateSummary();
+
+ return true;
}
void CGUIDialogPVRTimerSettings::SetButtonLabels()
diff --git a/xbmc/pvr/dialogs/GUIDialogPVRTimerSettings.h b/xbmc/pvr/dialogs/GUIDialogPVRTimerSettings.h
index ec8da192a3..cf7458a98c 100644
--- a/xbmc/pvr/dialogs/GUIDialogPVRTimerSettings.h
+++ b/xbmc/pvr/dialogs/GUIDialogPVRTimerSettings.h
@@ -45,13 +45,14 @@ namespace PVR
// specialization of CGUIDialogSettingsBase
bool AllowResettingSettings() const override { return false; }
- void Save() override;
+ bool Save() override;
void SetupView() override;
// specialization of CGUIDialogSettingsManualBase
void InitializeSettings() override;
private:
+ bool Validate();
void InitializeTypesList();
void InitializeChannelsList();
void SetButtonLabels();
diff --git a/xbmc/pvr/epg/Epg.cpp b/xbmc/pvr/epg/Epg.cpp
index e78c80a4f3..39e40b5112 100644
--- a/xbmc/pvr/epg/Epg.cpp
+++ b/xbmc/pvr/epg/Epg.cpp
@@ -547,3 +547,8 @@ bool CPVREpg::IsValid() const
return true;
}
+
+void CPVREpg::RemovedFromContainer()
+{
+ m_events.Publish(PVREvent::EpgDeleted);
+}
diff --git a/xbmc/pvr/epg/Epg.h b/xbmc/pvr/epg/Epg.h
index b1f51f1f5f..f5691970e7 100644
--- a/xbmc/pvr/epg/Epg.h
+++ b/xbmc/pvr/epg/Epg.h
@@ -277,6 +277,11 @@ namespace PVR
*/
void Unlock() { m_critSection.unlock(); }
+ /*!
+ * @brief Called to inform the EPG that it has been removed from the EPG container.
+ */
+ void RemovedFromContainer();
+
private:
CPVREpg() = delete;
CPVREpg(const CPVREpg&) = delete;
diff --git a/xbmc/pvr/epg/EpgContainer.cpp b/xbmc/pvr/epg/EpgContainer.cpp
index 351726bb82..867c6db0e4 100644
--- a/xbmc/pvr/epg/EpgContainer.cpp
+++ b/xbmc/pvr/epg/EpgContainer.cpp
@@ -206,7 +206,10 @@ void CPVREpgContainer::Unload()
}
for (const auto& epg : epgs)
+ {
epg->Events().Unsubscribe(this);
+ epg->RemovedFromContainer();
+ }
m_events.Publish(PVREvent::EpgContainer);
}
@@ -265,7 +268,7 @@ bool CPVREpgContainer::PersistAll(unsigned int iMaxTimeslice) const
if (epg.second && epg.second->NeedsSave())
{
// Note: We need to obtain a lock for every epg instance before we can lock
- // the epg db. This order is important. Otherwise deadlocks may occure.
+ // the epg db. This order is important. Otherwise deadlocks may occur.
epg.second->Lock();
changedEpgs.emplace_back(epg.second);
}
@@ -276,7 +279,7 @@ bool CPVREpgContainer::PersistAll(unsigned int iMaxTimeslice) const
if (!changedEpgs.empty())
{
- // Note: We must lock the db the whole time, otherwise races may occure.
+ // Note: We must lock the db the whole time, otherwise races may occur.
database->Lock();
XbmcThreads::EndTime processTimeslice(iMaxTimeslice);
@@ -609,6 +612,41 @@ bool CPVREpgContainer::RemoveOldEntries()
return true;
}
+bool CPVREpgContainer::QueueDeleteEpgs(const std::vector<std::shared_ptr<CPVREpg>>& epgs)
+{
+ if (epgs.empty())
+ return true;
+
+ const std::shared_ptr<CPVREpgDatabase> database = GetEpgDatabase();
+ if (!database)
+ {
+ CLog::LogF(LOGERROR, "No EPG database");
+ return false;
+ }
+
+ for (const auto& epg : epgs)
+ {
+ // Note: We need to obtain a lock for every epg instance before we can lock
+ // the epg db. This order is important. Otherwise deadlocks may occur.
+ epg->Lock();
+ }
+
+ database->Lock();
+ for (const auto& epg : epgs)
+ {
+ QueueDeleteEpg(epg);
+ epg->Unlock();
+
+ size_t queryCount = database->GetDeleteQueriesCount();
+ if (queryCount > EPG_COMMIT_QUERY_COUNT_LIMIT)
+ database->CommitDeleteQueries();
+ }
+ database->CommitDeleteQueries();
+ database->Unlock();
+
+ return true;
+}
+
bool CPVREpgContainer::QueueDeleteEpg(const std::shared_ptr<CPVREpg>& epg)
{
if (!epg || epg->EpgID() < 0)
@@ -642,6 +680,7 @@ bool CPVREpgContainer::QueueDeleteEpg(const std::shared_ptr<CPVREpg>& epg)
}
epgToDelete->Events().Unsubscribe(this);
+ epgToDelete->RemovedFromContainer();
return true;
}
@@ -743,17 +782,7 @@ bool CPVREpgContainer::UpdateEPG(bool bOnlyPending /* = false */)
if (bShowProgress && !bOnlyPending)
progressHandler->DestroyProgress();
- database->Lock();
- for (const auto& epg : invalidTables)
- {
- QueueDeleteEpg(epg);
-
- size_t queryCount = database->GetDeleteQueriesCount();
- if (queryCount > EPG_COMMIT_QUERY_COUNT_LIMIT)
- database->CommitDeleteQueries();
- }
- database->CommitDeleteQueries();
- database->Unlock();
+ QueueDeleteEpgs(invalidTables);
if (bInterrupted)
{
diff --git a/xbmc/pvr/epg/EpgContainer.h b/xbmc/pvr/epg/EpgContainer.h
index 19ab97003e..0847c8a8de 100644
--- a/xbmc/pvr/epg/EpgContainer.h
+++ b/xbmc/pvr/epg/EpgContainer.h
@@ -91,11 +91,11 @@ namespace PVR
bool IsStarted() const;
/*!
- * @brief Queue the deletion of an EPG table from this container.
- * @param epg The table to delete.
+ * @brief Queue the deletion of the given EPG tables from this container.
+ * @param epg The tables to delete.
* @return True on success, false otherwise.
*/
- bool QueueDeleteEpg(const std::shared_ptr<CPVREpg>& epg);
+ bool QueueDeleteEpgs(const std::vector<std::shared_ptr<CPVREpg>>& epgs);
/*!
* @brief CEventStream callback for PVR events.
@@ -280,6 +280,13 @@ namespace PVR
*/
void InsertFromDB(const std::shared_ptr<CPVREpg>& newEpg);
+ /*!
+ * @brief Queue the deletion of an EPG table from this container.
+ * @param epg The table to delete.
+ * @return True on success, false otherwise.
+ */
+ bool QueueDeleteEpg(const std::shared_ptr<CPVREpg>& epg);
+
std::shared_ptr<CPVREpgDatabase> m_database; /*!< the EPG database */
bool m_bIsUpdating = false; /*!< true while an update is running */
diff --git a/xbmc/pvr/guilib/PVRGUIActionListener.cpp b/xbmc/pvr/guilib/PVRGUIActionListener.cpp
index d4fb39b185..ecb9754ccd 100644
--- a/xbmc/pvr/guilib/PVRGUIActionListener.cpp
+++ b/xbmc/pvr/guilib/PVRGUIActionListener.cpp
@@ -48,6 +48,7 @@ CPVRGUIActionListener::CPVRGUIActionListener()
CSettings::SETTING_PVRMANAGER_CHANNELSCAN,
CSettings::SETTING_PVRMENU_SEARCHICONS,
CSettings::SETTING_PVRCLIENT_MENUHOOK,
+ CSettings::SETTING_EPG_PAST_DAYSTODISPLAY,
CSettings::SETTING_EPG_FUTURE_DAYSTODISPLAY
});
}
@@ -293,9 +294,15 @@ void CPVRGUIActionListener::OnSettingChanged(const std::shared_ptr<const CSettin
std::static_pointer_cast<CSettingBool>(std::const_pointer_cast<CSetting>(setting))->SetValue(false);
}
}
+ else if (settingId == CSettings::SETTING_EPG_PAST_DAYSTODISPLAY)
+ {
+ CServiceBroker::GetPVRManager().Clients()->SetEPGMaxPastDays(
+ std::static_pointer_cast<const CSettingInt>(setting)->GetValue());
+ }
else if (settingId == CSettings::SETTING_EPG_FUTURE_DAYSTODISPLAY)
{
- CServiceBroker::GetPVRManager().Clients()->SetEPGTimeFrame(std::static_pointer_cast<const CSettingInt>(setting)->GetValue());
+ CServiceBroker::GetPVRManager().Clients()->SetEPGMaxFutureDays(
+ std::static_pointer_cast<const CSettingInt>(setting)->GetValue());
}
}
diff --git a/xbmc/pvr/windows/GUIWindowPVRGuide.cpp b/xbmc/pvr/windows/GUIWindowPVRGuide.cpp
index eedd212b09..67805e6bae 100644
--- a/xbmc/pvr/windows/GUIWindowPVRGuide.cpp
+++ b/xbmc/pvr/windows/GUIWindowPVRGuide.cpp
@@ -503,7 +503,8 @@ bool CGUIWindowPVRGuideBase::OnMessage(CGUIMessage& message)
}
}
else if (message.GetSenderId() == CONTROL_BTNVIEWASICONS ||
- message.GetSenderId() == CONTROL_BTNSORTBY)
+ message.GetSenderId() == CONTROL_BTNSORTBY ||
+ message.GetSenderId() == CONTROL_BTNSORTASC)
{
RefreshView(message, false);
bReturn = true;
diff --git a/xbmc/rendering/dx/DeviceResources.cpp b/xbmc/rendering/dx/DeviceResources.cpp
index b66078e475..c70f62f9a6 100644
--- a/xbmc/rendering/dx/DeviceResources.cpp
+++ b/xbmc/rendering/dx/DeviceResources.cpp
@@ -81,6 +81,7 @@ DX::DeviceResources::DeviceResources()
, m_stereoEnabled(false)
, m_bDeviceCreated(false)
, m_IsHDROutput(false)
+ , m_IsTransferPQ(false)
{
}
@@ -1164,7 +1165,7 @@ void DX::DeviceResources::SetHdrMetaData(DXGI_HDR_METADATA_HDR10& hdr10) const
}
}
-void DX::DeviceResources::SetHdrColorSpace(const DXGI_COLOR_SPACE_TYPE colorSpace) const
+void DX::DeviceResources::SetHdrColorSpace(const DXGI_COLOR_SPACE_TYPE colorSpace)
{
ComPtr<IDXGISwapChain3> swapChain3;
@@ -1188,6 +1189,9 @@ void DX::DeviceResources::SetHdrColorSpace(const DXGI_COLOR_SPACE_TYPE colorSpac
}
if (SUCCEEDED(swapChain3->SetColorSpace1(cs)))
{
+ m_IsTransferPQ = cs == DXGI_COLOR_SPACE_RGB_FULL_G2084_NONE_P2020 ||
+ cs == DXGI_COLOR_SPACE_RGB_STUDIO_G2084_NONE_P2020;
+
CLog::LogF(LOGDEBUG, "DXGI SetColorSpace1 success");
}
else
@@ -1220,6 +1224,7 @@ HDR_STATUS DX::DeviceResources::ToggleHDR()
m_swapChain = nullptr;
m_deferrContext->Flush();
m_d3dContext->Flush();
+ m_IsTransferPQ = false;
}
DX::Windowing()->SetAlteringWindow(false);
diff --git a/xbmc/rendering/dx/DeviceResources.h b/xbmc/rendering/dx/DeviceResources.h
index 1a973badec..f972719f52 100644
--- a/xbmc/rendering/dx/DeviceResources.h
+++ b/xbmc/rendering/dx/DeviceResources.h
@@ -81,8 +81,9 @@ namespace DX
// HDR display support
HDR_STATUS ToggleHDR();
void SetHdrMetaData(DXGI_HDR_METADATA_HDR10& hdr10) const;
- void SetHdrColorSpace(const DXGI_COLOR_SPACE_TYPE colorSpace) const;
+ void SetHdrColorSpace(const DXGI_COLOR_SPACE_TYPE colorSpace);
bool IsHDROutput() const { return m_IsHDROutput; }
+ bool IsTransferPQ() const { return m_IsTransferPQ; }
// DX resources registration
void Register(ID3DResource *resource);
@@ -167,6 +168,7 @@ namespace DX
bool m_stereoEnabled;
bool m_bDeviceCreated;
bool m_IsHDROutput;
+ bool m_IsTransferPQ;
bool m_NV12SharedTexturesSupport{false};
};
}
diff --git a/xbmc/settings/AdvancedSettings.cpp b/xbmc/settings/AdvancedSettings.cpp
index 10d0212078..00610582ab 100644
--- a/xbmc/settings/AdvancedSettings.cpp
+++ b/xbmc/settings/AdvancedSettings.cpp
@@ -8,32 +8,33 @@
#include "AdvancedSettings.h"
-#include <climits>
-#include <algorithm>
-#include <string>
-#include <vector>
-
#include "AppParamParser.h"
#include "Application.h"
+#include "LangInfo.h"
#include "ServiceBroker.h"
#include "filesystem/File.h"
#include "filesystem/SpecialProtocol.h"
-#include "LangInfo.h"
#include "network/DNSNameCache.h"
#include "profiles/ProfileManager.h"
+#include "settings/SettingUtils.h"
+#include "settings/Settings.h"
+#include "settings/SettingsComponent.h"
#include "settings/lib/Setting.h"
#include "settings/lib/SettingDefinitions.h"
#include "settings/lib/SettingsManager.h"
-#include "settings/Settings.h"
-#include "settings/SettingsComponent.h"
-#include "settings/SettingUtils.h"
#include "utils/LangCodeExpander.h"
-#include "utils/log.h"
#include "utils/StringUtils.h"
#include "utils/SystemInfo.h"
#include "utils/URIUtils.h"
#include "utils/Variant.h"
#include "utils/XMLUtils.h"
+#include "utils/log.h"
+
+#include <algorithm>
+#include <climits>
+#include <regex>
+#include <string>
+#include <vector>
using namespace ADDON;
using namespace XFILE;
@@ -521,7 +522,10 @@ void CAdvancedSettings::ParseSettingsFile(const std::string &file)
printer.SetLineBreak("\n");
printer.SetIndent(" ");
advancedXMLCopy.Accept(&printer);
- CLog::Log(LOGINFO, "Contents of %s are...\n%s", file.c_str(), printer.CStr());
+ // redact User/pass in URLs
+ std::regex redactRe("(\\w+://)\\S+:\\S+@");
+ CLog::Log(LOGINFO, "Contents of {} are...\n{}", file,
+ std::regex_replace(printer.CStr(), redactRe, "$1USERNAME:PASSWORD@"));
TiXmlElement *pElement = pRootElement->FirstChildElement("audio");
if (pElement)
@@ -819,6 +823,7 @@ void CAdvancedSettings::ParseSettingsFile(const std::string &file)
XMLUtils::GetInt(pElement, "curlretries", m_curlretries, 0, 10);
XMLUtils::GetBoolean(pElement, "disableipv6", m_curlDisableIPV6);
XMLUtils::GetBoolean(pElement, "disablehttp2", m_curlDisableHTTP2);
+ XMLUtils::GetString(pElement, "catrustfile", m_caTrustFile);
}
pElement = pRootElement->FirstChildElement("cache");
@@ -1010,8 +1015,8 @@ void CAdvancedSettings::ParseSettingsFile(const std::string &file)
if (!strFrom.empty() && !strTo.empty())
{
CLog::Log(LOGDEBUG," Registering substitution pair:");
- CLog::Log(LOGDEBUG," From: [%s]", strFrom.c_str());
- CLog::Log(LOGDEBUG," To: [%s]", strTo.c_str());
+ CLog::Log(LOGDEBUG, " From: [{}]", CURL::GetRedacted(strFrom));
+ CLog::Log(LOGDEBUG, " To: [{}]", CURL::GetRedacted(strTo));
m_pathSubstitutions.push_back(std::make_pair(strFrom,strTo));
}
else
diff --git a/xbmc/settings/AdvancedSettings.h b/xbmc/settings/AdvancedSettings.h
index 95f3b28c52..a8bdcc5c99 100644
--- a/xbmc/settings/AdvancedSettings.h
+++ b/xbmc/settings/AdvancedSettings.h
@@ -288,6 +288,8 @@ class CAdvancedSettings : public ISettingCallback, public ISettingsHandler
bool m_curlDisableIPV6;
bool m_curlDisableHTTP2;
+ std::string m_caTrustFile;
+
bool m_fullScreen;
bool m_startFullScreen;
bool m_showExitButton; /* Ideal for appliances to hide a 'useless' button */
diff --git a/xbmc/settings/dialogs/GUIDialogContentSettings.cpp b/xbmc/settings/dialogs/GUIDialogContentSettings.cpp
index 898c5c36a5..56b0e83ad6 100644
--- a/xbmc/settings/dialogs/GUIDialogContentSettings.cpp
+++ b/xbmc/settings/dialogs/GUIDialogContentSettings.cpp
@@ -260,9 +260,10 @@ void CGUIDialogContentSettings::OnSettingAction(const std::shared_ptr<const CSet
CGUIDialogAddonSettings::ShowForAddon(m_scraper, false);
}
-void CGUIDialogContentSettings::Save()
+bool CGUIDialogContentSettings::Save()
{
//Should be saved by caller of ::Show
+ return true;
}
void CGUIDialogContentSettings::SetupView()
diff --git a/xbmc/settings/dialogs/GUIDialogContentSettings.h b/xbmc/settings/dialogs/GUIDialogContentSettings.h
index 1c4401c70f..7733ecca6f 100644
--- a/xbmc/settings/dialogs/GUIDialogContentSettings.h
+++ b/xbmc/settings/dialogs/GUIDialogContentSettings.h
@@ -56,7 +56,7 @@ protected:
// specialization of CGUIDialogSettingsBase
bool AllowResettingSettings() const override { return false; }
- void Save() override;
+ bool Save() override;
void SetupView() override;
// specialization of CGUIDialogSettingsManualBase
diff --git a/xbmc/settings/dialogs/GUIDialogLibExportSettings.cpp b/xbmc/settings/dialogs/GUIDialogLibExportSettings.cpp
index 8ed9a7d79f..ee89d17507 100644
--- a/xbmc/settings/dialogs/GUIDialogLibExportSettings.cpp
+++ b/xbmc/settings/dialogs/GUIDialogLibExportSettings.cpp
@@ -235,7 +235,7 @@ void CGUIDialogLibExportSettings::OnOK()
Close();
}
-void CGUIDialogLibExportSettings::Save()
+bool CGUIDialogLibExportSettings::Save()
{
CLog::Log(LOGINFO, "CGUIDialogMusicExportSettings: Save() called");
const std::shared_ptr<CSettings> settings = CServiceBroker::GetSettingsComponent()->GetSettings();
@@ -247,6 +247,8 @@ void CGUIDialogLibExportSettings::Save()
settings->SetBool(CSettings::SETTING_MUSICLIBRARY_EXPORT_ARTWORK, m_settings.m_artwork);
settings->SetBool(CSettings::SETTING_MUSICLIBRARY_EXPORT_SKIPNFO, m_settings.m_skipnfo);
settings->Save();
+
+ return true;
}
void CGUIDialogLibExportSettings::SetupView()
diff --git a/xbmc/settings/dialogs/GUIDialogLibExportSettings.h b/xbmc/settings/dialogs/GUIDialogLibExportSettings.h
index f948057af3..dd37020f0a 100644
--- a/xbmc/settings/dialogs/GUIDialogLibExportSettings.h
+++ b/xbmc/settings/dialogs/GUIDialogLibExportSettings.h
@@ -33,7 +33,7 @@ protected:
// specialization of CGUIDialogSettingsBase
bool OnMessage(CGUIMessage& message) override;
bool AllowResettingSettings() const override { return false; }
- void Save() override;
+ bool Save() override;
void SetupView() override;
// specialization of CGUIDialogSettingsManualBase
diff --git a/xbmc/settings/dialogs/GUIDialogSettingsBase.cpp b/xbmc/settings/dialogs/GUIDialogSettingsBase.cpp
index a0a523c888..5554460b27 100644
--- a/xbmc/settings/dialogs/GUIDialogSettingsBase.cpp
+++ b/xbmc/settings/dialogs/GUIDialogSettingsBase.cpp
@@ -193,9 +193,13 @@ bool CGUIDialogSettingsBase::OnMessage(CGUIMessage& message)
int iControl = message.GetSenderId();
if (iControl == CONTROL_SETTINGS_OKAY_BUTTON)
{
- OnOkay();
- Close();
- return true;
+ if (OnOkay())
+ {
+ Close();
+ return true;
+ }
+
+ return false;
}
if (iControl == CONTROL_SETTINGS_CANCEL_BUTTON)
diff --git a/xbmc/settings/dialogs/GUIDialogSettingsBase.h b/xbmc/settings/dialogs/GUIDialogSettingsBase.h
index 940091f10f..ee44f9f229 100644
--- a/xbmc/settings/dialogs/GUIDialogSettingsBase.h
+++ b/xbmc/settings/dialogs/GUIDialogSettingsBase.h
@@ -95,7 +95,11 @@ protected:
virtual unsigned int GetDelayMs() const { return 1500; }
virtual std::string GetLocalizedString(uint32_t labelId) const;
- virtual void OnOkay() { m_confirmed = true; }
+ virtual bool OnOkay()
+ {
+ m_confirmed = true;
+ return true;
+ }
virtual void OnCancel() {}
virtual void SetupView();
diff --git a/xbmc/settings/dialogs/GUIDialogSettingsManagerBase.cpp b/xbmc/settings/dialogs/GUIDialogSettingsManagerBase.cpp
index daa472d30d..e01edfb079 100644
--- a/xbmc/settings/dialogs/GUIDialogSettingsManagerBase.cpp
+++ b/xbmc/settings/dialogs/GUIDialogSettingsManagerBase.cpp
@@ -25,11 +25,15 @@ std::shared_ptr<CSetting> CGUIDialogSettingsManagerBase::GetSetting(const std::s
return GetSettingsManager()->GetSetting(settingId);
}
-void CGUIDialogSettingsManagerBase::OnOkay()
+bool CGUIDialogSettingsManagerBase::OnOkay()
{
- Save();
+ if (Save())
+ {
+ CGUIDialogSettingsBase::OnOkay();
+ return true;
+ }
- CGUIDialogSettingsBase::OnOkay();
+ return false;
}
std::set<std::string> CGUIDialogSettingsManagerBase::CreateSettings()
diff --git a/xbmc/settings/dialogs/GUIDialogSettingsManagerBase.h b/xbmc/settings/dialogs/GUIDialogSettingsManagerBase.h
index c1f75f4550..42c3c319c6 100644
--- a/xbmc/settings/dialogs/GUIDialogSettingsManagerBase.h
+++ b/xbmc/settings/dialogs/GUIDialogSettingsManagerBase.h
@@ -19,12 +19,12 @@ public:
~CGUIDialogSettingsManagerBase() override;
protected:
- virtual void Save() = 0;
+ virtual bool Save() = 0;
virtual CSettingsManager* GetSettingsManager() const = 0;
// implementation of CGUIDialogSettingsBase
std::shared_ptr<CSetting> GetSetting(const std::string &settingId) override;
- void OnOkay() override;
+ bool OnOkay() override;
std::set<std::string> CreateSettings() override;
void FreeSettingsControls() override;
diff --git a/xbmc/settings/windows/GUIWindowSettingsCategory.cpp b/xbmc/settings/windows/GUIWindowSettingsCategory.cpp
index 18d3cb7d58..ca6f7fd20b 100644
--- a/xbmc/settings/windows/GUIWindowSettingsCategory.cpp
+++ b/xbmc/settings/windows/GUIWindowSettingsCategory.cpp
@@ -186,9 +186,11 @@ SettingSectionPtr CGUIWindowSettingsCategory::GetSection()
return NULL;
}
-void CGUIWindowSettingsCategory::Save()
+bool CGUIWindowSettingsCategory::Save()
{
m_settings->Save();
+
+ return true;
}
CSettingsManager* CGUIWindowSettingsCategory::GetSettingsManager() const
diff --git a/xbmc/settings/windows/GUIWindowSettingsCategory.h b/xbmc/settings/windows/GUIWindowSettingsCategory.h
index dc5a5112c9..e1989c949f 100644
--- a/xbmc/settings/windows/GUIWindowSettingsCategory.h
+++ b/xbmc/settings/windows/GUIWindowSettingsCategory.h
@@ -34,7 +34,7 @@ protected:
// implementation of CGUIDialogSettingsBase
int GetSettingLevel() const override;
std::shared_ptr<CSettingSection> GetSection() override;
- void Save() override;
+ bool Save() override;
// implementation of CGUIDialogSettingsManagerBase
CSettingsManager* GetSettingsManager() const override;
diff --git a/xbmc/storage/MediaManager.cpp b/xbmc/storage/MediaManager.cpp
index f975294ec1..f1bb23f099 100644
--- a/xbmc/storage/MediaManager.cpp
+++ b/xbmc/storage/MediaManager.cpp
@@ -767,23 +767,27 @@ bool CMediaManager::playStubFile(const CFileItem& item)
{
// Figure out Lines 1 and 2 of the dialog
std::string strLine1, strLine2;
+
+ // use generic message by default
+ strLine1 = g_localizeStrings.Get(435).c_str();
+ strLine2 = g_localizeStrings.Get(436).c_str();
+
CXBMCTinyXML discStubXML;
if (discStubXML.LoadFile(item.GetPath()))
{
TiXmlElement* pRootElement = discStubXML.RootElement();
if (!pRootElement || StringUtils::CompareNoCase(pRootElement->Value(), "discstub") != 0)
- CLog::Log(LOGERROR, "Error loading %s, no <discstub> node", item.GetPath().c_str());
+ CLog::Log(LOGINFO, "No <discstub> node found for %s. Using default info dialog message", item.GetPath().c_str());
else
{
XMLUtils::GetString(pRootElement, "title", strLine1);
XMLUtils::GetString(pRootElement, "message", strLine2);
+ // no title? use the label of the CFileItem as line 1
+ if (strLine1.empty())
+ strLine1 = item.GetLabel();
}
}
- // Use the label for Line 1 if not defined
- if (strLine1.empty())
- strLine1 = item.GetLabel();
-
if (HasOpticalDrive())
{
#ifdef HAS_DVD_DRIVE
diff --git a/xbmc/video/VideoDatabase.cpp b/xbmc/video/VideoDatabase.cpp
index 89bdbb054e..6166db275c 100644
--- a/xbmc/video/VideoDatabase.cpp
+++ b/xbmc/video/VideoDatabase.cpp
@@ -3481,12 +3481,14 @@ void CVideoDatabase::DeleteMovie(int idMovie, bool bKeepId /* = false */)
BeginTransaction();
+ int idFile = GetDbId(PrepareSQL("SELECT idFile FROM movie WHERE idMovie=%i", idMovie));
+ DeleteStreamDetails(idFile);
+
// keep the movie table entry, linking to tv shows, and bookmarks
// so we can update the data in place
// the ancillary tables are still purged
if (!bKeepId)
{
- int idFile = GetDbId(PrepareSQL("SELECT idFile FROM movie WHERE idMovie=%i", idMovie));
std::string path = GetSingleValue(PrepareSQL("SELECT strPath FROM path JOIN files ON files.idPath=path.idPath WHERE files.idFile=%i", idFile));
if (!path.empty())
InvalidatePathHash(path);
@@ -3533,7 +3535,15 @@ void CVideoDatabase::DeleteTvShow(int idTvShow, bool bKeepId /* = false */)
std::set<int> paths;
GetPathsForTvShow(idTvShow, paths);
- std::string strSQL=PrepareSQL("SELECT episode.idEpisode FROM episode WHERE episode.idShow=%i",idTvShow);
+ std::string strSQL=PrepareSQL("SELECT episode.idFile FROM episode WHERE episode.idShow=%i",idTvShow);
+ m_pDS2->query(strSQL);
+ while (!m_pDS2->eof())
+ {
+ DeleteStreamDetails(m_pDS2->fv(0).get_asInt());
+ m_pDS2->next();
+ }
+
+ strSQL=PrepareSQL("SELECT episode.idEpisode FROM episode WHERE episode.idShow=%i",idTvShow);
m_pDS2->query(strSQL);
while (!m_pDS2->eof())
{
@@ -3630,11 +3640,13 @@ void CVideoDatabase::DeleteEpisode(int idEpisode, bool bKeepId /* = false */)
if (!bKeepId)
AnnounceRemove(MediaTypeEpisode, idEpisode);
+ int idFile = GetDbId(PrepareSQL("SELECT idFile FROM episode WHERE idEpisode=%i", idEpisode));
+ DeleteStreamDetails(idFile);
+
// keep episode table entry and bookmarks so we can update the data in place
// the ancillary tables are still purged
if (!bKeepId)
{
- int idFile = GetDbId(PrepareSQL("SELECT idFile FROM episode WHERE idEpisode=%i", idEpisode));
std::string path = GetSingleValue(PrepareSQL("SELECT strPath FROM path JOIN files ON files.idPath=path.idPath WHERE files.idFile=%i", idFile));
if (!path.empty())
InvalidatePathHash(path);
@@ -3671,11 +3683,13 @@ void CVideoDatabase::DeleteMusicVideo(int idMVideo, bool bKeepId /* = false */)
BeginTransaction();
+ int idFile = GetDbId(PrepareSQL("SELECT idFile FROM musicvideo WHERE idMVideo=%i", idMVideo));
+ DeleteStreamDetails(idFile);
+
// keep the music video table entry and bookmarks so we can update data in place
// the ancillary tables are still purged
if (!bKeepId)
{
- int idFile = GetDbId(PrepareSQL("SELECT idFile FROM musicvideo WHERE idMVideo=%i", idMVideo));
std::string path = GetSingleValue(PrepareSQL("SELECT strPath FROM path JOIN files ON files.idPath=path.idPath WHERE files.idFile=%i", idFile));
if (!path.empty())
InvalidatePathHash(path);
diff --git a/xbmc/video/dialogs/GUIDialogAudioSettings.cpp b/xbmc/video/dialogs/GUIDialogAudioSettings.cpp
index 1e36c6de35..27204454cc 100644
--- a/xbmc/video/dialogs/GUIDialogAudioSettings.cpp
+++ b/xbmc/video/dialogs/GUIDialogAudioSettings.cpp
@@ -146,22 +146,22 @@ void CGUIDialogAudioSettings::OnSettingAction(const std::shared_ptr<const CSetti
Save();
}
-void CGUIDialogAudioSettings::Save()
+bool CGUIDialogAudioSettings::Save()
{
const std::shared_ptr<CProfileManager> profileManager = CServiceBroker::GetSettingsComponent()->GetProfileManager();
if (!g_passwordManager.CheckSettingLevelLock(SettingLevel::Expert) &&
profileManager->GetMasterProfile().getLockMode() != LOCK_MODE_EVERYONE)
- return;
+ return true;
// prompt user if they are sure
if (!CGUIDialogYesNo::ShowAndGetInput(CVariant{12376}, CVariant{12377}))
- return;
+ return true;
// reset the settings
CVideoDatabase db;
if (!db.Open())
- return;
+ return true;
db.EraseAllVideoSettings();
db.Close();
@@ -169,6 +169,8 @@ void CGUIDialogAudioSettings::Save()
CMediaSettings::GetInstance().GetDefaultVideoSettings() = g_application.GetAppPlayer().GetVideoSettings();
CMediaSettings::GetInstance().GetDefaultVideoSettings().m_AudioStream = -1;
CServiceBroker::GetSettingsComponent()->GetSettings()->Save();
+
+ return true;
}
void CGUIDialogAudioSettings::SetupView()
diff --git a/xbmc/video/dialogs/GUIDialogAudioSettings.h b/xbmc/video/dialogs/GUIDialogAudioSettings.h
index 3a66d8e7e4..de69b77ae7 100644
--- a/xbmc/video/dialogs/GUIDialogAudioSettings.h
+++ b/xbmc/video/dialogs/GUIDialogAudioSettings.h
@@ -38,7 +38,7 @@ protected:
// specialization of CGUIDialogSettingsBase
bool AllowResettingSettings() const override { return false; }
- void Save() override;
+ bool Save() override;
void SetupView() override;
// specialization of CGUIDialogSettingsManualBase
diff --git a/xbmc/video/dialogs/GUIDialogCMSSettings.cpp b/xbmc/video/dialogs/GUIDialogCMSSettings.cpp
index e2e298d80c..d7bedaa419 100644
--- a/xbmc/video/dialogs/GUIDialogCMSSettings.cpp
+++ b/xbmc/video/dialogs/GUIDialogCMSSettings.cpp
@@ -203,10 +203,12 @@ bool CGUIDialogCMSSettings::OnBack(int actionID)
return CGUIDialogSettingsBase::OnBack(actionID);
}
-void CGUIDialogCMSSettings::Save()
+bool CGUIDialogCMSSettings::Save()
{
CLog::Log(LOGINFO, "CGUIDialogCMSSettings: Save() called");
CServiceBroker::GetSettingsComponent()->GetSettings()->Save();
+
+ return true;
}
void CGUIDialogCMSSettings::Cms3dLutsFiller(const SettingConstPtr& setting,
diff --git a/xbmc/video/dialogs/GUIDialogCMSSettings.h b/xbmc/video/dialogs/GUIDialogCMSSettings.h
index 67614f54de..e718b29940 100644
--- a/xbmc/video/dialogs/GUIDialogCMSSettings.h
+++ b/xbmc/video/dialogs/GUIDialogCMSSettings.h
@@ -25,7 +25,7 @@ protected:
// specialization of CGUIDialogSettingsBase
bool AllowResettingSettings() const override { return false; }
bool OnBack(int actionID) override;
- void Save() override;
+ bool Save() override;
void SetupView() override;
// specialization of CGUIDialogSettingsManualBase
diff --git a/xbmc/video/dialogs/GUIDialogSubtitleSettings.cpp b/xbmc/video/dialogs/GUIDialogSubtitleSettings.cpp
index ab5a27b39e..90cd042aae 100644
--- a/xbmc/video/dialogs/GUIDialogSubtitleSettings.cpp
+++ b/xbmc/video/dialogs/GUIDialogSubtitleSettings.cpp
@@ -184,22 +184,22 @@ void CGUIDialogSubtitleSettings::OnSettingAction(const std::shared_ptr<const CSe
Save();
}
-void CGUIDialogSubtitleSettings::Save()
+bool CGUIDialogSubtitleSettings::Save()
{
const std::shared_ptr<CProfileManager> profileManager = CServiceBroker::GetSettingsComponent()->GetProfileManager();
if (!g_passwordManager.CheckSettingLevelLock(SettingLevel::Expert) &&
profileManager->GetMasterProfile().getLockMode() != LOCK_MODE_EVERYONE)
- return;
+ return true;
// prompt user if they are sure
if (!CGUIDialogYesNo::ShowAndGetInput(CVariant{12376}, CVariant{12377}))
- return;
+ return true;
// reset the settings
CVideoDatabase db;
if (!db.Open())
- return;
+ return true;
db.EraseAllVideoSettings();
db.Close();
@@ -207,6 +207,8 @@ void CGUIDialogSubtitleSettings::Save()
CMediaSettings::GetInstance().GetDefaultVideoSettings() = g_application.GetAppPlayer().GetVideoSettings();
CMediaSettings::GetInstance().GetDefaultVideoSettings().m_SubtitleStream = -1;
CServiceBroker::GetSettingsComponent()->GetSettings()->Save();
+
+ return true;
}
void CGUIDialogSubtitleSettings::SetupView()
diff --git a/xbmc/video/dialogs/GUIDialogSubtitleSettings.h b/xbmc/video/dialogs/GUIDialogSubtitleSettings.h
index 1c14938368..65216ede38 100644
--- a/xbmc/video/dialogs/GUIDialogSubtitleSettings.h
+++ b/xbmc/video/dialogs/GUIDialogSubtitleSettings.h
@@ -37,7 +37,7 @@ protected:
// specialization of CGUIDialogSettingsBase
bool AllowResettingSettings() const override { return false; }
- void Save() override;
+ bool Save() override;
void SetupView() override;
// specialization of CGUIDialogSettingsManualBase
diff --git a/xbmc/video/dialogs/GUIDialogVideoSettings.cpp b/xbmc/video/dialogs/GUIDialogVideoSettings.cpp
index 2a47300c56..1bb46e3180 100644
--- a/xbmc/video/dialogs/GUIDialogVideoSettings.cpp
+++ b/xbmc/video/dialogs/GUIDialogVideoSettings.cpp
@@ -241,20 +241,20 @@ void CGUIDialogVideoSettings::OnSettingAction(const std::shared_ptr<const CSetti
Save();
}
-void CGUIDialogVideoSettings::Save()
+bool CGUIDialogVideoSettings::Save()
{
const std::shared_ptr<CProfileManager> profileManager = CServiceBroker::GetSettingsComponent()->GetProfileManager();
if (profileManager->GetMasterProfile().getLockMode() != LOCK_MODE_EVERYONE &&
!g_passwordManager.CheckSettingLevelLock(::SettingLevel::Expert))
- return;
+ return true;
// prompt user if they are sure
if (CGUIDialogYesNo::ShowAndGetInput(CVariant(12376), CVariant(12377)))
{ // reset the settings
CVideoDatabase db;
if (!db.Open())
- return;
+ return true;
db.EraseAllVideoSettings();
db.Close();
@@ -263,6 +263,8 @@ void CGUIDialogVideoSettings::Save()
CMediaSettings::GetInstance().GetDefaultVideoSettings().m_AudioStream = -1;
CServiceBroker::GetSettingsComponent()->GetSettings()->Save();
}
+
+ return true;
}
void CGUIDialogVideoSettings::SetupView()
diff --git a/xbmc/video/dialogs/GUIDialogVideoSettings.h b/xbmc/video/dialogs/GUIDialogVideoSettings.h
index dd1e1f5fa2..5314e4049e 100644
--- a/xbmc/video/dialogs/GUIDialogVideoSettings.h
+++ b/xbmc/video/dialogs/GUIDialogVideoSettings.h
@@ -43,7 +43,7 @@ protected:
// specialization of CGUIDialogSettingsBase
bool AllowResettingSettings() const override { return false; }
- void Save() override;
+ bool Save() override;
void SetupView() override;
// specialization of CGUIDialogSettingsManualBase
diff --git a/xbmc/video/windows/GUIWindowVideoBase.cpp b/xbmc/video/windows/GUIWindowVideoBase.cpp
index e10db027fd..7330a5496e 100644
--- a/xbmc/video/windows/GUIWindowVideoBase.cpp
+++ b/xbmc/video/windows/GUIWindowVideoBase.cpp
@@ -398,22 +398,6 @@ bool CGUIWindowVideoBase::ShowIMDB(CFileItemPtr item, const ScraperPtr &info2, b
item->SetPath(item->GetVideoInfoTag()->GetPath());
}
}
-
- if (needsRefresh)
- {
- // Delete stream details (=media flags). This allows users to force
- // a refresh of the stream details by performing a video info refresh
- const int fileId = item->GetVideoInfoTag()->m_iFileId;
- if (fileId > 0)
- {
- CVideoDatabase db;
- if (db.Open())
- {
- db.DeleteStreamDetails(fileId);
- db.Close();
- }
- }
- }
const std::shared_ptr<CProfileManager> profileManager = CServiceBroker::GetSettingsComponent()->GetProfileManager();
diff --git a/xbmc/windowing/win10/WinSystemWin10DX.cpp b/xbmc/windowing/win10/WinSystemWin10DX.cpp
index 3d5d50ee99..e7dee222f4 100644
--- a/xbmc/windowing/win10/WinSystemWin10DX.cpp
+++ b/xbmc/windowing/win10/WinSystemWin10DX.cpp
@@ -182,6 +182,11 @@ bool CWinSystemWin10DX::IsHDROutput() const
return m_deviceResources->IsHDROutput();
}
+bool CWinSystemWin10DX::IsTransferPQ() const
+{
+ return m_deviceResources->IsTransferPQ();
+}
+
void CWinSystemWin10DX::SetHdrMetaData(DXGI_HDR_METADATA_HDR10& hdr10) const
{
m_deviceResources->SetHdrMetaData(hdr10);
diff --git a/xbmc/windowing/win10/WinSystemWin10DX.h b/xbmc/windowing/win10/WinSystemWin10DX.h
index e9ba46c735..0701cc0638 100644
--- a/xbmc/windowing/win10/WinSystemWin10DX.h
+++ b/xbmc/windowing/win10/WinSystemWin10DX.h
@@ -73,6 +73,7 @@ public:
// HDR support
bool IsHDROutput() const;
+ bool IsTransferPQ() const;
void SetHdrMetaData(DXGI_HDR_METADATA_HDR10& hdr10) const;
void SetHdrColorSpace(const DXGI_COLOR_SPACE_TYPE colorSpace) const;
diff --git a/xbmc/windowing/windows/WinSystemWin32DX.cpp b/xbmc/windowing/windows/WinSystemWin32DX.cpp
index 305e4068b2..0732b474c4 100644
--- a/xbmc/windowing/windows/WinSystemWin32DX.cpp
+++ b/xbmc/windowing/windows/WinSystemWin32DX.cpp
@@ -407,6 +407,11 @@ bool CWinSystemWin32DX::IsHDROutput() const
return m_deviceResources->IsHDROutput();
}
+bool CWinSystemWin32DX::IsTransferPQ() const
+{
+ return m_deviceResources->IsTransferPQ();
+}
+
void CWinSystemWin32DX::SetHdrMetaData(DXGI_HDR_METADATA_HDR10& hdr10) const
{
m_deviceResources->SetHdrMetaData(hdr10);
diff --git a/xbmc/windowing/windows/WinSystemWin32DX.h b/xbmc/windowing/windows/WinSystemWin32DX.h
index a33891e624..ff05cb30dd 100644
--- a/xbmc/windowing/windows/WinSystemWin32DX.h
+++ b/xbmc/windowing/windows/WinSystemWin32DX.h
@@ -75,6 +75,7 @@ public:
// HDR support
bool IsHDROutput() const;
+ bool IsTransferPQ() const;
void SetHdrMetaData(DXGI_HDR_METADATA_HDR10& hdr10) const;
void SetHdrColorSpace(const DXGI_COLOR_SPACE_TYPE colorSpace) const;