diff --git a/data/keymap.xml b/data/keymap.xml index 694565393d8..b8753717718 100644 --- a/data/keymap.xml +++ b/data/keymap.xml @@ -661,6 +661,7 @@ + diff --git a/data/setup.xml b/data/setup.xml index 70a0971495c..91f02217a84 100644 --- a/data/setup.xml +++ b/data/setup.xml @@ -130,6 +130,8 @@ config.epg.filter_end config.epg.filter_reversal config.epg.filter_keepsorting + config.epg.ratingsort + config.epg.ratingsort_showratings config.subtitles.ttx_subtitle_colors diff --git a/lib/python/Components/Converter/Makefile.am b/lib/python/Components/Converter/Makefile.am index 20867663c45..f7756414a85 100644 --- a/lib/python/Components/Converter/Makefile.am +++ b/lib/python/Components/Converter/Makefile.am @@ -8,4 +8,5 @@ install_PYTHON = \ ServiceOrbitalPosition.py CryptoInfo.py TextCase.py \ ValueBitTest.py TunerInfo.py ConfigEntryTest.py ClientsStreaming.py TemplatedMultiContent.py ProgressToText.py \ Combine.py SensorToText.py ValueToPixmap.py PliExtraInfo.py genre.py TransponderInfo.py \ - RotorPosition.py VfdDisplay.py AnalogClock.py HddState.py VAudioInfo.py ServiceName2.py + RotorPosition.py VfdDisplay.py AnalogClock.py HddState.py VAudioInfo.py ServiceName2.py \ + RatingSort.py diff --git a/lib/python/Components/Converter/RatingSort.py b/lib/python/Components/Converter/RatingSort.py new file mode 100644 index 00000000000..11da2bb6998 --- /dev/null +++ b/lib/python/Components/Converter/RatingSort.py @@ -0,0 +1,12 @@ +from Components.Converter.EventName import EventName + +class RatingSort(EventName): + def __init__(self, type): + EventName.__init__(self, "Rating") + + def getText(self): + if not getattr(self.source, "ratingSortActive", False): + return "" + return EventName.getText(self) + + text = property(getText) \ No newline at end of file diff --git a/lib/python/Components/EpgList.py b/lib/python/Components/EpgList.py index c0e7e0c4a95..2fcc71cc3e9 100644 --- a/lib/python/Components/EpgList.py +++ b/lib/python/Components/EpgList.py @@ -1,6 +1,6 @@ from Components.GUIComponent import GUIComponent -from enigma import eEPGCache, eListbox, eListboxPythonMultiContent, gFont, RT_HALIGN_LEFT, RT_HALIGN_RIGHT, RT_HALIGN_CENTER, RT_VALIGN_CENTER +from enigma import eEPGCache, eListbox, eListboxPythonMultiContent, gFont, RT_HALIGN_LEFT, RT_HALIGN_RIGHT, RT_HALIGN_CENTER, RT_VALIGN_CENTER, eServiceReference from Tools.Alternatives import CompareWithAlternatives from Tools.LoadPixmap import LoadPixmap @@ -363,14 +363,31 @@ def fillSingleEPG(self, service, sorting=0, filtering=0): self.instance.moveSelectionTo(idx - 1) self.selectionChanged() + def getEventRating(self, event): + try: + ref = event[0] + if isinstance(ref, str): + ref = eServiceReference(ref) + ev = self.epgcache.lookupEventId(ref, int(event[1])) + if ev: + p = ev.getParentalData() + if p: + return p.getRating() or 0 + except Exception as e: + print("[EPG rating error]", event[4], type(event[0]), event[0], event[1], e) + return 0 + def sortSingleEPG(self, type): list = self.list if list: event_id = self.getSelectedEventId() - if type == 1: + if type & 0x10: + list.sort(key=lambda x: (self.getEventRating(x), x[2])) + elif type & 0x20: + list.sort(key=lambda x: (-self.getEventRating(x), x[2])) + elif type & 0x01: list.sort(key=lambda x: (x[4] and x[4].lower(), x[2])) else: - assert (type == 0) list.sort(key=lambda x: x[2]) self.l.invalidate() self.moveToEventId(event_id) diff --git a/lib/python/Components/UsageConfig.py b/lib/python/Components/UsageConfig.py index dd65444bb77..1bce0be5ebb 100644 --- a/lib/python/Components/UsageConfig.py +++ b/lib/python/Components/UsageConfig.py @@ -520,6 +520,8 @@ def minutes(t): config.epg.filter_end.addNotifier(validateEPGFilterTimes) config.epg.filter_reversal = ConfigYesNo(default=False) config.epg.filter_keepsorting = ConfigYesNo(default=False) + config.epg.ratingsort = ConfigYesNo(default=False) + config.epg.ratingsort_showratings = ConfigYesNo(default=False) def correctInvalidEPGDataChange(configElement): eServiceEvent.setUTF8CorrectMode(int(configElement.value)) diff --git a/lib/python/Screens/EpgSelection.py b/lib/python/Screens/EpgSelection.py index 67864f39d38..a4834414893 100644 --- a/lib/python/Screens/EpgSelection.py +++ b/lib/python/Screens/EpgSelection.py @@ -74,6 +74,7 @@ def __init__(self, session, service, zapFunc=None, eventid=None, bouquetChangeCB self.currentService = ServiceReference(service) self.zapFunc = zapFunc self.sort_type = 0 + self["Event"].ratingSortActive = False self.original_cfg_filter_start = config.epg.filter_start.value[:] self.original_cfg_filter_end = config.epg.filter_end.value[:] self.setSortDescription() @@ -119,6 +120,7 @@ def __init__(self, session, service, zapFunc=None, eventid=None, bouquetChangeCB }) self["EPGFilterActions"] = HelpableActionMap(self, ["EPGFilterActions"], { + "instantRecord": (self.instantRecButtonPressed, _("Sort EPG by rating")), "filter": (self.stopButtonPressed, _("EPG filter switching")), "startDown": (self.filterStartDown, _("Start time") + " -"), "startUp": (self.filterStartUp, _("Start time") + " +"), @@ -313,7 +315,7 @@ def stopButtonPressed(self): def fillFilteredSingleEPG(self, timespan): self.serviceToTitle(self.currentService) - self.setTitle(self.instance.getTitle() + timespan) + self.setSingleEpgTitle() self["list"].fillSingleEPG(self.currentService, self.sort_type, self.filtering) def resetFiltering(self): @@ -357,16 +359,32 @@ def filterEndDown(self): def filterEndUp(self): self.filtering and self.filterShiftTimespan('end', 1) + def instantRecButtonPressed(self): + if config.epg.ratingsort.value: + rating = self.sort_type & 0x30 + normal = self.sort_type & 0x01 + if rating == 0x00: + rating = 0x10 + elif rating == 0x10: + rating = 0x20 + else: + rating = 0x00 + self.sort_type = normal | rating + self.updateRatingSortActive() + self.redrawEvent() + self["list"].sortSingleEPG(self.sort_type) + self.setSingleEpgTitle() + def yellowButtonPressed(self): if self.type == EPG_TYPE_MULTI: self["list"].updateMultiEPG(-1) elif self.type == EPG_TYPE_SINGLE: - if self.sort_type == 0: - self.sort_type = 1 - else: - self.sort_type = 0 + self.sort_type &= ~0x30 # remove rating flag + self.sort_type ^= 0x01 + self.updateRatingSortActive() self["list"].sortSingleEPG(self.sort_type) self.setSortDescription() + self.setSingleEpgTitle() elif self.type == EPG_TYPE_SIMILAR: cur = self["list"].getCurrent() cur_event = cur and cur[0] @@ -375,16 +393,39 @@ def yellowButtonPressed(self): self.session.open(EPGSelection, None, None, event) def setSortDescription(self): - if self.sort_type == 1: + if self.sort_type & 0x01: # TRANSLATORS: This must fit into the header button in the EPG-List self["key_yellow"].setText(_("Sort time")) else: # TRANSLATORS: This must fit into the header button in the EPG-List self["key_yellow"].setText(_("Sort A-Z")) + def setSingleEpgTitle(self): + text = self.saved_title + ' - ' + self.currentService.getServiceName() + if self.filtering: + text += " " + self.getTimespanText() + if self.sort_type & 0x10: + text += " - " + _("Rating 0-18") + elif self.sort_type & 0x20: + text += " - " + _("Rating 18-0") + self.setTitle(text) + def resetSortStatus(self): self.sort_type = 0 self.setSortDescription() + self.setSingleEpgTitle() + self.updateRatingSortActive() + + def updateRatingSortActive(self): + self["Event"].ratingSortActive = ( + self.type == EPG_TYPE_SINGLE and + config.epg.ratingsort.value and + config.epg.ratingsort_showratings.value and + bool(self.sort_type & 0x30) + ) + + def redrawEvent(self): + self["Event"].changed((self["Event"].CHANGED_ALL,)) def blueButtonPressed(self): if self.type == EPG_TYPE_MULTI: