don't crash gui on custom counter format string (added to list as "custom")
[vuplus_dvbapp-plugin] / autotimer / src / AutoTimerEditor.py
1 # GUI (Screens)
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
7
8 # GUI (Summary)
9 from Screens.Setup import SetupSummary
10
11 # GUI (Components)
12 from Components.ActionMap import ActionMap
13 from Components.Button import Button
14
15 # Configuration
16 from Components.config import getConfigListEntry, ConfigEnableDisable, ConfigYesNo, ConfigText, ConfigClock, ConfigInteger, ConfigSelection
17
18 # Timer
19 from RecordTimer import AFTEREVENT
20
21 # Needed to convert our timestamp back and forth
22 from time import localtime, mktime
23
24 # Show ServiceName instead of ServiceReference
25 from ServiceReference import ServiceReference
26
27 weekdays = [("0", _("Monday")), ("1", _("Tuesday")),  ("2", _("Wednesday")),  ("3", _("Thursday")),  ("4", _("Friday")),  ("5", _("Saturday")),  ("6", _("Sunday")), ("weekend", _("Weekend"))]
28
29 class AutoTimerEditor(Screen, ConfigListScreen):
30         """Edit AutoTimer"""
31
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" />
42         </screen>"""
43
44         def __init__(self, session, timer):
45                 Screen.__init__(self, session)
46
47                 # Keep Timer
48                 self.timer = timer
49
50                 # Summary
51                 self.setup_title = "AutoTimer Editor"
52                 self.onChangedEntry = []
53
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]):
58                         self.filterSet = True
59                 else:
60                         self.filterSet = False
61
62                 # See if services are restricted
63                 self.services = timer.getServices()
64                 if len(self.services):
65                         self.serviceRestriction = True
66                 else:
67                         self.serviceRestriction = False
68
69                 self.createSetup(timer)
70
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)
78
79                 self.refresh()
80
81                 ConfigListScreen.__init__(self, self.list, session = session, on_change = self.changed)
82
83                 # Initialize Buttons
84                 self["key_red"] = Button(_("Cancel"))
85                 self["key_green"] = Button(_("OK"))
86                 self["key_yellow"] = Button()
87                 self["key_blue"] = Button()
88
89                 # Set Button texts
90                 self.renameChannelButton()
91                 self.renameFilterButton()
92
93                 # Define Actions
94                 self["actions"] = ActionMap(["SetupActions", "ColorActions"],
95                         {
96                                 "cancel": self.cancel,
97                                 "save": self.maybeSave,
98                                 "yellow": self.editFilter,
99                                 "blue": self.editChannels
100                         }
101                 )
102
103                 # Trigger change
104                 self.changed()
105
106         def renameFilterButton(self):
107                 if self.filterSet:
108                         self["key_yellow"].setText(_("Edit Filters"))
109                 else:
110                         self["key_yellow"].setText(_("Add Filters"))
111
112         def renameChannelButton(self):
113                 if self.serviceRestriction:
114                         self["key_blue"].setText(_("Edit Channels"))
115                 else:
116                         self["key_blue"].setText(_("Add Channels"))
117
118         def changed(self):
119                 for x in self.onChangedEntry:
120                         try:
121                                 x()
122                         except:
123                                 pass
124
125         def getCurrentEntry(self):
126                 return self["config"].getCurrent()[0]
127
128         def getCurrentValue(self):
129                 return str(self["config"].getCurrent()[1].getText())
130
131         def createSummary(self):
132                 return SetupSummary
133
134         def createSetup(self, timer):
135                 # Name
136                 self.name = ConfigText(default = timer.name, fixed_size = False)
137
138                 # Match
139                 self.match = ConfigText(default = timer.match, fixed_size = False)
140
141                 # Justplay
142                 self.justplay = ConfigSelection(choices = [("zap", _("zap")), ("record", _("record"))], default = {0: "record", 1: "zap"}[int(timer.justplay)])
143
144                 # Timespan
145                 now = [x for x in localtime()]
146                 if timer.hasTimespan():
147                         default = True
148                         now[3] = timer.timespan[0][0]
149                         now[4] = timer.timespan[0][1]
150                         begin = mktime(now)
151                         now[3] = timer.timespan[1][0]
152                         now[4] = timer.timespan[1][1]
153                         end = mktime(now)
154                 else:
155                         default = False
156                         now[3] = 20
157                         now[4] = 15
158                         begin = mktime(now)
159                         now[3] = 23
160                         now[4] = 15
161                         end = mktime(now)
162                 self.timespan = ConfigEnableDisable(default = default)
163                 self.timespanbegin = ConfigClock(default = begin)
164                 self.timespanend = ConfigClock(default = end)
165
166                 # Services have their own Screen
167
168                 # Offset
169                 if timer.hasOffset():
170                         default = True
171                         begin = timer.getOffsetBegin()
172                         end = timer.getOffsetEnd()
173                 else:
174                         default = False
175                         begin = 5
176                         end = 5
177                 self.offset = ConfigEnableDisable(default = default)
178                 self.offsetbegin = ConfigInteger(default = begin, limits = (0, 60))
179                 self.offsetend = ConfigInteger(default = end, limits = (0, 60))
180
181                 # AfterEvent
182                 if timer.hasAfterEvent():
183                         afterevent = { None: "default", AFTEREVENT.NONE: "nothing", AFTEREVENT.DEEPSTANDBY: "deepstandby", AFTEREVENT.STANDBY: "standby"}[timer.afterevent[0][0]]
184                 else:
185                         afterevent = "default"
186                 self.afterevent = ConfigSelection(choices = [("default", _("standard")), ("nothing", _("do nothing")), ("standby", _("go to standby")), ("deepstandby", _("go to deep standby"))], default = afterevent)
187
188                 # AfterEvent (Timespan)
189                 if timer.hasAfterEvent() and timer.afterevent[0][1][0] is not None:
190                         default = True
191                         now[3] = timer.afterevent[0][1][0][0]
192                         now[4] = timer.afterevent[0][1][0][1]
193                         begin = mktime(now)
194                         now[3] = timer.afterevent[0][1][1][0]
195                         now[4] = timer.afterevent[0][1][1][1]
196                         end = mktime(now)
197                 else:
198                         default = False
199                         now[3] = 23
200                         now[4] = 15
201                         begin = mktime(now)
202                         now[3] = 7
203                         now[4] = 0
204                         end = mktime(now)
205                 self.afterevent_timespan = ConfigEnableDisable(default = default)
206                 self.afterevent_timespanbegin = ConfigClock(default = begin)
207                 self.afterevent_timespanend = ConfigClock(default = end)
208
209                 # Enabled
210                 self.enabled = ConfigYesNo(default = timer.enabled)
211
212                 # Maxduration
213                 if timer.hasDuration():
214                         default = True
215                         duration = timer.getDuration()
216                 else:
217                         default = False
218                         duration =70
219                 self.duration = ConfigEnableDisable(default = default)
220                 self.durationlength = ConfigInteger(default = duration, limits = (0, 600))
221
222                 # Counter
223                 if timer.hasCounter():
224                         default = timer.matchCount
225                 else:
226                         default = 0
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)
233
234         def refresh(self):
235                 # First four entries are always shown
236                 self.list = [
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)
242                 ]
243
244                 # Only allow editing timespan when it's enabled
245                 if self.timespan.value:
246                         self.list.extend([
247                                 getConfigListEntry(_("Begin of Timespan"), self.timespanbegin),
248                                 getConfigListEntry(_("End of Timespan"), self.timespanend)
249                         ])
250
251                 self.list.append(getConfigListEntry(_("Custom offset"), self.offset))
252
253                 # Only allow editing offsets when it's enabled
254                 if self.offset.value:
255                         self.list.extend([
256                                 getConfigListEntry(_("Offset before recording (in m)"), self.offsetbegin),
257                                 getConfigListEntry(_("Offset after recording (in m)"), self.offsetend)
258                         ])
259
260                 self.list.append(getConfigListEntry(_("Set maximum Duration"), self.duration))
261
262                 # Only allow editing maxduration when it's enabled
263                 if self.duration.value:
264                         self.list.extend([
265                                 getConfigListEntry(_("Maximum Duration (in m)"), self.durationlength)
266                         ])
267
268                 self.list.append(getConfigListEntry(_("After event"), self.afterevent))
269
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))
273
274                         # Only allow editing timespan when it's enabled
275                         if self.afterevent_timespan.value:
276                                 self.list.extend([
277                                         getConfigListEntry(_("Begin of after Event Timespan"), self.afterevent_timespanbegin),
278                                         getConfigListEntry(_("End of after Event Timespan"), self.afterevent_timespanend)
279                                 ])
280
281                 self.list.append(getConfigListEntry(_("Record a maximum of x times"), self.counter))
282
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))
287
288         def reloadList(self, value):
289                 self.refresh()
290                 self["config"].setList(self.list)
291
292         def editFilter(self):
293                 self.session.openWithCallback(
294                         self.editFilterCallback,
295                         AutoTimerFilterEditor,
296                         self.filterSet,
297                         self.excludes,
298                         self.includes
299                 )
300
301         def editFilterCallback(self, ret):
302                 if ret:
303                         self.filterSet = ret[0]
304                         self.excludes = ret[1]
305                         self.includes = ret[2]
306                         self.renameFilterButton()
307
308         def editChannels(self):
309                 self.session.openWithCallback(
310                         self.editChannelsCallback,
311                         AutoTimerChannelEditor,
312                         self.serviceRestriction,
313                         self.services
314                 )
315
316         def editChannelsCallback(self, ret):
317                 if ret:
318                         self.serviceRestriction = ret[0]
319                         self.services = ret[1]
320                         self.renameChannelButton()
321
322         def cancel(self):
323                 if self["config"].isChanged():
324                         self.session.openWithCallback(self.cancelConfirm, MessageBox, _("Really close without saving settings?"))
325                 else:
326                         self.close(None)
327
328         def cancelConfirm(self, ret):
329                 if ret:
330                         self.close(None)
331
332         def maybeSave(self):
333                 # Check if we have a trailing whitespace
334                 if self.match.value[-1:] == " ":
335                         self.session.openWithCallback(
336                                 self.saveCallback,
337                                 MessageBox,
338                                 _('You entered "%s" as Text to match.\nDo you want to remove trailing whitespaces?') % (self.match.value)
339                         )
340                 # Just save else
341                 else:
342                         self.save()
343
344         def saveCallback(self, ret):
345                 if ret is not None:
346                         if ret:
347                                 self.match.value = self.match.value.rstrip()
348                         self.save()
349                 # Don't to anything if MessageBox was canceled!
350
351         def save(self):
352                 # Match
353                 self.timer.match = self.match.value
354
355                 # Name
356                 self.timer.name = self.name.value or self.timer.match
357
358                 # Enabled
359                 self.timer.enabled = self.enabled.value
360
361                 # Justplay
362                 self.timer.justplay = self.justplay.value == "zap"
363
364                 # Timespan
365                 if self.timespan.value:
366                         start = self.timespanbegin.value
367                         end = self.timespanend.value
368                         self.timer.timespan = (start, end)
369                 else:
370                         self.timer.timespan = None
371
372                 # Services
373                 if self.serviceRestriction:
374                         self.timer.services = self.services
375                 else:
376                         self.timer.services = None
377
378                 # Offset
379                 if self.offset.value:
380                         self.timer.offset = (self.offsetbegin.value*60, self.offsetend.value*60)
381                 else:
382                         self.timer.offset = None
383
384                 # AfterEvent
385                 if self.afterevent.value == "default":
386                         self.timer.afterevent = []
387                 else:
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))]
394                         else:
395                                 self.timer.afterevent = [(afterevent, None)]
396
397                 # Maxduration
398                 if self.duration.value:
399                         self.timer.maxduration = self.durationlength.value*60
400                 else:
401                         self.timer.maxduration = None
402
403                 # Ex-&Includes
404                 if self.filterSet:
405                         self.timer.exclude = self.excludes
406                         self.timer.include = self.includes
407                 else:
408                         self.timer.exclude = None
409                         self.timer.include = None
410
411                 # Counter
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
416                         else:
417                                 self.timer.matchLeft = self.counter.value
418                         if self.counterFormatString.value:
419                                 self.timer.matchFormatString = self.counterFormatString.value
420                         else:
421                                 self.timer.matchFormatString = ''
422                 else:
423                         self.timer.matchCount = 0
424                         self.timer.matchLeft = 0
425                         self.timer.matchFormatString = ''
426
427                 # Close
428                 self.close(self.timer)
429
430 class AutoTimerFilterEditor(Screen, ConfigListScreen):
431         """Edit AutoTimer Filter"""
432
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" />
443         </screen>"""
444
445         def __init__(self, session, filterset, excludes, includes):
446                 Screen.__init__(self, session)
447
448                 # Summary
449                 self.setup_title = "AutoTimer Filters"
450                 self.onChangedEntry = []
451
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)
454
455                 self.enabled = ConfigEnableDisable(default = filterset)
456
457                 self.excludes = excludes
458                 self.includes = includes
459
460                 self.reloadList()
461
462                 ConfigListScreen.__init__(self, self.list, session = session, on_change = self.changed)
463
464                 # Initialize Buttons
465                 self["key_red"] = Button(_("Cancel"))
466                 self["key_green"] = Button(_("Save"))
467                 self["key_yellow"] = Button(_("delete"))
468                 self["key_blue"] = Button(_("New"))
469
470                 # Define Actions
471                 self["actions"] = ActionMap(["SetupActions", "ColorActions"],
472                         {
473                                 "cancel": self.cancel,
474                                 "save": self.save,
475                                 "yellow": self.remove,
476                                 "blue": self.new
477                         }
478                 )
479
480                 # Trigger change
481                 self.changed()
482
483         def changed(self):
484                 for x in self.onChangedEntry:
485                         try:
486                                 x()
487                         except:
488                                 pass
489
490         def getCurrentEntry(self):
491                 return self["config"].getCurrent()[0]
492
493         def getCurrentValue(self):
494                 return str(self["config"].getCurrent()[1].getText())
495
496         def createSummary(self):
497                 return SetupSummary
498
499         def saveCurrent(self):
500                 del self.excludes[self.idx][:]
501                 del self.includes[self.idx][:]
502
503                 # Warning, accessing a ConfigListEntry directly might be considered evil!
504
505                 idx = -1
506                 for item in self["config"].getList():
507                         idx += 1
508                         # Skip empty entries (and those which are no filters)
509                         if item[1].value == "" or idx < 2:
510                                 continue
511                         elif idx < self.lenExcludes:
512                                 self.excludes[self.idx].append(item[1].value.encode("UTF-8"))
513                         else:
514                                 self.includes[self.idx].append(item[1].value.encode("UTF-8"))
515
516         def refresh(self, value):
517                 self.saveCurrent()
518
519                 self.reloadList()
520                 self["config"].setList(self.list)
521
522         def reloadList(self):
523                 self.list = [
524                         getConfigListEntry(_("Enable Filtering"), self.enabled),
525                         getConfigListEntry(_("Filter"), self.typeSelection)
526                 ]
527
528                 if self.typeSelection.value == "title":
529                         self.idx = 0
530                 elif self.typeSelection.value == "short":
531                         self.idx = 1
532                 elif self.typeSelection.value == "desc":
533                         self.idx = 2
534                 else:
535                         self.idx = 3
536
537                 self.list.extend([
538                         getConfigListEntry(_("Exclude"), ConfigText(default = x, fixed_size = False))
539                                 for x in self.excludes[self.idx]
540                 ])
541                 self.lenExcludes = len(self.list)
542                 self.list.extend([
543                         getConfigListEntry(_("Include"), ConfigText(default = x, fixed_size = False))
544                                 for x in self.includes[self.idx]
545                 ])
546
547         def remove(self):
548                 idx = self["config"].getCurrentIndex()
549                 if idx and idx > 1:
550                         if idx < self.lenExcludes:
551                                 self.lenExcludes -= 1
552
553                         list = self["config"].getList()
554                         list.remove(self["config"].getCurrent())
555                         self["config"].setList(list)
556
557         def new(self):
558                 self.session.openWithCallback(
559                         self.typeSelected,
560                         ChoiceBox,
561                         _("Select type of Filter"),
562                         [
563                                 (_("Exclude"), 0),
564                                 (_("Include"), 1),
565                         ]
566                 )
567
568         def typeSelected(self, ret):
569                 if ret is not None:
570                         list = self["config"].getList()
571
572                         if ret[1] == 0:
573                                 pos = self.lenExcludes
574                                 self.lenExcludes += 1
575                                 text = ret[0]
576                         else:
577                                 pos = len(self.list)
578                                 text = ret[0]
579
580                         if self.typeSelection.value == "day":
581                                 entry = getConfigListEntry(text, ConfigSelection(choices = weekdays))
582                         else:
583                                 entry = getConfigListEntry(text, ConfigText(fixed_size = False))
584
585                         list.insert(pos, entry)
586                         self["config"].setList(list)
587
588         def cancel(self):
589                 if self["config"].isChanged():
590                         self.session.openWithCallback(self.cancelConfirm, MessageBox, _("Really close without saving settings?"))
591                 else:
592                         self.close(None)
593
594         def cancelConfirm(self, ret):
595                 if ret:
596                         self.close(None)
597
598         def save(self):
599                 self.saveCurrent()
600
601                 self.close((
602                         self.enabled.value,
603                         self.excludes,
604                         self.includes
605                 ))
606
607 class AutoTimerChannelEditor(Screen, ConfigListScreen):
608         """Edit allowed Channels of a AutoTimer"""
609
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" />
620         </screen>"""
621
622         def __init__(self, session, servicerestriction, servicelist):
623                 Screen.__init__(self, session)
624
625                 # Summary
626                 self.setup_title = "AutoTimer Channels"
627                 self.onChangedEntry = []
628
629                 self.list = [
630                         getConfigListEntry(_("Enable Channel Restriction"), ConfigEnableDisable(default = servicerestriction))
631                 ]
632
633                 self.list.extend([
634                         getConfigListEntry(_("Record on"), ConfigSelection(choices = [(str(x), ServiceReference(str(x)).getServiceName().replace('\xc2\x86', '').replace('\xc2\x87', ''))]))
635                                 for x in servicelist
636                 ])
637
638                 ConfigListScreen.__init__(self, self.list, session = session, on_change = self.changed)
639
640                 # Initialize Buttons
641                 self["key_red"] = Button(_("Cancel"))
642                 self["key_green"] = Button(_("OK"))
643                 self["key_yellow"] = Button(_("delete"))
644                 self["key_blue"] = Button(_("New"))
645
646                 # Define Actions
647                 self["actions"] = ActionMap(["SetupActions", "ColorActions"],
648                         {
649                                 "cancel": self.cancel,
650                                 "save": self.save,
651                                 "yellow": self.removeChannel,
652                                 "blue": self.newChannel
653                         }
654                 )
655
656                 # Trigger change
657                 self.changed()
658
659         def changed(self):
660                 for x in self.onChangedEntry:
661                         try:
662                                 x()
663                         except:
664                                 pass
665
666         def getCurrentEntry(self):
667                 return self["config"].getCurrent()[0]
668
669         def getCurrentValue(self):
670                 return str(self["config"].getCurrent()[1].getText())
671
672         def createSummary(self):
673                 return SetupSummary
674
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)
680
681         def newChannel(self):
682                 self.session.openWithCallback(
683                         self.finishedChannelSelection,
684                         SimpleChannelSelection,
685                         _("Select channel to record from")
686                 )
687
688         def finishedChannelSelection(self, *args):
689                 if len(args):
690                         list = self["config"].getList()
691                         sname = args[0].toString()
692
693                         # strip all after last :
694                         pos = sname.rfind(':')
695                         if pos != -1:
696                                 sname = sname[:pos+1]
697
698                         list.append(getConfigListEntry(_("Record on"), ConfigSelection(choices = [(sname, ServiceReference(args[0]).getServiceName().replace('\xc2\x86', '').replace('\xc2\x87', ''))])))
699                         self["config"].setList(list)
700
701         def cancel(self):
702                 if self["config"].isChanged():
703                         self.session.openWithCallback(self.cancelConfirm, MessageBox, _("Really close without saving settings?"))
704                 else:
705                         self.close(None)
706
707         def cancelConfirm(self, ret):
708                 if ret:
709                         self.close(None)
710
711         def save(self):
712                 list = self["config"].getList()
713                 restriction = list.pop(0)
714
715                 # Warning, accessing a ConfigListEntry directly might be considered evil!
716                 self.close((
717                         restriction[1].value,
718                         [
719                                 x[1].value.encode("UTF-8")
720                                         for x in list
721                         ]
722                 ))