2 from Screens.Screen import Screen
3 from Components.ConfigList import ConfigListScreen
4 from Screens.ChannelSelection import SimpleChannelSelection
5 from Screens.MessageBox import MessageBox
6 from Screens.ChoiceBox import ChoiceBox
9 from Screens.Setup import SetupSummary
12 from Components.ActionMap import ActionMap
13 from Components.Button import Button
16 from Components.config import getConfigListEntry, ConfigEnableDisable, ConfigYesNo, ConfigText, ConfigClock, ConfigInteger, ConfigSelection
19 from RecordTimer import AFTEREVENT
21 # Needed to convert our timestamp back and forth
22 from time import localtime, mktime
24 # Show ServiceName instead of ServiceReference
25 from ServiceReference import ServiceReference
27 weekdays = [("0", _("Monday")), ("1", _("Tuesday")), ("2", _("Wednesday")), ("3", _("Thursday")), ("4", _("Friday")), ("5", _("Saturday")), ("6", _("Sunday")), ("weekend", _("Weekend"))]
29 class AutoTimerEditor(Screen, ConfigListScreen):
32 skin = """<screen name="AutoTimerEdit" title="Edit AutoTimer" position="75,155" size="565,280">
33 <widget name="config" position="5,5" size="555,225" scrollbarMode="showOnDemand" />
34 <ePixmap position="0,235" zPosition="4" size="140,40" pixmap="skin_default/key-red.png" transparent="1" alphatest="on" />
35 <ePixmap position="140,235" zPosition="4" size="140,40" pixmap="skin_default/key-green.png" transparent="1" alphatest="on" />
36 <ePixmap position="280,235" zPosition="4" size="140,40" pixmap="skin_default/key-yellow.png" transparent="1" alphatest="on" />
37 <ePixmap position="420,235" zPosition="4" size="140,40" pixmap="skin_default/key-blue.png" transparent="1" alphatest="on" />
38 <widget name="key_red" position="0,235" zPosition="5" size="140,40" valign="center" halign="center" font="Regular;21" transparent="1" foregroundColor="white" shadowColor="black" shadowOffset="-1,-1" />
39 <widget name="key_green" position="140,235" zPosition="5" size="140,40" valign="center" halign="center" font="Regular;21" transparent="1" foregroundColor="white" shadowColor="black" shadowOffset="-1,-1" />
40 <widget name="key_yellow" position="280,235" zPosition="5" size="140,40" valign="center" halign="center" font="Regular;21" transparent="1" foregroundColor="white" shadowColor="black" shadowOffset="-1,-1" />
41 <widget name="key_blue" position="420,235" zPosition="5" size="140,40" valign="center" halign="center" font="Regular;21" transparent="1" foregroundColor="white" shadowColor="black" shadowOffset="-1,-1" />
44 def __init__(self, session, timer):
45 Screen.__init__(self, session)
51 self.setup_title = "AutoTimer Editor"
52 self.onChangedEntry = []
54 # See if we are filtering some strings
55 self.excludes = (timer.getExcludedTitle(), timer.getExcludedShort(), timer.getExcludedDescription(), timer.getExcludedDays())
56 self.includes = (timer.getIncludedTitle(), timer.getIncludedShort(), timer.getIncludedDescription(), timer.getIncludedDays())
57 if len(self.excludes[0]) or len(self.excludes[1]) or len(self.excludes[2]) or len(self.excludes[3]) or len(self.includes[0]) or len(self.includes[1]) or len(self.includes[2]) or len(self.includes[3]):
60 self.filterSet = False
62 # See if services are restricted
63 self.services = timer.getServices()
64 if len(self.services):
65 self.serviceRestriction = True
67 self.serviceRestriction = False
69 self.createSetup(timer)
71 # We might need to change shown items, so add some notifiers
72 self.timespan.addNotifier(self.reloadList, initial_call = False)
73 self.offset.addNotifier(self.reloadList, initial_call = False)
74 self.duration.addNotifier(self.reloadList, initial_call = False)
75 self.afterevent.addNotifier(self.reloadList, initial_call = False)
76 self.afterevent_timespan.addNotifier(self.reloadList, initial_call = False)
77 self.counter.addNotifier(self.reloadList, initial_call = False)
81 ConfigListScreen.__init__(self, self.list, session = session, on_change = self.changed)
84 self["key_red"] = Button(_("Cancel"))
85 self["key_green"] = Button(_("OK"))
86 self["key_yellow"] = Button()
87 self["key_blue"] = Button()
90 self.renameChannelButton()
91 self.renameFilterButton()
94 self["actions"] = ActionMap(["SetupActions", "ColorActions"],
96 "cancel": self.cancel,
97 "save": self.maybeSave,
98 "yellow": self.editFilter,
99 "blue": self.editChannels
106 def renameFilterButton(self):
108 self["key_yellow"].setText(_("Edit Filters"))
110 self["key_yellow"].setText(_("Add Filters"))
112 def renameChannelButton(self):
113 if self.serviceRestriction:
114 self["key_blue"].setText(_("Edit Channels"))
116 self["key_blue"].setText(_("Add Channels"))
119 for x in self.onChangedEntry:
125 def getCurrentEntry(self):
126 return self["config"].getCurrent()[0]
128 def getCurrentValue(self):
129 return str(self["config"].getCurrent()[1].getText())
131 def createSummary(self):
134 def createSetup(self, timer):
136 self.name = ConfigText(default = timer.name, fixed_size = False)
139 self.match = ConfigText(default = timer.match, fixed_size = False)
142 self.justplay = ConfigSelection(choices = [("zap", _("zap")), ("record", _("record"))], default = {0: "record", 1: "zap"}[int(timer.justplay)])
145 now = [x for x in localtime()]
146 if timer.hasTimespan():
148 now[3] = timer.timespan[0][0]
149 now[4] = timer.timespan[0][1]
151 now[3] = timer.timespan[1][0]
152 now[4] = timer.timespan[1][1]
162 self.timespan = ConfigEnableDisable(default = default)
163 self.timespanbegin = ConfigClock(default = begin)
164 self.timespanend = ConfigClock(default = end)
166 # Services have their own Screen
169 if timer.hasOffset():
171 begin = timer.getOffsetBegin()
172 end = timer.getOffsetEnd()
177 self.offset = ConfigEnableDisable(default = default)
178 self.offsetbegin = ConfigInteger(default = begin, limits = (0, 60))
179 self.offsetend = ConfigInteger(default = end, limits = (0, 60))
182 if timer.hasAfterEvent():
183 afterevent = { None: "default", AFTEREVENT.NONE: "nothing", AFTEREVENT.DEEPSTANDBY: "deepstandby", AFTEREVENT.STANDBY: "standby"}[timer.afterevent[0][0]]
185 afterevent = "default"
186 self.afterevent = ConfigSelection(choices = [("default", _("standard")), ("nothing", _("do nothing")), ("standby", _("go to standby")), ("deepstandby", _("go to deep standby"))], default = afterevent)
188 # AfterEvent (Timespan)
189 if timer.hasAfterEvent() and timer.afterevent[0][1][0] is not None:
191 now[3] = timer.afterevent[0][1][0][0]
192 now[4] = timer.afterevent[0][1][0][1]
194 now[3] = timer.afterevent[0][1][1][0]
195 now[4] = timer.afterevent[0][1][1][1]
205 self.afterevent_timespan = ConfigEnableDisable(default = default)
206 self.afterevent_timespanbegin = ConfigClock(default = begin)
207 self.afterevent_timespanend = ConfigClock(default = end)
210 self.enabled = ConfigYesNo(default = timer.enabled)
213 if timer.hasDuration():
215 duration = timer.getDuration()
219 self.duration = ConfigEnableDisable(default = default)
220 self.durationlength = ConfigInteger(default = duration, limits = (0, 600))
223 if timer.hasCounter():
224 default = timer.matchCount
227 self.counter = ConfigInteger(default = default, limits = (0, 50))
228 self.counterLeft = ConfigInteger(default = timer.matchLeft, limits = (0, 50))
229 selection = [("", _("Never")), ("%m", _("Monthly")), ("%U", _("Weekly (Sunday)")), ("%W", _("Weekly (Monday)"))]
230 if timer.matchFormatString not in ["", "%m", "%U", "%W"]:
231 selection.append((timer.matchFormatString, _("Custom")))
232 self.counterFormatString = ConfigSelection(selection, default = timer.matchFormatString)
235 # First four entries are always shown
237 getConfigListEntry(_("Enabled"), self.enabled),
238 getConfigListEntry(_("Description"), self.name),
239 getConfigListEntry(_("Match Title"), self.match),
240 getConfigListEntry(_("Timer Type"), self.justplay),
241 getConfigListEntry(_("Only match during Timespan"), self.timespan)
244 # Only allow editing timespan when it's enabled
245 if self.timespan.value:
247 getConfigListEntry(_("Begin of Timespan"), self.timespanbegin),
248 getConfigListEntry(_("End of Timespan"), self.timespanend)
251 self.list.append(getConfigListEntry(_("Custom offset"), self.offset))
253 # Only allow editing offsets when it's enabled
254 if self.offset.value:
256 getConfigListEntry(_("Offset before recording (in m)"), self.offsetbegin),
257 getConfigListEntry(_("Offset after recording (in m)"), self.offsetend)
260 self.list.append(getConfigListEntry(_("Set maximum Duration"), self.duration))
262 # Only allow editing maxduration when it's enabled
263 if self.duration.value:
265 getConfigListEntry(_("Maximum Duration (in m)"), self.durationlength)
268 self.list.append(getConfigListEntry(_("After event"), self.afterevent))
270 # Only allow setting afterevent timespan when afterevent is active
271 if self.afterevent.value != "default":
272 self.list.append(getConfigListEntry(_("Execute after Event during Timespan"), self.afterevent_timespan))
274 # Only allow editing timespan when it's enabled
275 if self.afterevent_timespan.value:
277 getConfigListEntry(_("Begin of after Event Timespan"), self.afterevent_timespanbegin),
278 getConfigListEntry(_("End of after Event Timespan"), self.afterevent_timespanend)
281 self.list.append(getConfigListEntry(_("Record a maximum of x times"), self.counter))
283 # Only allow setting matchLeft when counting hits
284 if self.counter.value:
285 self.list.append(getConfigListEntry(_("Ammount of recordings left"), self.counterLeft))
286 self.list.append(getConfigListEntry(_("Reset Count"), self.counterFormatString))
288 def reloadList(self, value):
290 self["config"].setList(self.list)
292 def editFilter(self):
293 self.session.openWithCallback(
294 self.editFilterCallback,
295 AutoTimerFilterEditor,
301 def editFilterCallback(self, ret):
303 self.filterSet = ret[0]
304 self.excludes = ret[1]
305 self.includes = ret[2]
306 self.renameFilterButton()
308 def editChannels(self):
309 self.session.openWithCallback(
310 self.editChannelsCallback,
311 AutoTimerChannelEditor,
312 self.serviceRestriction,
316 def editChannelsCallback(self, ret):
318 self.serviceRestriction = ret[0]
319 self.services = ret[1]
320 self.renameChannelButton()
323 if self["config"].isChanged():
324 self.session.openWithCallback(self.cancelConfirm, MessageBox, _("Really close without saving settings?"))
328 def cancelConfirm(self, ret):
333 # Check if we have a trailing whitespace
334 if self.match.value[-1:] == " ":
335 self.session.openWithCallback(
338 _('You entered "%s" as Text to match.\nDo you want to remove trailing whitespaces?') % (self.match.value)
344 def saveCallback(self, ret):
347 self.match.value = self.match.value.rstrip()
349 # Don't to anything if MessageBox was canceled!
353 self.timer.match = self.match.value
356 self.timer.name = self.name.value or self.timer.match
359 self.timer.enabled = self.enabled.value
362 self.timer.justplay = self.justplay.value == "zap"
365 if self.timespan.value:
366 start = self.timespanbegin.value
367 end = self.timespanend.value
368 self.timer.timespan = (start, end)
370 self.timer.timespan = None
373 if self.serviceRestriction:
374 self.timer.services = self.services
376 self.timer.services = None
379 if self.offset.value:
380 self.timer.offset = (self.offsetbegin.value*60, self.offsetend.value*60)
382 self.timer.offset = None
385 if self.afterevent.value == "default":
386 self.timer.afterevent = []
388 afterevent = {"nothing": AFTEREVENT.NONE, "deepstandby": AFTEREVENT.DEEPSTANDBY, "standby": AFTEREVENT.STANDBY}[self.afterevent.value]
389 # AfterEvent Timespan
390 if self.afterevent_timespan.value:
391 start = self.afterevent_timespanbegin.value
392 end = self.afterevent_timespanend.value
393 self.timer.afterevent = [(afterevent, (start, end))]
395 self.timer.afterevent = [(afterevent, None)]
398 if self.duration.value:
399 self.timer.maxduration = self.durationlength.value*60
401 self.timer.maxduration = None
405 self.timer.exclude = self.excludes
406 self.timer.include = self.includes
408 self.timer.exclude = None
409 self.timer.include = None
412 if self.counter.value:
413 self.timer.matchCount = self.counter.value
414 if self.counterLeft.value <= self.counter.value:
415 self.timer.matchLeft = self.counterLeft.value
417 self.timer.matchLeft = self.counter.value
418 if self.counterFormatString.value:
419 self.timer.matchFormatString = self.counterFormatString.value
421 self.timer.matchFormatString = ''
423 self.timer.matchCount = 0
424 self.timer.matchLeft = 0
425 self.timer.matchFormatString = ''
428 self.close(self.timer)
430 class AutoTimerFilterEditor(Screen, ConfigListScreen):
431 """Edit AutoTimer Filter"""
433 skin = """<screen name="AutoFilterEditor" title="Edit AutoTimer Filters" position="75,150" size="565,245">
434 <widget name="config" position="5,5" size="555,200" scrollbarMode="showOnDemand" />
435 <ePixmap position="5,205" zPosition="4" size="140,40" pixmap="skin_default/key-red.png" transparent="1" alphatest="on" />
436 <ePixmap position="145,205" zPosition="4" size="140,40" pixmap="skin_default/key-green.png" transparent="1" alphatest="on" />
437 <ePixmap position="285,205" zPosition="4" size="140,40" pixmap="skin_default/key-yellow.png" transparent="1" alphatest="on" />
438 <ePixmap position="425,205" zPosition="4" size="140,40" pixmap="skin_default/key-blue.png" transparent="1" alphatest="on" />
439 <widget name="key_red" position="5,205" zPosition="5" size="140,40" valign="center" halign="center" font="Regular;21" transparent="1" foregroundColor="white" shadowColor="black" shadowOffset="-1,-1" />
440 <widget name="key_green" position="145,205" zPosition="5" size="140,40" valign="center" halign="center" font="Regular;21" transparent="1" foregroundColor="white" shadowColor="black" shadowOffset="-1,-1" />
441 <widget name="key_yellow" position="285,205" zPosition="5" size="140,40" valign="center" halign="center" font="Regular;21" transparent="1" foregroundColor="white" shadowColor="black" shadowOffset="-1,-1" />
442 <widget name="key_blue" position="425,205" zPosition="5" size="140,40" valign="center" halign="center" font="Regular;21" transparent="1" foregroundColor="white" shadowColor="black" shadowOffset="-1,-1" />
445 def __init__(self, session, filterset, excludes, includes):
446 Screen.__init__(self, session)
449 self.setup_title = "AutoTimer Filters"
450 self.onChangedEntry = []
452 self.typeSelection = ConfigSelection(choices = [("title", _("in Title")), ("short", _("in Shortdescription")), ("desc", _("in Description")), ("day", _("on Weekday"))])
453 self.typeSelection.addNotifier(self.refresh, initial_call = False)
455 self.enabled = ConfigEnableDisable(default = filterset)
457 self.excludes = excludes
458 self.includes = includes
462 ConfigListScreen.__init__(self, self.list, session = session, on_change = self.changed)
465 self["key_red"] = Button(_("Cancel"))
466 self["key_green"] = Button(_("Save"))
467 self["key_yellow"] = Button(_("delete"))
468 self["key_blue"] = Button(_("New"))
471 self["actions"] = ActionMap(["SetupActions", "ColorActions"],
473 "cancel": self.cancel,
475 "yellow": self.remove,
484 for x in self.onChangedEntry:
490 def getCurrentEntry(self):
491 return self["config"].getCurrent()[0]
493 def getCurrentValue(self):
494 return str(self["config"].getCurrent()[1].getText())
496 def createSummary(self):
499 def saveCurrent(self):
500 del self.excludes[self.idx][:]
501 del self.includes[self.idx][:]
503 # Warning, accessing a ConfigListEntry directly might be considered evil!
506 for item in self["config"].getList():
508 # Skip empty entries (and those which are no filters)
509 if item[1].value == "" or idx < 2:
511 elif idx < self.lenExcludes:
512 self.excludes[self.idx].append(item[1].value.encode("UTF-8"))
514 self.includes[self.idx].append(item[1].value.encode("UTF-8"))
516 def refresh(self, value):
520 self["config"].setList(self.list)
522 def reloadList(self):
524 getConfigListEntry(_("Enable Filtering"), self.enabled),
525 getConfigListEntry(_("Filter"), self.typeSelection)
528 if self.typeSelection.value == "title":
530 elif self.typeSelection.value == "short":
532 elif self.typeSelection.value == "desc":
538 getConfigListEntry(_("Exclude"), ConfigText(default = x, fixed_size = False))
539 for x in self.excludes[self.idx]
541 self.lenExcludes = len(self.list)
543 getConfigListEntry(_("Include"), ConfigText(default = x, fixed_size = False))
544 for x in self.includes[self.idx]
548 idx = self["config"].getCurrentIndex()
550 if idx < self.lenExcludes:
551 self.lenExcludes -= 1
553 list = self["config"].getList()
554 list.remove(self["config"].getCurrent())
555 self["config"].setList(list)
558 self.session.openWithCallback(
561 _("Select type of Filter"),
568 def typeSelected(self, ret):
570 list = self["config"].getList()
573 pos = self.lenExcludes
574 self.lenExcludes += 1
580 if self.typeSelection.value == "day":
581 entry = getConfigListEntry(text, ConfigSelection(choices = weekdays))
583 entry = getConfigListEntry(text, ConfigText(fixed_size = False))
585 list.insert(pos, entry)
586 self["config"].setList(list)
589 if self["config"].isChanged():
590 self.session.openWithCallback(self.cancelConfirm, MessageBox, _("Really close without saving settings?"))
594 def cancelConfirm(self, ret):
607 class AutoTimerChannelEditor(Screen, ConfigListScreen):
608 """Edit allowed Channels of a AutoTimer"""
610 skin = """<screen name="AutoChannelEditor" title="Edit AutoTimer Channels" position="75,150" size="565,245">
611 <widget name="config" position="5,5" size="555,200" scrollbarMode="showOnDemand" />
612 <ePixmap position="5,205" zPosition="4" size="140,40" pixmap="skin_default/key-red.png" transparent="1" alphatest="on" />
613 <ePixmap position="145,205" zPosition="4" size="140,40" pixmap="skin_default/key-green.png" transparent="1" alphatest="on" />
614 <ePixmap position="285,205" zPosition="4" size="140,40" pixmap="skin_default/key-yellow.png" transparent="1" alphatest="on" />
615 <ePixmap position="425,205" zPosition="4" size="140,40" pixmap="skin_default/key-blue.png" transparent="1" alphatest="on" />
616 <widget name="key_red" position="5,205" zPosition="5" size="140,40" valign="center" halign="center" font="Regular;21" transparent="1" foregroundColor="white" shadowColor="black" shadowOffset="-1,-1" />
617 <widget name="key_green" position="145,205" zPosition="5" size="140,40" valign="center" halign="center" font="Regular;21" transparent="1" foregroundColor="white" shadowColor="black" shadowOffset="-1,-1" />
618 <widget name="key_yellow" position="285,205" zPosition="5" size="140,40" valign="center" halign="center" font="Regular;21" transparent="1" foregroundColor="white" shadowColor="black" shadowOffset="-1,-1" />
619 <widget name="key_blue" position="425,205" zPosition="5" size="140,40" valign="center" halign="center" font="Regular;21" transparent="1" foregroundColor="white" shadowColor="black" shadowOffset="-1,-1" />
622 def __init__(self, session, servicerestriction, servicelist):
623 Screen.__init__(self, session)
626 self.setup_title = "AutoTimer Channels"
627 self.onChangedEntry = []
630 getConfigListEntry(_("Enable Channel Restriction"), ConfigEnableDisable(default = servicerestriction))
634 getConfigListEntry(_("Record on"), ConfigSelection(choices = [(str(x), ServiceReference(str(x)).getServiceName().replace('\xc2\x86', '').replace('\xc2\x87', ''))]))
638 ConfigListScreen.__init__(self, self.list, session = session, on_change = self.changed)
641 self["key_red"] = Button(_("Cancel"))
642 self["key_green"] = Button(_("OK"))
643 self["key_yellow"] = Button(_("delete"))
644 self["key_blue"] = Button(_("New"))
647 self["actions"] = ActionMap(["SetupActions", "ColorActions"],
649 "cancel": self.cancel,
651 "yellow": self.removeChannel,
652 "blue": self.newChannel
660 for x in self.onChangedEntry:
666 def getCurrentEntry(self):
667 return self["config"].getCurrent()[0]
669 def getCurrentValue(self):
670 return str(self["config"].getCurrent()[1].getText())
672 def createSummary(self):
675 def removeChannel(self):
676 if self["config"].getCurrentIndex() != 0:
677 list = self["config"].getList()
678 list.remove(self["config"].getCurrent())
679 self["config"].setList(list)
681 def newChannel(self):
682 self.session.openWithCallback(
683 self.finishedChannelSelection,
684 SimpleChannelSelection,
685 _("Select channel to record from")
688 def finishedChannelSelection(self, *args):
690 list = self["config"].getList()
691 sname = args[0].toString()
693 # strip all after last :
694 pos = sname.rfind(':')
696 sname = sname[:pos+1]
698 list.append(getConfigListEntry(_("Record on"), ConfigSelection(choices = [(sname, ServiceReference(args[0]).getServiceName().replace('\xc2\x86', '').replace('\xc2\x87', ''))])))
699 self["config"].setList(list)
702 if self["config"].isChanged():
703 self.session.openWithCallback(self.cancelConfirm, MessageBox, _("Really close without saving settings?"))
707 def cancelConfirm(self, ret):
712 list = self["config"].getList()
713 restriction = list.pop(0)
715 # Warning, accessing a ConfigListEntry directly might be considered evil!
717 restriction[1].value,
719 x[1].value.encode("UTF-8")