diff --git a/data/setup.xml b/data/setup.xml
index 875c035b940..3e5029b448c 100644
--- a/data/setup.xml
+++ b/data/setup.xml
@@ -75,14 +75,15 @@
- config.cimisc.bootDelay
- - config.channelSelection.style
- config.misc.use_ci_assignment
- config.usage.alternative_number_mode
- config.usage.show_bouquetalways
- config.usage.quickzap_bouquet_change
- config.usage.servicelistpreview_mode
- - config.usage.use_pig
- - config.usage.servicelist_mode
+
+ - config.usage.use_pig
+ - config.usage.servicelist_mode
+
- config.usage.show_servicelist
- config.usage.servicelist_cursor_behavior
- config.usage.multibouquet
@@ -92,25 +93,34 @@
- config.usage.panicchannel
- config.usage.numzappicon
- config.usage.show_channel_jump_in_servicelist
- - config.usage.service_icon_enable
- - config.usage.servicelist_picon_ratio
- - config.usage.servicelist_picon_downsize
- - config.usage.servicetype_icon_mode
- - config.usage.crypto_icon_mode
- - config.usage.record_indicator_mode
- - config.usage.servicelist_twolines
- - config.usage.servicelist_servicenumber_valign
- - config.usage.servicelist_eventprogress_valign
- - config.usage.show_channel_numbers_in_servicelist
- - config.usage.servicelist_eventprogress_view_mode
- - config.usage.show_event_progress_in_servicelist
- - config.usage.servicelist_column
- - config.usage.serviceitems_per_page_twolines
- - config.usage.serviceitems_per_page
- - config.usage.servicenum_fontsize
- - config.usage.servicename_fontsize
- - config.usage.serviceinfo_fontsize
- - config.usage.progressinfo_fontsize
+
+ - config.usage.show_channel_numbers_in_servicelist
+ - config.usage.service_icon_enable
+ - config.usage.servicelist_picon_ratio
+ - config.usage.servicelist_picon_downsize
+ - config.usage.servicetype_icon_mode
+ - config.usage.crypto_icon_mode
+ - config.usage.record_indicator_mode
+ - config.usage.servicelist_twolines
+ - config.usage.servicelist_servicenumber_valign
+ - config.usage.servicelist_eventprogress_valign
+ - config.usage.servicelist_eventprogress_view_mode
+ - config.usage.show_event_progress_in_servicelist
+ - config.usage.servicelist_column
+ - config.usage.serviceitems_per_page_twolines
+ - config.usage.serviceitems_per_page
+ - config.usage.servicenum_fontsize
+ - config.usage.servicename_fontsize
+ - config.usage.serviceinfo_fontsize
+ - config.usage.progressinfo_fontsize
+
+ - config.channelSelection.showNumber
+ - config.channelSelection.showLCN
+ - config.channelSelection.showPicon
+ - config.channelSelection.showServiceTypeIcon
+ - config.channelSelection.showCryptoIcon
+ - config.channelSelection.recordIndicatorMode
+
- config.misc.zapmode
- config.usage.numzaptimeoutmode
- config.usage.numzaptimeout1
@@ -823,6 +833,8 @@
- config.skin.guiSkin
- config.skin.lcdSkin
- config.skin.FallbackFont
+ - config.channelSelection.screenStyle
+ - config.channelSelection.widgetStyle
- config.usage.sleepTimer
diff --git a/lib/gdi/drawing.cpp b/lib/gdi/drawing.cpp
index da3fd1eb5be..0502fce506d 100644
--- a/lib/gdi/drawing.cpp
+++ b/lib/gdi/drawing.cpp
@@ -1,7 +1,7 @@
/*
Creative Commons Attribution-NonCommercial-ShareAlike 4.0 International License
-Copyright (c) 2023-2024 openATV
+Copyright (c) 2023-2024 zKhadiri, jbleyel, openATV
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
diff --git a/lib/gdi/drawing.h b/lib/gdi/drawing.h
index 01b5d482012..0cf5b732c4b 100644
--- a/lib/gdi/drawing.h
+++ b/lib/gdi/drawing.h
@@ -1,7 +1,7 @@
/*
Creative Commons Attribution-NonCommercial-ShareAlike 4.0 International License
-Copyright (c) 2023-2024 openATV
+Copyright (c) 2023-2024 zKhadiri, jbleyel, openATV
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
diff --git a/lib/gui/elistboxcontent.cpp b/lib/gui/elistboxcontent.cpp
index 821e238db71..32194ff9658 100644
--- a/lib/gui/elistboxcontent.cpp
+++ b/lib/gui/elistboxcontent.cpp
@@ -1782,14 +1782,14 @@ void eListboxPythonMultiContent::paint(gPainter &painter, eWindowStyle &style, c
pheight = PyTuple_GET_ITEM(item, 4),
pfilled_perc = PyTuple_GET_ITEM(item, 5),
ppixmap, pborderWidth, pforeColor, pforeColorSelected, pbackColor, pbackColorSelected,
- pstartColor, pmidColor, pendColor, pstartColorSelected, pmidColorSelected, pendColorSelected;
+ pstartColor, pmidColor, pendColor, pstartColorSelected, pmidColorSelected, pendColorSelected, pborderColor, pborderColorSelected;
int idx = 6;
if (type == TYPE_PROGRESS)
{
if (!(px && py && pwidth && pheight && pfilled_perc))
{
- eDebug("[eListboxPythonMultiContent] tuple too small (must be (TYPE_PROGRESS, x, y, width, height, filled percent [, borderWidth, color, colorSelected, backColor, backColorSelected]))");
+ eDebug("[eListboxPythonMultiContent] tuple too small (must be (TYPE_PROGRESS, x, y, width, height, filled percent [, borderWidth, color, colorSelected, backColor, backColorSelected, borderColor, borderColorSelected]))");
goto error_out;
}
}
@@ -1800,7 +1800,7 @@ void eListboxPythonMultiContent::paint(gPainter &painter, eWindowStyle &style, c
continue;
if (!(px && py && pwidth && pheight && pfilled_perc, ppixmap))
{
- eDebug("[eListboxPythonMultiContent] tuple too small (must be (TYPE_PROGRESS_PIXMAP, x, y, width, height, filled percent, pixmap, [,borderWidth, color, colorSelected, backColor, backColorSelected]))");
+ eDebug("[eListboxPythonMultiContent] tuple too small (must be (TYPE_PROGRESS_PIXMAP, x, y, width, height, filled percent, pixmap, [,borderWidth, color, colorSelected, backColor, backColorSelected, borderColor, borderColorSelected]))");
goto error_out;
}
}
@@ -1836,6 +1836,12 @@ void eListboxPythonMultiContent::paint(gPainter &painter, eWindowStyle &style, c
pbackColorSelected = ePyObject();
}
+ if (size > idx)
+ pborderColor = lookupColor(PyTuple_GET_ITEM(item, idx++), data);
+
+ if (size > idx)
+ pborderColorSelected = lookupColor(PyTuple_GET_ITEM(item, idx++), data);
+
int radius = 0;
int edges = 0;
@@ -1966,6 +1972,11 @@ void eListboxPythonMultiContent::paint(gPainter &painter, eWindowStyle &style, c
}
else
{
+ if (pborderColor) {
+ uint32_t color = PyLong_AsUnsignedLongMask((selected && pborderColorSelected) ? pborderColorSelected : pborderColor);
+ painter.setForegroundColor(gRGB(color));
+ }
+
rect.setRect(x, y, width, bwidth);
painter.fill(rect);
@@ -1977,6 +1988,23 @@ void eListboxPythonMultiContent::paint(gPainter &painter, eWindowStyle &style, c
rect.setRect(x + width - bwidth, y + bwidth, bwidth, height - bwidth);
painter.fill(rect);
+
+ if (pborderColor) {
+ if (selected && pforeColorSelected)
+ {
+ uint32_t color = PyLong_AsUnsignedLongMask(pforeColorSelected);
+ painter.setForegroundColor(gRGB(color));
+ }
+ else if (pforeColor)
+ {
+ uint32_t color = PyLong_AsUnsignedLongMask(pforeColor);
+ painter.setForegroundColor(gRGB(color));
+ }
+ else
+ {
+ painter.setForegroundColor(defaultForeColor);
+ }
+ }
}
}
diff --git a/lib/python/Components/Converter/XmlMultiContent.py b/lib/python/Components/Converter/XmlMultiContent.py
index 9f3fa4ed576..634c5eeb049 100644
--- a/lib/python/Components/Converter/XmlMultiContent.py
+++ b/lib/python/Components/Converter/XmlMultiContent.py
@@ -35,7 +35,7 @@ def parseTemplateModes(template):
context = SkinContext(context, "0,0", f"{itemWidth},{itemHeight}")
for element in list(mode):
processor = self.processors.get(element.tag, self.processNone)
- newItems = processor(element, context, excludeItemValues=[], includeItemValues=[])
+ newItems = processor(element, context)
if newItems:
items += newItems
newItems = []
@@ -129,8 +129,7 @@ class XmlMultiContent(StringList, MultiContentTemplateParser):
def __init__(self, args):
StringList.__init__(self, args)
- self.debug = True
- MultiContentTemplateParser.__init__(self, self.debug)
+ MultiContentTemplateParser.__init__(self)
self.activeStyle = None
self.activeTemplate = "Default" # This value string is used in the UI.
self.dom = args.get("dom")
diff --git a/lib/python/Components/MultiContent.py b/lib/python/Components/MultiContent.py
index 244822ba4d1..80abc7f428d 100644
--- a/lib/python/Components/MultiContent.py
+++ b/lib/python/Components/MultiContent.py
@@ -49,12 +49,12 @@ def MultiContentEntryPixmapAlphaBlend(pos=(0, 0), size=(0, 0), png=None, backcol
return eListboxPythonMultiContent.TYPE_PIXMAP_ALPHABLEND, int(pos[0]), int(pos[1]), int(size[0]), int(size[1]), __resolvePixmap(png), __resolveColor(backcolor), __resolveColor(backcolor_sel), flags, cornerRadius, cornerEdges
-def MultiContentEntryProgress(pos=(0, 0), size=(0, 0), percent=None, borderWidth=None, foreColor=None, foreColorSelected=None, backColor=None, backColorSelected=None, startColor=None, midColor=None, endColor=None, startColorSelected=None, midColorSelected=None, endColorSelected=None, cornerRadius=0, cornerEdges=15):
- return eListboxPythonMultiContent.TYPE_PROGRESS, int(pos[0]), int(pos[1]), int(size[0]), int(size[1]), percent, borderWidth, __resolveColor(foreColor), __resolveColor(foreColorSelected), __resolveColor(backColor), __resolveColor(backColorSelected), __resolveColor(startColor), __resolveColor(midColor), __resolveColor(endColor), __resolveColor(startColorSelected), __resolveColor(midColorSelected), __resolveColor(endColorSelected), cornerRadius, cornerEdges
+def MultiContentEntryProgress(pos=(0, 0), size=(0, 0), percent=None, borderWidth=None, borderColor=None, borderColorSelected=None, foreColor=None, foreColorSelected=None, backColor=None, backColorSelected=None, startColor=None, midColor=None, endColor=None, startColorSelected=None, midColorSelected=None, endColorSelected=None, cornerRadius=0, cornerEdges=15):
+ return eListboxPythonMultiContent.TYPE_PROGRESS, int(pos[0]), int(pos[1]), int(size[0]), int(size[1]), percent, borderWidth, __resolveColor(foreColor), __resolveColor(foreColorSelected), __resolveColor(backColor), __resolveColor(backColorSelected), __resolveColor(borderColor), __resolveColor(borderColorSelected), __resolveColor(startColor), __resolveColor(midColor), __resolveColor(endColor), __resolveColor(startColorSelected), __resolveColor(midColorSelected), __resolveColor(endColorSelected), cornerRadius, cornerEdges
-def MultiContentEntryProgressPixmap(pos=(0, 0), size=(0, 0), percent=None, pixmap=None, borderWidth=None, foreColor=None, foreColorSelected=None, backColor=None, backColorSelected=None, cornerRadius=0, cornerEdges=15):
- return eListboxPythonMultiContent.TYPE_PROGRESS_PIXMAP, int(pos[0]), int(pos[1]), int(size[0]), int(size[1]), percent, __resolvePixmap(pixmap), borderWidth, __resolveColor(foreColor), __resolveColor(foreColorSelected), __resolveColor(backColor), __resolveColor(backColorSelected), cornerRadius, cornerEdges
+def MultiContentEntryProgressPixmap(pos=(0, 0), size=(0, 0), percent=None, pixmap=None, borderWidth=None, borderColor=None, borderColorSelected=None, foreColor=None, foreColorSelected=None, backColor=None, backColorSelected=None, cornerRadius=0, cornerEdges=15):
+ return eListboxPythonMultiContent.TYPE_PROGRESS_PIXMAP, int(pos[0]), int(pos[1]), int(size[0]), int(size[1]), percent, __resolvePixmap(pixmap), borderWidth, __resolveColor(foreColor), __resolveColor(foreColorSelected), __resolveColor(backColor), __resolveColor(backColorSelected), __resolveColor(borderColor), __resolveColor(borderColorSelected), cornerRadius, cornerEdges
def MultiContentEntryLinearGradient(pos=(0, 0), size=(0, 0), direction=GRADIENT_VERTICAL, startColor=None, midColor=None, endColor=None, startColorSelected=None, midColorSelected=None, endColorSelected=None, cornerRadius=0, cornerEdges=15):
diff --git a/lib/python/Components/ServiceList.py b/lib/python/Components/ServiceList.py
index 7bc6a42accf..11beb29feb0 100644
--- a/lib/python/Components/ServiceList.py
+++ b/lib/python/Components/ServiceList.py
@@ -1,6 +1,6 @@
from enigma import eListboxServiceContent, eListbox, eServiceCenter, eServiceReference, gFont, eRect, eSize
-from Components.config import config, ConfigSelection, ConfigSubsection
+from Components.config import config, ConfigYesNo, ConfigSelection, ConfigSubsection
from Components.GUIComponent import GUIComponent
from Components.Renderer.Picon import getPiconName
from skin import parseColor, parseFont
@@ -11,8 +11,19 @@
def InitServiceListSettings():
config.channelSelection = ConfigSubsection()
+ config.channelSelection.showNumber = ConfigYesNo(default=True)
+ config.channelSelection.showLCN = ConfigYesNo(default=False)
+ config.channelSelection.showPicon = ConfigYesNo(default=False)
+ config.channelSelection.showServiceTypeIcon = ConfigYesNo(default=False)
+ config.channelSelection.showCryptoIcon = ConfigYesNo(default=False)
+ config.channelSelection.recordIndicatorMode = ConfigSelection(default=2, choices=[
+ (0, _("None")),
+ (1, _("Record Icon")),
+ (2, _("Colored Text"))
+ ])
choiceList = [("", _("Legacy mode"))]
- config.channelSelection.style = ConfigSelection(default="", choices=choiceList)
+ config.channelSelection.screenStyle = ConfigSelection(default="", choices=choiceList)
+ config.channelSelection.widgetStyle = ConfigSelection(default="", choices=choiceList)
def refreshServiceList(configElement=None):
diff --git a/lib/python/Plugins/Extensions/AtileHD/plugin.py b/lib/python/Plugins/Extensions/AtileHD/plugin.py
index 6615e69f43b..71d56b1a017 100644
--- a/lib/python/Plugins/Extensions/AtileHD/plugin.py
+++ b/lib/python/Plugins/Extensions/AtileHD/plugin.py
@@ -115,7 +115,7 @@ def keyCancel(self):
self.close(None)
-class AtileHD_Config(Screen, ConfigListScreen):
+class AtileHD_Config(ConfigListScreen, Screen):
skin = """
diff --git a/lib/python/Plugins/Extensions/DVDBurn/ProjectSettings.py b/lib/python/Plugins/Extensions/DVDBurn/ProjectSettings.py
index 643c5b4bb5e..89f2c3903ad 100644
--- a/lib/python/Plugins/Extensions/DVDBurn/ProjectSettings.py
+++ b/lib/python/Plugins/Extensions/DVDBurn/ProjectSettings.py
@@ -81,7 +81,7 @@ def exit(self):
self.close(None, False, None)
-class ProjectSettings(Screen, ConfigListScreen):
+class ProjectSettings(ConfigListScreen, Screen):
skin = """
diff --git a/lib/python/Plugins/Extensions/DVDBurn/TitleProperties.py b/lib/python/Plugins/Extensions/DVDBurn/TitleProperties.py
index aa37add3719..951a6ce161d 100644
--- a/lib/python/Plugins/Extensions/DVDBurn/TitleProperties.py
+++ b/lib/python/Plugins/Extensions/DVDBurn/TitleProperties.py
@@ -8,7 +8,7 @@
from . import Title
-class TitleProperties(Screen, ConfigListScreen):
+class TitleProperties(ConfigListScreen, Screen):
skin = """
diff --git a/lib/python/Plugins/Extensions/MediaPlayer/plugin.py b/lib/python/Plugins/Extensions/MediaPlayer/plugin.py
index b8935295f45..f87d2b961e4 100644
--- a/lib/python/Plugins/Extensions/MediaPlayer/plugin.py
+++ b/lib/python/Plugins/Extensions/MediaPlayer/plugin.py
@@ -133,7 +133,7 @@ def __init__(self, session, args=None):
defaultDir = ""
if defaultDir == "":
defaultDir = None
- self.filelist = FileList(defaultDir, matchingPattern=r"(?i)^.*\.(mp2|mp3|ogg|ts|trp|mts|m2ts|wav|wave|m3u|pls|e2pls|mpg|vob|avi|divx|m4v|mkv|mp4|m4a|dat|flac|flv|mov|dts|3gp|3g2|asf|wmv|wma|webm)", useServiceRef=True, additionalExtensions="4098:m3u 4098:e2pls 4098:pls")
+ self.filelist = FileList(defaultDir, matchingPattern=r"(?i)^.*\.(mp2|mp3|ogg|stream|ts|trp|mts|m2ts|wav|wave|m3u|pls|e2pls|mpg|vob|avi|divx|m4v|mkv|mp4|m4a|dat|flac|flv|mov|dts|3gp|3g2|asf|wmv|wma|webm)", useServiceRef=True, additionalExtensions="4098:m3u 4098:e2pls 4098:pls")
self["filelist"] = self.filelist
self.playlist = MyPlayList()
diff --git a/lib/python/Plugins/SystemPlugins/DiseqcTester/plugin.py b/lib/python/Plugins/SystemPlugins/DiseqcTester/plugin.py
index 33c92826b6d..b951dcb7eef 100644
--- a/lib/python/Plugins/SystemPlugins/DiseqcTester/plugin.py
+++ b/lib/python/Plugins/SystemPlugins/DiseqcTester/plugin.py
@@ -571,7 +571,7 @@ def selectionChanged(self):
self["CmdText"].setText(_("Press OK to get further details for %s") % str(self["progress_list"].getCurrent()[1]))
-class DiseqcTesterTestTypeSelection(Screen, ConfigListScreen):
+class DiseqcTesterTestTypeSelection(ConfigListScreen, Screen):
def __init__(self, session, feid):
Screen.__init__(self, session)
diff --git a/lib/python/Plugins/SystemPlugins/SatelliteEquipmentControl/plugin.py b/lib/python/Plugins/SystemPlugins/SatelliteEquipmentControl/plugin.py
index 63c70d1940d..78019548e79 100644
--- a/lib/python/Plugins/SystemPlugins/SatelliteEquipmentControl/plugin.py
+++ b/lib/python/Plugins/SystemPlugins/SatelliteEquipmentControl/plugin.py
@@ -8,7 +8,7 @@
from Components.NimManager import nimmanager as nimmgr
-class SecParameterSetup(Screen, ConfigListScreen):
+class SecParameterSetup(ConfigListScreen, Screen):
skin = """
diff --git a/lib/python/Plugins/SystemPlugins/SoftwareManager/BackupRestore.py b/lib/python/Plugins/SystemPlugins/SoftwareManager/BackupRestore.py
index fcf4346afd0..ed0fc0cf145 100755
--- a/lib/python/Plugins/SystemPlugins/SoftwareManager/BackupRestore.py
+++ b/lib/python/Plugins/SystemPlugins/SoftwareManager/BackupRestore.py
@@ -111,7 +111,7 @@ def SettingsEntry(name, checked):
return (name, picture, checked)
-class BackupScreen(Screen, ConfigListScreen):
+class BackupScreen(ConfigListScreen, Screen):
skin = """
@@ -429,7 +429,7 @@ def checkSummary(self):
self["summary_description"].text = cur
-class RestoreScreen(Screen, ConfigListScreen):
+class RestoreScreen(ConfigListScreen, Screen):
skin = """
diff --git a/lib/python/Plugins/SystemPlugins/VideoClippingSetup/plugin.py b/lib/python/Plugins/SystemPlugins/VideoClippingSetup/plugin.py
index 77d0102f455..fb706019428 100644
--- a/lib/python/Plugins/SystemPlugins/VideoClippingSetup/plugin.py
+++ b/lib/python/Plugins/SystemPlugins/VideoClippingSetup/plugin.py
@@ -9,7 +9,7 @@
config.plugins.VideoClippingSetup.clip_height = ConfigInteger(default=576)
-class VideoClippingCoordinates(Screen, ConfigListScreen):
+class VideoClippingCoordinates(ConfigListScreen, Screen):
skin = """
diff --git a/lib/python/Plugins/SystemPlugins/VideoEnhancement/plugin.py b/lib/python/Plugins/SystemPlugins/VideoEnhancement/plugin.py
index 1c1891279ea..8d0346e7f71 100644
--- a/lib/python/Plugins/SystemPlugins/VideoEnhancement/plugin.py
+++ b/lib/python/Plugins/SystemPlugins/VideoEnhancement/plugin.py
@@ -13,7 +13,7 @@
from . import VideoEnhancement
-class VideoEnhancementSetup(Screen, ConfigListScreen):
+class VideoEnhancementSetup(ConfigListScreen, Screen):
def __init__(self, session):
Screen.__init__(self, session)
self.onChangedEntry = []
@@ -280,7 +280,7 @@ def createSummary(self):
return SetupSummary
-class VideoEnhancementPreview(Screen, ConfigListScreen):
+class VideoEnhancementPreview(ConfigListScreen, Screen):
skin = """
diff --git a/lib/python/Plugins/SystemPlugins/VideoEnhancementAML/plugin.py b/lib/python/Plugins/SystemPlugins/VideoEnhancementAML/plugin.py
index cdaad3c46e3..7e39cecfcd5 100644
--- a/lib/python/Plugins/SystemPlugins/VideoEnhancementAML/plugin.py
+++ b/lib/python/Plugins/SystemPlugins/VideoEnhancementAML/plugin.py
@@ -11,7 +11,7 @@
from . import VideoEnhancement
-class VideoEnhancementSetup(Screen, ConfigListScreen):
+class VideoEnhancementSetup(ConfigListScreen, Screen):
def __init__(self, session):
Screen.__init__(self, session)
self.onChangedEntry = []
@@ -196,7 +196,7 @@ def createSummary(self):
return SetupSummary
-class VideoEnhancementPreview(Screen, ConfigListScreen):
+class VideoEnhancementPreview(ConfigListScreen, Screen):
skin = """
diff --git a/lib/python/Screens/AudioSelection.py b/lib/python/Screens/AudioSelection.py
index 2f0138ecb75..9415585e612 100644
--- a/lib/python/Screens/AudioSelection.py
+++ b/lib/python/Screens/AudioSelection.py
@@ -29,7 +29,7 @@ def getConfigMenuItem(configElementName):
return "", None
-class AudioSelection(Screen, ConfigListScreen):
+class AudioSelection(ConfigListScreen, Screen):
def __init__(self, session, infobar=None, page=PAGE_AUDIO):
Screen.__init__(self, session)
diff --git a/lib/python/Screens/AutoDiseqc.py b/lib/python/Screens/AutoDiseqc.py
index 690b537c2f3..fa9aa786452 100644
--- a/lib/python/Screens/AutoDiseqc.py
+++ b/lib/python/Screens/AutoDiseqc.py
@@ -8,7 +8,7 @@
from enigma import eDVBFrontendParametersSatellite, eDVBResourceManager, eTimer
-class AutoDiseqc(Screen, ConfigListScreen):
+class AutoDiseqc(ConfigListScreen, Screen):
diseqc_ports = [
"A", "B", "C", "D"
]
diff --git a/lib/python/Screens/ChannelSelection.py b/lib/python/Screens/ChannelSelection.py
index b395876ef6b..290bf757fd6 100644
--- a/lib/python/Screens/ChannelSelection.py
+++ b/lib/python/Screens/ChannelSelection.py
@@ -136,7 +136,7 @@ def digitHelp():
self["key_green"] = StaticText(_("Reception Lists"))
self["key_yellow"] = StaticText(_("Providers"))
self["key_blue"] = StaticText(_("Bouquets"))
- self["list"] = ServiceListLegacy(self) if config.channelSelection.style.value == "" else ServiceList(self)
+ self["list"] = ServiceListLegacy(self) if config.channelSelection.screenStyle.value == "" or config.channelSelection.widgetStyle.value == "" else ServiceList(self)
self.servicelist = self["list"]
self.numericalTextInput = NumericalTextInput(handleTimeout=False)
self.servicePath = []
@@ -2254,7 +2254,9 @@ class ChannelSelection(ChannelSelectionBase, ChannelSelectionEdit, ChannelSelect
def __init__(self, session):
ChannelSelectionBase.__init__(self, session)
- if config.usage.use_pig.value:
+ if config.channelSelection.screenStyle.value:
+ self.skinName = [config.channelSelection.screenStyle.value]
+ elif config.usage.use_pig.value:
self.skinName = ["ChannelSelection_PIG", "ChannelSelection"]
elif config.usage.servicelist_mode.value == "simple":
self.skinName = ["SlimChannelSelection", "SimpleChannelSelection", "ChannelSelection"]
diff --git a/lib/python/Screens/CronTimer.py b/lib/python/Screens/CronTimer.py
index cc83d406976..0a8634d08e6 100755
--- a/lib/python/Screens/CronTimer.py
+++ b/lib/python/Screens/CronTimer.py
@@ -287,7 +287,7 @@ def info(self):
config.crontimers.dayofmonth = NoSave(ConfigInteger(default=1, limits=(1, 31)))
-class CronTimersConfig(Screen, ConfigListScreen):
+class CronTimersConfig(ConfigListScreen, Screen):
def __init__(self, session):
Screen.__init__(self, session)
Screen.setTitle(self, _("Cron Manager"))
diff --git a/lib/python/Screens/EpgSelection.py b/lib/python/Screens/EpgSelection.py
index 1320bc87579..b2970c36374 100644
--- a/lib/python/Screens/EpgSelection.py
+++ b/lib/python/Screens/EpgSelection.py
@@ -764,6 +764,9 @@ def BouquetOK(self):
self["list"].instance.moveSelectionTo(0)
if self.type == EPG_TYPE_GRAPH or self.type == EPG_TYPE_INFOBARGRAPH:
self["list"].fillGraphEPG(None, self.ask_time, True)
+ serviceref = self.session.nav.getCurrentlyPlayingServiceOrGroup()
+ if serviceref:
+ self["list"].moveToService(serviceref)
self.setTitle(self["bouquetlist"].getCurrentBouquet())
self.BouquetlistHide(False)
diff --git a/lib/python/Screens/InstallWizard.py b/lib/python/Screens/InstallWizard.py
index 5b841bc9eba..a906d531375 100644
--- a/lib/python/Screens/InstallWizard.py
+++ b/lib/python/Screens/InstallWizard.py
@@ -16,7 +16,7 @@
config.misc.installwizard.channellistdownloaded = ConfigBoolean(default=False)
-class InstallWizard(Screen, ConfigListScreen):
+class InstallWizard(ConfigListScreen, Screen):
STATE_UPDATE = 0
STATE_CHANNELLIST = 1
STATE_SOFTCAM = 2
diff --git a/lib/python/Screens/MountManager.py b/lib/python/Screens/MountManager.py
index a5da678061f..74af987df34 100644
--- a/lib/python/Screens/MountManager.py
+++ b/lib/python/Screens/MountManager.py
@@ -293,7 +293,7 @@ def restBo(self, answer):
self.selectionChanged()
-class DevicePanelConf(Screen, ConfigListScreen):
+class DevicePanelConf(ConfigListScreen, Screen):
skin = """
diff --git a/lib/python/Screens/NetworkSetup.py b/lib/python/Screens/NetworkSetup.py
index ec116bcaafb..00f566f47cd 100644
--- a/lib/python/Screens/NetworkSetup.py
+++ b/lib/python/Screens/NetworkSetup.py
@@ -382,7 +382,7 @@ def __init__(self, session):
DNSSettings.__init__(self, session=session)
-class NetworkMacSetup(Screen, ConfigListScreen):
+class NetworkMacSetup(ConfigListScreen, Screen):
def __init__(self, session):
Screen.__init__(self, session, enableHelp=True)
self.setTitle(_("MAC Address Settings"))
@@ -440,7 +440,7 @@ def restartfinishedCB(self, data):
self.session.openWithCallback(self.close, MessageBox, _("Finished configuring your network"), type=MessageBox.TYPE_INFO, timeout=10, default=False)
-class AdapterSetup(Screen, ConfigListScreen):
+class AdapterSetup(ConfigListScreen, Screen):
def __init__(self, session, networkinfo, essid=None):
Screen.__init__(self, session, enableHelp=True)
self.setTitle(_("Adapter Settings"))
diff --git a/lib/python/Screens/TimeDateInput.py b/lib/python/Screens/TimeDateInput.py
index 23efcb443fd..b6107f81648 100644
--- a/lib/python/Screens/TimeDateInput.py
+++ b/lib/python/Screens/TimeDateInput.py
@@ -9,7 +9,7 @@
import datetime
-class TimeDateInput(Screen, ConfigListScreen):
+class TimeDateInput(ConfigListScreen, Screen):
def __init__(self, session, config_time=None, config_date=None):
Screen.__init__(self, session)
self.setTitle(_("Date/time input"))
diff --git a/lib/python/Screens/VideoMode.py b/lib/python/Screens/VideoMode.py
index a66f81ef5b3..2ad6ee8041b 100644
--- a/lib/python/Screens/VideoMode.py
+++ b/lib/python/Screens/VideoMode.py
@@ -58,7 +58,7 @@ def setProgressiveRate(vid_rate, new_rate, new_res, config_res, config_rate):
return new_rate
-class VideoSetup(Screen, ConfigListScreen):
+class VideoSetup(ConfigListScreen, Screen):
def __init__(self, session):
Screen.__init__(self, session)
# for the skin: first try VideoSetup, then Setup, this allows individual skinning
diff --git a/lib/python/Tools/MultiBoot.py b/lib/python/Tools/MultiBoot.py
index 501a77c850c..8c966ea300e 100644
--- a/lib/python/Tools/MultiBoot.py
+++ b/lib/python/Tools/MultiBoot.py
@@ -245,7 +245,7 @@ def saveKernel(bootSlots, slotCode, kernel):
if startupFile:
if isinstance(startupFile, dict):
if "" in startupFile:
- print(f"[MultiBoot] Startup file: '{startupFile['']}'.")
+ print(f"[MultiBoot] Startup file: '{startupFile[""]}'.")
else:
print("[MultiBoot] Startup files:")
for key in sorted(startupFile.keys()):
@@ -256,18 +256,18 @@ def saveKernel(bootSlots, slotCode, kernel):
if commandLine:
if isinstance(commandLine, dict):
if "" in startupFile:
- print(f"[MultiBoot] Command line: '{startupFile['']}'.")
+ print(f"[MultiBoot] Command line: '{startupFile[""]}'.")
else:
print("[MultiBoot] Command lines:")
for key in sorted(commandLine.keys()):
print(f"[MultiBoot] Mode '{key}': '{commandLine[key]}'.")
else:
print(f"[MultiBoot] Command line: '{startupFile}'.")
- print(f"[MultiBoot] Kernel device: '{bootSlots[slotCode].get('kernel', 'Unknown')}'.")
- print(f"[MultiBoot] Root device: '{bootSlots[slotCode].get('device', 'Unknown')}'.")
- print(f"[MultiBoot] Root directory: '{bootSlots[slotCode].get('rootsubdir', 'Unknown')}'.")
- print(f"[MultiBoot] UBI device: '{'Yes' if bootSlots[slotCode].get('ubi', False) else 'No'}'.")
- print(f"[MultiBoot] UUID device: '{'Yes' if bootSlots[slotCode].get('uuid', False) else 'No'}'.")
+ print(f"[MultiBoot] Kernel device: '{bootSlots[slotCode].get("kernel", "Unknown")}'.")
+ print(f"[MultiBoot] Root device: '{bootSlots[slotCode].get("device", "Unknown")}'.")
+ print(f"[MultiBoot] Root directory: '{bootSlots[slotCode].get("rootsubdir", "Unknown")}'.")
+ print(f"[MultiBoot] UBI device: '{"Yes" if bootSlots[slotCode].get("ubi", False) else "No"}'.")
+ print(f"[MultiBoot] UUID device: '{"Yes" if bootSlots[slotCode].get("uuid", False) else "No"}'.")
print(f"[MultiBoot] {len(bootSlots)} boot slots detected.")
return bootSlots, bootSlotsKeys
@@ -400,16 +400,16 @@ def findSlot(self): # Part of getSlotImageList().
if self.debugMode:
for slotCode in sorted(self.imageList.keys()):
# print(f"[MultiBoot] findSlot DEBUG: Image slot '{slotCode}': {self.imageList[slotCode]}")
- print(f"[MultiBoot] Slot '{slotCode}' content: '{self.imageList[slotCode].get('imagelogname', 'Unknown')}'.")
- print(f"[MultiBoot] Device: '{self.imageList[slotCode].get('devicelog', 'Unknown')}'.")
- print(f"[MultiBoot] Root: '{self.imageList[slotCode].get('rootlog', 'Unknown')}'.")
- print(f"[MultiBoot] Detection: '{self.imageList[slotCode].get('detection', 'Unknown')}'.")
- print(f"[MultiBoot] Status: '{self.imageList[slotCode].get('status', 'Unknown').capitalize()}'.")
+ print(f"[MultiBoot] Slot '{slotCode}' content: '{self.imageList[slotCode].get("imagelogname", "Unknown")}'.")
+ print(f"[MultiBoot] Device: '{self.imageList[slotCode].get("devicelog", "Unknown")}'.")
+ print(f"[MultiBoot] Root: '{self.imageList[slotCode].get("rootlog", "Unknown")}'.")
+ print(f"[MultiBoot] Detection: '{self.imageList[slotCode].get("detection", "Unknown")}'.")
+ print(f"[MultiBoot] Status: '{self.imageList[slotCode].get("status", "Unknown").capitalize()}'.")
modes = self.imageList[slotCode].get("bootCodes")
if modes and modes != [""]:
print(f"[MultiBoot] Boot modes: '{"', '".join(modes)}'.")
- print(f"[MultiBoot] UBI device: '{'Yes' if self.imageList[slotCode].get('ubi', False) else 'No'}'.")
- print(f"[MultiBoot] UUID device: '{'Yes' if self.imageList[slotCode].get('uuid', False) else 'No'}'.")
+ print(f"[MultiBoot] UBI device: '{"Yes" if self.imageList[slotCode].get("ubi", False) else "No"}'.")
+ print(f"[MultiBoot] UUID device: '{"Yes" if self.imageList[slotCode].get("uuid", False) else "No"}'.")
print(f"[MultiBoot] {len(self.imageList)} boot slots detected.")
self.callback(self.imageList)
@@ -432,32 +432,32 @@ def analyzeSlot(self, data, retVal, extraArgs): # Part of getSlotImageList().
revision = "" if revision.strip() == compileDate else revision
compileDate = f"{compileDate[0:4]}-{compileDate[4:6]}-{compileDate[6:8]}"
self.imageList[self.slotCode]["detection"] = "Found an enigma information file"
- self.imageList[self.slotCode]["imagename"] = f"{info.get('displaydistro', info.get('distro'))} {info.get('imgversion')}{revision} ({compileDate})"
- self.imageList[self.slotCode]["imagelogname"] = f"{info.get('displaydistro', info.get('distro'))} {info.get('imgversion')}{revision} ({compileDate})"
+ self.imageList[self.slotCode]["imagename"] = f"{info.get("displaydistro", info.get("distro"))} {info.get("imgversion")}{revision} ({compileDate})"
+ self.imageList[self.slotCode]["imagelogname"] = f"{info.get("displaydistro", info.get("distro"))} {info.get("imgversion")}{revision} ({compileDate})"
self.imageList[self.slotCode]["status"] = "active"
elif isfile(infoFile1):
info = self.readSlotInfo(infoFile1)
compileDate = self.getCompiledate(imageDir)
compileDate = f"{compileDate[0:4]}-{compileDate[4:6]}-{compileDate[6:8]}"
- imgversion = str(info.get("version"))
- if "." not in imgversion and "-" not in imgversion and imgversion.isdigit():
- imgversion = f"{int(imgversion[0:2])}.{int(imgversion[3:5])}"
+ version = str(info.get("version"))
+ if "." not in version and "-" not in version and version.isdigit():
+ version = f"{int(version[0:2])}.{int(version[3:5])}"
self.imageList[self.slotCode]["detection"] = "Found an image version file"
- creator = info.get('creator')
+ creator = info.get("creator")
if creator is not None:
- self.imageList[self.slotCode]["imagename"] = f"{creator.split()[0]} {imgversion} ({compileDate})"
- self.imageList[self.slotCode]["imagelogname"] = f"{creator.split()[0]} {imgversion} ({compileDate})"
+ self.imageList[self.slotCode]["imagename"] = f"{creator.split()[0]} {version} ({compileDate})"
+ self.imageList[self.slotCode]["imagelogname"] = f"{creator.split()[0]} {version} ({compileDate})"
else:
- self.imageList[self.slotCode]["imagename"] = f"Unknown Creator {imgversion} ({compileDate})"
- self.imageList[self.slotCode]["imagelogname"] = f"Unknown Creator {imgversion} ({compileDate})"
+ self.imageList[self.slotCode]["imagename"] = f"Unknown Creator {version} ({compileDate})"
+ self.imageList[self.slotCode]["imagelogname"] = f"Unknown Creator {version} ({compileDate})"
self.imageList[self.slotCode]["status"] = "active"
elif isfile(pathjoin(imageDir, "usr/bin/enigma2")):
info = self.deriveSlotInfo(imageDir)
compileDate = str(info.get("compiledate"))
compileDate = f"{compileDate[0:4]}-{compileDate[4:6]}-{compileDate[6:8]}"
self.imageList[self.slotCode]["detection"] = "Found an enigma2 binary file"
- self.imageList[self.slotCode]["imagename"] = f"{info.get('displaydistro', info.get('distro'))} {info.get('imgversion')} ({compileDate})"
- self.imageList[self.slotCode]["imagelogname"] = f"{info.get('displaydistro', info.get('distro'))} {info.get('imgversion')} ({compileDate})"
+ self.imageList[self.slotCode]["imagename"] = f"{info.get("displaydistro", info.get("distro"))} {info.get("imgversion")} ({compileDate})"
+ self.imageList[self.slotCode]["imagelogname"] = f"{info.get("displaydistro", info.get("distro"))} {info.get("imgversion")} ({compileDate})"
self.imageList[self.slotCode]["status"] = "active"
else:
self.imageList[self.slotCode]["detection"] = "Found no enigma files"
diff --git a/lib/python/skin.py b/lib/python/skin.py
index e40fe11d4a0..232fb168c89 100644
--- a/lib/python/skin.py
+++ b/lib/python/skin.py
@@ -153,9 +153,7 @@ def InitSkins():
getDesktop(GUI_SKIN_ID).resize(eSize(resolution[0], resolution[1]))
runCallbacks = True
# Load all XML templates.
- skinTemplatesFileName = resolveFilename(SCOPE_SKINS, pathjoin(dirname(currentPrimarySkin), "skinTemplates.xml"))
- if isfile(skinTemplatesFileName):
- loadSkinTemplates(skinTemplatesFileName)
+ reloadSkinTemplates()
# Method to load a skin XML file into the skin data structures.
@@ -203,22 +201,39 @@ def loadSkin(filename, scope=SCOPE_SKINS, desktop=getDesktop(GUI_SKIN_ID), scree
return False
-# Method to load a skinTemplates.xml if one exists.
+# Method to load a skinTemplates.xml if one exists or load the templates from the screens.
#
def loadSkinTemplates(skinTemplatesFileName):
- print(f"[Skin] Loading XML templates from '{skinTemplatesFileName}'.")
- domStyles = fileReadXML(skinTemplatesFileName, source=MODULE_NAME)
- if domStyles is not None:
- for template in domStyles.findall("template"):
- component = template.get("component")
- name = template.get("name")
- if component and name:
- if component in componentTemplates:
- componentTemplates[component][name] = template
- else:
- componentTemplates[component] = {name: template}
- if config.crash.debugScreens.value:
- print(f"[Skin] DEBUG: componentTemplates '{componentTemplates}'.")
+ if isfile(skinTemplatesFileName):
+ print(f"[Skin] Loading XML templates from '{skinTemplatesFileName}'.")
+ domStyles = fileReadXML(skinTemplatesFileName, source=MODULE_NAME)
+ if domStyles is not None:
+ for template in domStyles.findall("template"):
+ component = template.get("component")
+ name = template.get("name")
+ if component and name:
+ if component in componentTemplates:
+ componentTemplates[component][name] = template
+ else:
+ componentTemplates[component] = {name: template}
+ else:
+ for screen in domScreens:
+ element, path = domScreens.get(screen, (None, None))
+ for template in element.findall(".//widget/templates/template"):
+ component = template.get("component")
+ name = template.get("name")
+ if component and name:
+ if component in componentTemplates:
+ componentTemplates[component][name] = template
+ else:
+ componentTemplates[component] = {name: template}
+ if config.crash.debugScreens.value:
+ print(f"[Skin] DEBUG: componentTemplates '{componentTemplates}'.")
+
+
+def reloadSkinTemplates():
+ skinTemplatesFileName = resolveFilename(SCOPE_SKINS, pathjoin(dirname(currentPrimarySkin), "skinTemplates.xml"))
+ loadSkinTemplates(skinTemplatesFileName)
def reloadSkins():
@@ -1817,7 +1832,7 @@ def collectColors(self, attributes):
attributes[color] = translatedColor
return attributes
- def collectAttributes(self, node, context, ignore=(), excludeItemValues=None, includeItemValues=None):
+ def collectAttributes(self, node, context, ignore=(), excludeItemIndexes=None, includeItemIndexes=None):
horizontalAlignments = {
"left": 1,
"center": 4,
@@ -1846,7 +1861,7 @@ def collectAttributes(self, node, context, ignore=(), excludeItemValues=None, in
pos = None
size = None
skinAttributes = []
- itemValue = ""
+ itemIndex = ""
for attrib, value in node.items(): # Walk all attributes.
if attrib not in ignore:
newValue = value
@@ -1855,13 +1870,14 @@ def collectAttributes(self, node, context, ignore=(), excludeItemValues=None, in
pos = newValue
case "size":
size = newValue
- case "value":
- itemValue = value
+ case "index":
+ itemIndex = value
+ skinAttributes.append((attrib, newValue))
case _:
skinAttributes.append((attrib, newValue))
- if itemValue and includeItemValues and itemValue not in includeItemValues:
+ if itemIndex and includeItemIndexes and itemIndex not in includeItemIndexes:
return []
- if itemValue and excludeItemValues and itemValue in excludeItemValues:
+ if itemIndex and excludeItemIndexes and itemIndex in excludeItemIndexes:
return []
if pos is not None:
pos, size = context.parse(pos, size, None)
@@ -1884,7 +1900,7 @@ def collectAttributes(self, node, context, ignore=(), excludeItemValues=None, in
attributes = self.collectColors(attributes)
return [attributes]
- def processPanel(self, widget, context, excludeItemValues=None, includeItemValues=None):
+ def processPanel(self, widget, context, excludeItemIndexes=None, includeItemIndexes=None):
if self.debug:
print(f"[TemplateParser] processPanel DEBUG: Position={widget.attrib.get("position")}, Size={widget.attrib.get("size")}.")
print(f"[TemplateParser] processPanel DEBUG: Parent x={context.x}, width={context.w}.")
@@ -1909,7 +1925,7 @@ def processPanel(self, widget, context, excludeItemValues=None, includeItemValue
items = []
for element in list(widget):
processor = self.processors.get(element.tag, self.processNone)
- newItems = processor(element, newContext, excludeItemValues=excludeItemValues, includeItemValues=includeItemValues)
+ newItems = processor(element, newContext, excludeItemIndexes=excludeItemIndexes, includeItemIndexes=includeItemIndexes)
if newItems:
items += newItems
if layout == "horizontal" and newContext.w > 0:
@@ -2047,14 +2063,6 @@ def processWidget(widget, context):
raise SkinError(f"Component with name '{widgetName}' was not found in skin of screen '{myName}'")
# assert screen[widgetName] is not Source
collectAttributes(attributes, widget, context, skinPath, ignore=("name",))
- for widgetTemplate in widget.findall("template"):
- widgetTemplateComponent = widgetTemplate.get("component")
- widgetTemplateName = widgetTemplate.get("name")
- if widgetTemplateComponent and widgetTemplateName:
- if widgetTemplateComponent in componentTemplates:
- componentTemplates[widgetTemplateComponent][widgetTemplateName] = widgetTemplateComponent
- else:
- componentTemplates[widgetTemplateComponent] = {widgetTemplateName: widgetTemplateComponent}
elif widgetSource:
# print(f"[Skin] DEBUG: Widget source='{widgetSource}'.")
while True: # Get corresponding source until we found a non-obsolete source.