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.getCounterFormatString() not in ["", "%m", "%U", "%W"]:
231 selection.append((timer.getCounterFormatString(), _("Custom")))
232 self.counterFormatString = ConfigSelection(selection, default = timer.getCounterFormatString())
234 # Avoid Duplicate Description
235 self.avoidDuplicateDescription = ConfigEnableDisable(default = timer.getAvoidDuplicateDescription())
238 # First four entries are always shown
240 getConfigListEntry(_("Enabled"), self.enabled),
241 getConfigListEntry(_("Description"), self.name),
242 getConfigListEntry(_("Match Title"), self.match),
243 getConfigListEntry(_("Timer Type"), self.justplay),
244 getConfigListEntry(_("Only match during Timespan"), self.timespan)
247 # Only allow editing timespan when it's enabled
248 if self.timespan.value:
250 getConfigListEntry(_("Begin of Timespan"), self.timespanbegin),
251 getConfigListEntry(_("End of Timespan"), self.timespanend)
254 self.list.append(getConfigListEntry(_("Custom offset"), self.offset))
256 # Only allow editing offsets when it's enabled
257 if self.offset.value:
259 getConfigListEntry(_("Offset before recording (in m)"), self.offsetbegin),
260 getConfigListEntry(_("Offset after recording (in m)"), self.offsetend)
263 self.list.append(getConfigListEntry(_("Set maximum Duration"), self.duration))
265 # Only allow editing maxduration when it's enabled
266 if self.duration.value:
268 getConfigListEntry(_("Maximum Duration (in m)"), self.durationlength)
271 self.list.append(getConfigListEntry(_("After event"), self.afterevent))
273 # Only allow setting afterevent timespan when afterevent is active
274 if self.afterevent.value != "default":
275 self.list.append(getConfigListEntry(_("Execute after Event during Timespan"), self.afterevent_timespan))
277 # Only allow editing timespan when it's enabled
278 if self.afterevent_timespan.value:
280 getConfigListEntry(_("Begin of after Event Timespan"), self.afterevent_timespanbegin),
281 getConfigListEntry(_("End of after Event Timespan"), self.afterevent_timespanend)
284 self.list.append(getConfigListEntry(_("Record a maximum of x times"), self.counter))
286 # Only allow setting matchLeft when counting hits
287 if self.counter.value:
288 self.list.append(getConfigListEntry(_("Ammount of recordings left"), self.counterLeft))
289 self.list.append(getConfigListEntry(_("Reset Count"), self.counterFormatString))
291 self.list.append(getConfigListEntry(_("Require Description to be unique"), self.avoidDuplicateDescription))
293 def reloadList(self, value):
295 self["config"].setList(self.list)
297 def editFilter(self):
298 self.session.openWithCallback(
299 self.editFilterCallback,
300 AutoTimerFilterEditor,
306 def editFilterCallback(self, ret):
308 self.filterSet = ret[0]
309 self.excludes = ret[1]
310 self.includes = ret[2]
311 self.renameFilterButton()
313 def editChannels(self):
314 self.session.openWithCallback(
315 self.editChannelsCallback,
316 AutoTimerChannelEditor,
317 self.serviceRestriction,
321 def editChannelsCallback(self, ret):
323 self.serviceRestriction = ret[0]
324 self.services = ret[1]
325 self.renameChannelButton()
328 if self["config"].isChanged():
329 self.session.openWithCallback(self.cancelConfirm, MessageBox, _("Really close without saving settings?"))
333 def cancelConfirm(self, ret):
338 # Check if we have a trailing whitespace
339 if self.match.value[-1:] == " ":
340 self.session.openWithCallback(
343 _('You entered "%s" as Text to match.\nDo you want to remove trailing whitespaces?') % (self.match.value)
349 def saveCallback(self, ret):
352 self.match.value = self.match.value.rstrip()
354 # Don't to anything if MessageBox was canceled!
358 self.timer.match = self.match.value
361 self.timer.name = self.name.value or self.timer.match
364 self.timer.enabled = self.enabled.value
367 self.timer.justplay = self.justplay.value == "zap"
370 if self.timespan.value:
371 start = self.timespanbegin.value
372 end = self.timespanend.value
373 self.timer.timespan = (start, end)
375 self.timer.timespan = None
378 if self.serviceRestriction:
379 self.timer.services = self.services
381 self.timer.services = None
384 if self.offset.value:
385 self.timer.offset = (self.offsetbegin.value*60, self.offsetend.value*60)
387 self.timer.offset = None
390 if self.afterevent.value == "default":
391 self.timer.afterevent = []
393 afterevent = {"nothing": AFTEREVENT.NONE, "deepstandby": AFTEREVENT.DEEPSTANDBY, "standby": AFTEREVENT.STANDBY}[self.afterevent.value]
394 # AfterEvent Timespan
395 if self.afterevent_timespan.value:
396 start = self.afterevent_timespanbegin.value
397 end = self.afterevent_timespanend.value
398 self.timer.afterevent = [(afterevent, (start, end))]
400 self.timer.afterevent = [(afterevent, None)]
403 if self.duration.value:
404 self.timer.maxduration = self.durationlength.value*60
406 self.timer.maxduration = None
410 self.timer.exclude = self.excludes
411 self.timer.include = self.includes
413 self.timer.exclude = None
414 self.timer.include = None
417 if self.counter.value:
418 self.timer.matchCount = self.counter.value
419 if self.counterLeft.value <= self.counter.value:
420 self.timer.matchLeft = self.counterLeft.value
422 self.timer.matchLeft = self.counter.value
423 if self.counterFormatString.value:
424 self.timer.matchFormatString = self.counterFormatString.value
426 self.timer.matchFormatString = ''
428 self.timer.matchCount = 0
429 self.timer.matchLeft = 0
430 self.timer.matchFormatString = ''
432 self.timer.avoidDuplicateDescription = self.avoidDuplicateDescription.value
435 self.close(self.timer)
437 class AutoTimerFilterEditor(Screen, ConfigListScreen):
438 """Edit AutoTimer Filter"""
440 skin = """<screen name="AutoFilterEditor" title="Edit AutoTimer Filters" position="75,150" size="565,245">
441 <widget name="config" position="5,5" size="555,200" scrollbarMode="showOnDemand" />
442 <ePixmap position="5,205" zPosition="4" size="140,40" pixmap="skin_default/key-red.png" transparent="1" alphatest="on" />
443 <ePixmap position="145,205" zPosition="4" size="140,40" pixmap="skin_default/key-green.png" transparent="1" alphatest="on" />
444 <ePixmap position="285,205" zPosition="4" size="140,40" pixmap="skin_default/key-yellow.png" transparent="1" alphatest="on" />
445 <ePixmap position="425,205" zPosition="4" size="140,40" pixmap="skin_default/key-blue.png" transparent="1" alphatest="on" />
446 <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" />
447 <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" />
448 <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" />
449 <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" />
452 def __init__(self, session, filterset, excludes, includes):
453 Screen.__init__(self, session)
456 self.setup_title = "AutoTimer Filters"
457 self.onChangedEntry = []
459 self.typeSelection = ConfigSelection(choices = [("title", _("in Title")), ("short", _("in Shortdescription")), ("desc", _("in Description")), ("day", _("on Weekday"))])
460 self.typeSelection.addNotifier(self.refresh, initial_call = False)
462 self.enabled = ConfigEnableDisable(default = filterset)
464 self.excludes = excludes
465 self.includes = includes
469 ConfigListScreen.__init__(self, self.list, session = session, on_change = self.changed)
472 self["key_red"] = Button(_("Cancel"))
473 self["key_green"] = Button(_("Save"))
474 self["key_yellow"] = Button(_("delete"))
475 self["key_blue"] = Button(_("New"))
478 self["actions"] = ActionMap(["SetupActions", "ColorActions"],
480 "cancel": self.cancel,
482 "yellow": self.remove,
491 for x in self.onChangedEntry:
497 def getCurrentEntry(self):
498 return self["config"].getCurrent()[0]
500 def getCurrentValue(self):
501 return str(self["config"].getCurrent()[1].getText())
503 def createSummary(self):
506 def saveCurrent(self):
507 del self.excludes[self.idx][:]
508 del self.includes[self.idx][:]
510 # Warning, accessing a ConfigListEntry directly might be considered evil!
513 for item in self["config"].getList():
515 # Skip empty entries (and those which are no filters)
516 if item[1].value == "" or idx < 2:
518 elif idx < self.lenExcludes:
519 self.excludes[self.idx].append(item[1].value.encode("UTF-8"))
521 self.includes[self.idx].append(item[1].value.encode("UTF-8"))
523 def refresh(self, value):
527 self["config"].setList(self.list)
529 def reloadList(self):
531 getConfigListEntry(_("Enable Filtering"), self.enabled),
532 getConfigListEntry(_("Filter"), self.typeSelection)
535 if self.typeSelection.value == "title":
537 elif self.typeSelection.value == "short":
539 elif self.typeSelection.value == "desc":
545 getConfigListEntry(_("Exclude"), ConfigText(default = x, fixed_size = False))
546 for x in self.excludes[self.idx]
548 self.lenExcludes = len(self.list)
550 getConfigListEntry(_("Include"), ConfigText(default = x, fixed_size = False))
551 for x in self.includes[self.idx]
555 idx = self["config"].getCurrentIndex()
557 if idx < self.lenExcludes:
558 self.lenExcludes -= 1
560 list = self["config"].getList()
561 list.remove(self["config"].getCurrent())
562 self["config"].setList(list)
565 self.session.openWithCallback(
568 _("Select type of Filter"),
575 def typeSelected(self, ret):
577 list = self["config"].getList()
580 pos = self.lenExcludes
581 self.lenExcludes += 1
587 if self.typeSelection.value == "day":
588 entry = getConfigListEntry(text, ConfigSelection(choices = weekdays))
590 entry = getConfigListEntry(text, ConfigText(fixed_size = False))
592 list.insert(pos, entry)
593 self["config"].setList(list)
596 if self["config"].isChanged():
597 self.session.openWithCallback(self.cancelConfirm, MessageBox, _("Really close without saving settings?"))
601 def cancelConfirm(self, ret):
614 class AutoTimerChannelEditor(Screen, ConfigListScreen):
615 """Edit allowed Channels of a AutoTimer"""
617 skin = """<screen name="AutoChannelEditor" title="Edit AutoTimer Channels" position="75,150" size="565,245">
618 <widget name="config" position="5,5" size="555,200" scrollbarMode="showOnDemand" />
619 <ePixmap position="5,205" zPosition="4" size="140,40" pixmap="skin_default/key-red.png" transparent="1" alphatest="on" />
620 <ePixmap position="145,205" zPosition="4" size="140,40" pixmap="skin_default/key-green.png" transparent="1" alphatest="on" />
621 <ePixmap position="285,205" zPosition="4" size="140,40" pixmap="skin_default/key-yellow.png" transparent="1" alphatest="on" />
622 <ePixmap position="425,205" zPosition="4" size="140,40" pixmap="skin_default/key-blue.png" transparent="1" alphatest="on" />
623 <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" />
624 <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" />
625 <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" />
626 <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" />
629 def __init__(self, session, servicerestriction, servicelist):
630 Screen.__init__(self, session)
633 self.setup_title = "AutoTimer Channels"
634 self.onChangedEntry = []
637 getConfigListEntry(_("Enable Channel Restriction"), ConfigEnableDisable(default = servicerestriction))
641 getConfigListEntry(_("Record on"), ConfigSelection(choices = [(str(x), ServiceReference(str(x)).getServiceName().replace('\xc2\x86', '').replace('\xc2\x87', ''))]))
645 ConfigListScreen.__init__(self, self.list, session = session, on_change = self.changed)
648 self["key_red"] = Button(_("Cancel"))
649 self["key_green"] = Button(_("OK"))
650 self["key_yellow"] = Button(_("delete"))
651 self["key_blue"] = Button(_("New"))
654 self["actions"] = ActionMap(["SetupActions", "ColorActions"],
656 "cancel": self.cancel,
658 "yellow": self.removeChannel,
659 "blue": self.newChannel
667 for x in self.onChangedEntry:
673 def getCurrentEntry(self):
674 return self["config"].getCurrent()[0]
676 def getCurrentValue(self):
677 return str(self["config"].getCurrent()[1].getText())
679 def createSummary(self):
682 def removeChannel(self):
683 if self["config"].getCurrentIndex() != 0:
684 list = self["config"].getList()
685 list.remove(self["config"].getCurrent())
686 self["config"].setList(list)
688 def newChannel(self):
689 self.session.openWithCallback(
690 self.finishedChannelSelection,
691 SimpleChannelSelection,
692 _("Select channel to record from")
695 def finishedChannelSelection(self, *args):
697 list = self["config"].getList()
698 sname = args[0].toString()
700 # strip all after last :
701 pos = sname.rfind(':')
703 sname = sname[:pos+1]
705 list.append(getConfigListEntry(_("Record on"), ConfigSelection(choices = [(sname, ServiceReference(args[0]).getServiceName().replace('\xc2\x86', '').replace('\xc2\x87', ''))])))
706 self["config"].setList(list)
709 if self["config"].isChanged():
710 self.session.openWithCallback(self.cancelConfirm, MessageBox, _("Really close without saving settings?"))
714 def cancelConfirm(self, ret):
719 list = self["config"].getList()
720 restriction = list.pop(0)
722 # Warning, accessing a ConfigListEntry directly might be considered evil!
724 restriction[1].value,
726 x[1].value.encode("UTF-8")