add new per-timer option "avoid duplicate descriptions" to ignore an event if a timer...
[enigma2-plugins.git] / 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.getCounterFormatString() not in ["", "%m", "%U", "%W"]:
231                         selection.append((timer.getCounterFormatString(), _("Custom")))
232                 self.counterFormatString = ConfigSelection(selection, default = timer.getCounterFormatString())
233
234                 # Avoid Duplicate Description
235                 self.avoidDuplicateDescription = ConfigEnableDisable(default = timer.getAvoidDuplicateDescription())
236
237         def refresh(self):
238                 # First four entries are always shown
239                 self.list = [
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)
245                 ]
246
247                 # Only allow editing timespan when it's enabled
248                 if self.timespan.value:
249                         self.list.extend([
250                                 getConfigListEntry(_("Begin of Timespan"), self.timespanbegin),
251                                 getConfigListEntry(_("End of Timespan"), self.timespanend)
252                         ])
253
254                 self.list.append(getConfigListEntry(_("Custom offset"), self.offset))
255
256                 # Only allow editing offsets when it's enabled
257                 if self.offset.value:
258                         self.list.extend([
259                                 getConfigListEntry(_("Offset before recording (in m)"), self.offsetbegin),
260                                 getConfigListEntry(_("Offset after recording (in m)"), self.offsetend)
261                         ])
262
263                 self.list.append(getConfigListEntry(_("Set maximum Duration"), self.duration))
264
265                 # Only allow editing maxduration when it's enabled
266                 if self.duration.value:
267                         self.list.extend([
268                                 getConfigListEntry(_("Maximum Duration (in m)"), self.durationlength)
269                         ])
270
271                 self.list.append(getConfigListEntry(_("After event"), self.afterevent))
272
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))
276
277                         # Only allow editing timespan when it's enabled
278                         if self.afterevent_timespan.value:
279                                 self.list.extend([
280                                         getConfigListEntry(_("Begin of after Event Timespan"), self.afterevent_timespanbegin),
281                                         getConfigListEntry(_("End of after Event Timespan"), self.afterevent_timespanend)
282                                 ])
283
284                 self.list.append(getConfigListEntry(_("Record a maximum of x times"), self.counter))
285
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))
290
291                 self.list.append(getConfigListEntry(_("Require Description to be unique"), self.avoidDuplicateDescription))
292
293         def reloadList(self, value):
294                 self.refresh()
295                 self["config"].setList(self.list)
296
297         def editFilter(self):
298                 self.session.openWithCallback(
299                         self.editFilterCallback,
300                         AutoTimerFilterEditor,
301                         self.filterSet,
302                         self.excludes,
303                         self.includes
304                 )
305
306         def editFilterCallback(self, ret):
307                 if ret:
308                         self.filterSet = ret[0]
309                         self.excludes = ret[1]
310                         self.includes = ret[2]
311                         self.renameFilterButton()
312
313         def editChannels(self):
314                 self.session.openWithCallback(
315                         self.editChannelsCallback,
316                         AutoTimerChannelEditor,
317                         self.serviceRestriction,
318                         self.services
319                 )
320
321         def editChannelsCallback(self, ret):
322                 if ret:
323                         self.serviceRestriction = ret[0]
324                         self.services = ret[1]
325                         self.renameChannelButton()
326
327         def cancel(self):
328                 if self["config"].isChanged():
329                         self.session.openWithCallback(self.cancelConfirm, MessageBox, _("Really close without saving settings?"))
330                 else:
331                         self.close(None)
332
333         def cancelConfirm(self, ret):
334                 if ret:
335                         self.close(None)
336
337         def maybeSave(self):
338                 # Check if we have a trailing whitespace
339                 if self.match.value[-1:] == " ":
340                         self.session.openWithCallback(
341                                 self.saveCallback,
342                                 MessageBox,
343                                 _('You entered "%s" as Text to match.\nDo you want to remove trailing whitespaces?') % (self.match.value)
344                         )
345                 # Just save else
346                 else:
347                         self.save()
348
349         def saveCallback(self, ret):
350                 if ret is not None:
351                         if ret:
352                                 self.match.value = self.match.value.rstrip()
353                         self.save()
354                 # Don't to anything if MessageBox was canceled!
355
356         def save(self):
357                 # Match
358                 self.timer.match = self.match.value
359
360                 # Name
361                 self.timer.name = self.name.value or self.timer.match
362
363                 # Enabled
364                 self.timer.enabled = self.enabled.value
365
366                 # Justplay
367                 self.timer.justplay = self.justplay.value == "zap"
368
369                 # Timespan
370                 if self.timespan.value:
371                         start = self.timespanbegin.value
372                         end = self.timespanend.value
373                         self.timer.timespan = (start, end)
374                 else:
375                         self.timer.timespan = None
376
377                 # Services
378                 if self.serviceRestriction:
379                         self.timer.services = self.services
380                 else:
381                         self.timer.services = None
382
383                 # Offset
384                 if self.offset.value:
385                         self.timer.offset = (self.offsetbegin.value*60, self.offsetend.value*60)
386                 else:
387                         self.timer.offset = None
388
389                 # AfterEvent
390                 if self.afterevent.value == "default":
391                         self.timer.afterevent = []
392                 else:
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))]
399                         else:
400                                 self.timer.afterevent = [(afterevent, None)]
401
402                 # Maxduration
403                 if self.duration.value:
404                         self.timer.maxduration = self.durationlength.value*60
405                 else:
406                         self.timer.maxduration = None
407
408                 # Ex-&Includes
409                 if self.filterSet:
410                         self.timer.exclude = self.excludes
411                         self.timer.include = self.includes
412                 else:
413                         self.timer.exclude = None
414                         self.timer.include = None
415
416                 # Counter
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
421                         else:
422                                 self.timer.matchLeft = self.counter.value
423                         if self.counterFormatString.value:
424                                 self.timer.matchFormatString = self.counterFormatString.value
425                         else:
426                                 self.timer.matchFormatString = ''
427                 else:
428                         self.timer.matchCount = 0
429                         self.timer.matchLeft = 0
430                         self.timer.matchFormatString = ''
431
432                 self.timer.avoidDuplicateDescription = self.avoidDuplicateDescription.value
433
434                 # Close
435                 self.close(self.timer)
436
437 class AutoTimerFilterEditor(Screen, ConfigListScreen):
438         """Edit AutoTimer Filter"""
439
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" />
450         </screen>"""
451
452         def __init__(self, session, filterset, excludes, includes):
453                 Screen.__init__(self, session)
454
455                 # Summary
456                 self.setup_title = "AutoTimer Filters"
457                 self.onChangedEntry = []
458
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)
461
462                 self.enabled = ConfigEnableDisable(default = filterset)
463
464                 self.excludes = excludes
465                 self.includes = includes
466
467                 self.reloadList()
468
469                 ConfigListScreen.__init__(self, self.list, session = session, on_change = self.changed)
470
471                 # Initialize Buttons
472                 self["key_red"] = Button(_("Cancel"))
473                 self["key_green"] = Button(_("Save"))
474                 self["key_yellow"] = Button(_("delete"))
475                 self["key_blue"] = Button(_("New"))
476
477                 # Define Actions
478                 self["actions"] = ActionMap(["SetupActions", "ColorActions"],
479                         {
480                                 "cancel": self.cancel,
481                                 "save": self.save,
482                                 "yellow": self.remove,
483                                 "blue": self.new
484                         }
485                 )
486
487                 # Trigger change
488                 self.changed()
489
490         def changed(self):
491                 for x in self.onChangedEntry:
492                         try:
493                                 x()
494                         except:
495                                 pass
496
497         def getCurrentEntry(self):
498                 return self["config"].getCurrent()[0]
499
500         def getCurrentValue(self):
501                 return str(self["config"].getCurrent()[1].getText())
502
503         def createSummary(self):
504                 return SetupSummary
505
506         def saveCurrent(self):
507                 del self.excludes[self.idx][:]
508                 del self.includes[self.idx][:]
509
510                 # Warning, accessing a ConfigListEntry directly might be considered evil!
511
512                 idx = -1
513                 for item in self["config"].getList():
514                         idx += 1
515                         # Skip empty entries (and those which are no filters)
516                         if item[1].value == "" or idx < 2:
517                                 continue
518                         elif idx < self.lenExcludes:
519                                 self.excludes[self.idx].append(item[1].value.encode("UTF-8"))
520                         else:
521                                 self.includes[self.idx].append(item[1].value.encode("UTF-8"))
522
523         def refresh(self, value):
524                 self.saveCurrent()
525
526                 self.reloadList()
527                 self["config"].setList(self.list)
528
529         def reloadList(self):
530                 self.list = [
531                         getConfigListEntry(_("Enable Filtering"), self.enabled),
532                         getConfigListEntry(_("Filter"), self.typeSelection)
533                 ]
534
535                 if self.typeSelection.value == "title":
536                         self.idx = 0
537                 elif self.typeSelection.value == "short":
538                         self.idx = 1
539                 elif self.typeSelection.value == "desc":
540                         self.idx = 2
541                 else:
542                         self.idx = 3
543
544                 self.list.extend([
545                         getConfigListEntry(_("Exclude"), ConfigText(default = x, fixed_size = False))
546                                 for x in self.excludes[self.idx]
547                 ])
548                 self.lenExcludes = len(self.list)
549                 self.list.extend([
550                         getConfigListEntry(_("Include"), ConfigText(default = x, fixed_size = False))
551                                 for x in self.includes[self.idx]
552                 ])
553
554         def remove(self):
555                 idx = self["config"].getCurrentIndex()
556                 if idx and idx > 1:
557                         if idx < self.lenExcludes:
558                                 self.lenExcludes -= 1
559
560                         list = self["config"].getList()
561                         list.remove(self["config"].getCurrent())
562                         self["config"].setList(list)
563
564         def new(self):
565                 self.session.openWithCallback(
566                         self.typeSelected,
567                         ChoiceBox,
568                         _("Select type of Filter"),
569                         [
570                                 (_("Exclude"), 0),
571                                 (_("Include"), 1),
572                         ]
573                 )
574
575         def typeSelected(self, ret):
576                 if ret is not None:
577                         list = self["config"].getList()
578
579                         if ret[1] == 0:
580                                 pos = self.lenExcludes
581                                 self.lenExcludes += 1
582                                 text = ret[0]
583                         else:
584                                 pos = len(self.list)
585                                 text = ret[0]
586
587                         if self.typeSelection.value == "day":
588                                 entry = getConfigListEntry(text, ConfigSelection(choices = weekdays))
589                         else:
590                                 entry = getConfigListEntry(text, ConfigText(fixed_size = False))
591
592                         list.insert(pos, entry)
593                         self["config"].setList(list)
594
595         def cancel(self):
596                 if self["config"].isChanged():
597                         self.session.openWithCallback(self.cancelConfirm, MessageBox, _("Really close without saving settings?"))
598                 else:
599                         self.close(None)
600
601         def cancelConfirm(self, ret):
602                 if ret:
603                         self.close(None)
604
605         def save(self):
606                 self.saveCurrent()
607
608                 self.close((
609                         self.enabled.value,
610                         self.excludes,
611                         self.includes
612                 ))
613
614 class AutoTimerChannelEditor(Screen, ConfigListScreen):
615         """Edit allowed Channels of a AutoTimer"""
616
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" />
627         </screen>"""
628
629         def __init__(self, session, servicerestriction, servicelist):
630                 Screen.__init__(self, session)
631
632                 # Summary
633                 self.setup_title = "AutoTimer Channels"
634                 self.onChangedEntry = []
635
636                 self.list = [
637                         getConfigListEntry(_("Enable Channel Restriction"), ConfigEnableDisable(default = servicerestriction))
638                 ]
639
640                 self.list.extend([
641                         getConfigListEntry(_("Record on"), ConfigSelection(choices = [(str(x), ServiceReference(str(x)).getServiceName().replace('\xc2\x86', '').replace('\xc2\x87', ''))]))
642                                 for x in servicelist
643                 ])
644
645                 ConfigListScreen.__init__(self, self.list, session = session, on_change = self.changed)
646
647                 # Initialize Buttons
648                 self["key_red"] = Button(_("Cancel"))
649                 self["key_green"] = Button(_("OK"))
650                 self["key_yellow"] = Button(_("delete"))
651                 self["key_blue"] = Button(_("New"))
652
653                 # Define Actions
654                 self["actions"] = ActionMap(["SetupActions", "ColorActions"],
655                         {
656                                 "cancel": self.cancel,
657                                 "save": self.save,
658                                 "yellow": self.removeChannel,
659                                 "blue": self.newChannel
660                         }
661                 )
662
663                 # Trigger change
664                 self.changed()
665
666         def changed(self):
667                 for x in self.onChangedEntry:
668                         try:
669                                 x()
670                         except:
671                                 pass
672
673         def getCurrentEntry(self):
674                 return self["config"].getCurrent()[0]
675
676         def getCurrentValue(self):
677                 return str(self["config"].getCurrent()[1].getText())
678
679         def createSummary(self):
680                 return SetupSummary
681
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)
687
688         def newChannel(self):
689                 self.session.openWithCallback(
690                         self.finishedChannelSelection,
691                         SimpleChannelSelection,
692                         _("Select channel to record from")
693                 )
694
695         def finishedChannelSelection(self, *args):
696                 if len(args):
697                         list = self["config"].getList()
698                         sname = args[0].toString()
699
700                         # strip all after last :
701                         pos = sname.rfind(':')
702                         if pos != -1:
703                                 sname = sname[:pos+1]
704
705                         list.append(getConfigListEntry(_("Record on"), ConfigSelection(choices = [(sname, ServiceReference(args[0]).getServiceName().replace('\xc2\x86', '').replace('\xc2\x87', ''))])))
706                         self["config"].setList(list)
707
708         def cancel(self):
709                 if self["config"].isChanged():
710                         self.session.openWithCallback(self.cancelConfirm, MessageBox, _("Really close without saving settings?"))
711                 else:
712                         self.close(None)
713
714         def cancelConfirm(self, ret):
715                 if ret:
716                         self.close(None)
717
718         def save(self):
719                 list = self["config"].getList()
720                 restriction = list.pop(0)
721
722                 # Warning, accessing a ConfigListEntry directly might be considered evil!
723                 self.close((
724                         restriction[1].value,
725                         [
726                                 x[1].value.encode("UTF-8")
727                                         for x in list
728                         ]
729                 ))