- add function to add autotimer based on an event,
[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, \
17         ConfigYesNo, ConfigText, ConfigClock, ConfigInteger, ConfigSelection
18
19 # Timer
20 from RecordTimer import AFTEREVENT
21
22 # Needed to convert our timestamp back and forth
23 from time import localtime, mktime
24
25 # Show ServiceName instead of ServiceReference
26 from ServiceReference import ServiceReference
27
28 weekdays = [
29         ("0", _("Monday")),
30         ("1", _("Tuesday")),
31         ("2", _("Wednesday")),
32         ("3", _("Thursday")),
33         ("4", _("Friday")),
34         ("5", _("Saturday")),
35         ("6", _("Sunday")),
36         ("weekend", _("Weekend")),
37         ("weekday", _("Weekday"))
38 ]
39
40 class AutoTimerEditor(Screen, ConfigListScreen):
41         """Edit AutoTimer"""
42
43         skin = """<screen name="AutoTimerEdit" title="Edit AutoTimer" position="75,155" size="565,280">
44                 <widget name="config" position="5,5" size="555,225" scrollbarMode="showOnDemand" />
45                 <ePixmap position="0,235" zPosition="4" size="140,40" pixmap="skin_default/key-red.png" transparent="1" alphatest="on" />
46                 <ePixmap position="140,235" zPosition="4" size="140,40" pixmap="skin_default/key-green.png" transparent="1" alphatest="on" />
47                 <ePixmap position="280,235" zPosition="4" size="140,40" pixmap="skin_default/key-yellow.png" transparent="1" alphatest="on" />
48                 <ePixmap position="420,235" zPosition="4" size="140,40" pixmap="skin_default/key-blue.png" transparent="1" alphatest="on" />
49                 <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" />
50                 <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" />
51                 <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" />
52                 <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" />
53         </screen>"""
54
55         def __init__(self, session, timer):
56                 Screen.__init__(self, session)
57
58                 # Keep Timer
59                 self.timer = timer
60
61                 # Summary
62                 self.setup_title = "AutoTimer Editor"
63                 self.onChangedEntry = []
64
65                 # See if we are filtering some strings
66                 self.excludes = (
67                         timer.getExcludedTitle(),
68                         timer.getExcludedShort(),
69                         timer.getExcludedDescription(),
70                         timer.getExcludedDays()
71                 )
72                 self.includes = (
73                         timer.getIncludedTitle(),
74                         timer.getIncludedShort(),
75                         timer.getIncludedDescription(),
76                         timer.getIncludedDays()
77                 )
78                 if len(self.excludes[0]) or len(self.excludes[1]) \
79                                 or len(self.excludes[2]) or len(self.excludes[3]) \
80                                 or len(self.includes[0]) or len(self.includes[1]) \
81                                 or len(self.includes[2]) or len(self.includes[3]):
82                         self.filterSet = True
83                 else:
84                         self.filterSet = False
85
86                 # See if services are restricted
87                 self.services = timer.getServices()
88                 if len(self.services):
89                         self.serviceRestriction = True
90                 else:
91                         self.serviceRestriction = False
92
93                 self.createSetup(timer)
94
95                 # We might need to change shown items, so add some notifiers
96                 self.timespan.addNotifier(self.reloadList, initial_call = False)
97                 self.offset.addNotifier(self.reloadList, initial_call = False)
98                 self.duration.addNotifier(self.reloadList, initial_call = False)
99                 self.afterevent.addNotifier(self.reloadList, initial_call = False)
100                 self.afterevent_timespan.addNotifier(self.reloadList, initial_call = False)
101                 self.counter.addNotifier(self.reloadList, initial_call = False)
102
103                 self.refresh()
104
105                 ConfigListScreen.__init__(self, self.list, session = session, on_change = self.changed)
106
107                 # Initialize Buttons
108                 self["key_red"] = Button(_("Cancel"))
109                 self["key_green"] = Button(_("OK"))
110                 self["key_yellow"] = Button()
111                 self["key_blue"] = Button()
112
113                 # Set Button texts
114                 self.renameChannelButton()
115                 self.renameFilterButton()
116
117                 # Define Actions
118                 self["actions"] = ActionMap(["SetupActions", "ColorActions"],
119                         {
120                                 "cancel": self.cancel,
121                                 "save": self.maybeSave,
122                                 "yellow": self.editFilter,
123                                 "blue": self.editChannels
124                         }
125                 )
126
127                 # Trigger change
128                 self.changed()
129
130         def renameFilterButton(self):
131                 if self.filterSet:
132                         self["key_yellow"].setText(_("Edit Filters"))
133                 else:
134                         self["key_yellow"].setText(_("Add Filters"))
135
136         def renameChannelButton(self):
137                 if self.serviceRestriction:
138                         self["key_blue"].setText(_("Edit Channels"))
139                 else:
140                         self["key_blue"].setText(_("Add Channels"))
141
142         def changed(self):
143                 for x in self.onChangedEntry:
144                         try:
145                                 x()
146                         except:
147                                 pass
148
149         def getCurrentEntry(self):
150                 return self["config"].getCurrent()[0]
151
152         def getCurrentValue(self):
153                 return str(self["config"].getCurrent()[1].getText())
154
155         def createSummary(self):
156                 return SetupSummary
157
158         def createSetup(self, timer):
159                 # Name
160                 self.name = ConfigText(default = timer.name, fixed_size = False)
161
162                 # Match
163                 self.match = ConfigText(default = timer.match, fixed_size = False)
164
165                 # Justplay
166                 self.justplay = ConfigSelection(choices = [("zap", _("zap")), ("record", _("record"))], default = {0: "record", 1: "zap"}[int(timer.justplay)])
167
168                 # Timespan
169                 now = [x for x in localtime()]
170                 if timer.hasTimespan():
171                         default = True
172                         now[3] = timer.timespan[0][0]
173                         now[4] = timer.timespan[0][1]
174                         begin = mktime(now)
175                         now[3] = timer.timespan[1][0]
176                         now[4] = timer.timespan[1][1]
177                         end = mktime(now)
178                 else:
179                         default = False
180                         now[3] = 20
181                         now[4] = 15
182                         begin = mktime(now)
183                         now[3] = 23
184                         now[4] = 15
185                         end = mktime(now)
186                 self.timespan = ConfigEnableDisable(default = default)
187                 self.timespanbegin = ConfigClock(default = begin)
188                 self.timespanend = ConfigClock(default = end)
189
190                 # Services have their own Screen
191
192                 # Offset
193                 if timer.hasOffset():
194                         default = True
195                         begin = timer.getOffsetBegin()
196                         end = timer.getOffsetEnd()
197                 else:
198                         default = False
199                         begin = 5
200                         end = 5
201                 self.offset = ConfigEnableDisable(default = default)
202                 self.offsetbegin = ConfigInteger(default = begin, limits = (0, 180))
203                 self.offsetend = ConfigInteger(default = end, limits = (0, 180))
204
205                 # AfterEvent
206                 if timer.hasAfterEvent():
207                         afterevent = { None: "default", AFTEREVENT.NONE: "nothing", AFTEREVENT.DEEPSTANDBY: "deepstandby", AFTEREVENT.STANDBY: "standby"}[timer.afterevent[0][0]]
208                 else:
209                         afterevent = "default"
210                 self.afterevent = ConfigSelection(choices = [("default", _("standard")), ("nothing", _("do nothing")), ("standby", _("go to standby")), ("deepstandby", _("go to deep standby"))], default = afterevent)
211
212                 # AfterEvent (Timespan)
213                 if timer.hasAfterEvent() and timer.afterevent[0][1][0] is not None:
214                         default = True
215                         now[3] = timer.afterevent[0][1][0][0]
216                         now[4] = timer.afterevent[0][1][0][1]
217                         begin = mktime(now)
218                         now[3] = timer.afterevent[0][1][1][0]
219                         now[4] = timer.afterevent[0][1][1][1]
220                         end = mktime(now)
221                 else:
222                         default = False
223                         now[3] = 23
224                         now[4] = 15
225                         begin = mktime(now)
226                         now[3] = 7
227                         now[4] = 0
228                         end = mktime(now)
229                 self.afterevent_timespan = ConfigEnableDisable(default = default)
230                 self.afterevent_timespanbegin = ConfigClock(default = begin)
231                 self.afterevent_timespanend = ConfigClock(default = end)
232
233                 # Enabled
234                 self.enabled = ConfigYesNo(default = timer.enabled)
235
236                 # Maxduration
237                 if timer.hasDuration():
238                         default = True
239                         duration = timer.getDuration()
240                 else:
241                         default = False
242                         duration =70
243                 self.duration = ConfigEnableDisable(default = default)
244                 self.durationlength = ConfigInteger(default = duration, limits = (0, 600))
245
246                 # Counter
247                 if timer.hasCounter():
248                         default = timer.matchCount
249                 else:
250                         default = 0
251                 self.counter = ConfigInteger(default = default, limits = (0, 50))
252                 self.counterLeft = ConfigInteger(default = timer.matchLeft, limits = (0, 50))
253                 selection = [("", _("Never")), ("%m", _("Monthly")), ("%U", _("Weekly (Sunday)")), ("%W", _("Weekly (Monday)"))]
254                 if timer.getCounterFormatString() not in ["", "%m", "%U", "%W"]:
255                         selection.append((timer.getCounterFormatString(), _("Custom (%s)") % (timer.getCounterFormatString())))
256                 self.counterFormatString = ConfigSelection(selection, default = timer.getCounterFormatString())
257
258                 # Avoid Duplicate Description
259                 self.avoidDuplicateDescription = ConfigEnableDisable(default = timer.getAvoidDuplicateDescription())
260
261         def refresh(self):
262                 # First four entries are always shown
263                 self.list = [
264                         getConfigListEntry(_("Enabled"), self.enabled),
265                         getConfigListEntry(_("Description"), self.name),
266                         getConfigListEntry(_("Match Title"), self.match),
267                         getConfigListEntry(_("Timer Type"), self.justplay),
268                         getConfigListEntry(_("Only match during Timespan"), self.timespan)
269                 ]
270
271                 # Only allow editing timespan when it's enabled
272                 if self.timespan.value:
273                         self.list.extend([
274                                 getConfigListEntry(_("Begin of Timespan"), self.timespanbegin),
275                                 getConfigListEntry(_("End of Timespan"), self.timespanend)
276                         ])
277
278                 self.list.append(getConfigListEntry(_("Custom offset"), self.offset))
279
280                 # Only allow editing offsets when it's enabled
281                 if self.offset.value:
282                         self.list.extend([
283                                 getConfigListEntry(_("Offset before recording (in m)"), self.offsetbegin),
284                                 getConfigListEntry(_("Offset after recording (in m)"), self.offsetend)
285                         ])
286
287                 self.list.append(getConfigListEntry(_("Set maximum Duration"), self.duration))
288
289                 # Only allow editing maxduration when it's enabled
290                 if self.duration.value:
291                         self.list.extend([
292                                 getConfigListEntry(_("Maximum Duration (in m)"), self.durationlength)
293                         ])
294
295                 self.list.append(getConfigListEntry(_("After event"), self.afterevent))
296
297                 # Only allow setting afterevent timespan when afterevent is active
298                 if self.afterevent.value != "default":
299                         self.list.append(getConfigListEntry(_("Execute after Event during Timespan"), self.afterevent_timespan))
300
301                         # Only allow editing timespan when it's enabled
302                         if self.afterevent_timespan.value:
303                                 self.list.extend([
304                                         getConfigListEntry(_("Begin of after Event Timespan"), self.afterevent_timespanbegin),
305                                         getConfigListEntry(_("End of after Event Timespan"), self.afterevent_timespanend)
306                                 ])
307
308                 self.list.append(getConfigListEntry(_("Record a maximum of x times"), self.counter))
309
310                 # Only allow setting matchLeft when counting hits
311                 if self.counter.value:
312                         self.list.append(getConfigListEntry(_("Ammount of recordings left"), self.counterLeft))
313                         self.list.append(getConfigListEntry(_("Reset Count"), self.counterFormatString))
314
315                 self.list.append(getConfigListEntry(_("Require Description to be unique"), self.avoidDuplicateDescription))
316
317         def reloadList(self, value):
318                 self.refresh()
319                 self["config"].setList(self.list)
320
321         def editFilter(self):
322                 self.session.openWithCallback(
323                         self.editFilterCallback,
324                         AutoTimerFilterEditor,
325                         self.filterSet,
326                         self.excludes,
327                         self.includes
328                 )
329
330         def editFilterCallback(self, ret):
331                 if ret:
332                         self.filterSet = ret[0]
333                         self.excludes = ret[1]
334                         self.includes = ret[2]
335                         self.renameFilterButton()
336
337         def editChannels(self):
338                 self.session.openWithCallback(
339                         self.editChannelsCallback,
340                         AutoTimerChannelEditor,
341                         self.serviceRestriction,
342                         self.services
343                 )
344
345         def editChannelsCallback(self, ret):
346                 if ret:
347                         self.serviceRestriction = ret[0]
348                         self.services = ret[1]
349                         self.renameChannelButton()
350
351         def cancel(self):
352                 if self["config"].isChanged():
353                         self.session.openWithCallback(
354                                 self.cancelConfirm,
355                                 MessageBox,
356                                 _("Really close without saving settings?")
357                         )
358                 else:
359                         self.close(None)
360
361         def cancelConfirm(self, ret):
362                 if ret:
363                         self.close(None)
364
365         def maybeSave(self):
366                 # Check if we have a trailing whitespace
367                 if self.match.value[-1:] == " ":
368                         self.session.openWithCallback(
369                                 self.saveCallback,
370                                 MessageBox,
371                                 _('You entered "%s" as Text to match.\nDo you want to remove trailing whitespaces?') % (self.match.value)
372                         )
373                 # Just save else
374                 else:
375                         self.save()
376
377         def saveCallback(self, ret):
378                 if ret is not None:
379                         if ret:
380                                 self.match.value = self.match.value.rstrip()
381                         self.save()
382                 # Don't to anything if MessageBox was canceled!
383
384         def save(self):
385                 # Match
386                 self.timer.match = self.match.value
387
388                 # Name
389                 self.timer.name = self.name.value or self.timer.match
390
391                 # Enabled
392                 self.timer.enabled = self.enabled.value
393
394                 # Justplay
395                 self.timer.justplay = self.justplay.value == "zap"
396
397                 # Timespan
398                 if self.timespan.value:
399                         start = self.timespanbegin.value
400                         end = self.timespanend.value
401                         self.timer.timespan = (start, end)
402                 else:
403                         self.timer.timespan = None
404
405                 # Services
406                 if self.serviceRestriction:
407                         self.timer.services = self.services
408                 else:
409                         self.timer.services = None
410
411                 # Offset
412                 if self.offset.value:
413                         self.timer.offset = (self.offsetbegin.value*60, self.offsetend.value*60)
414                 else:
415                         self.timer.offset = None
416
417                 # AfterEvent
418                 if self.afterevent.value == "default":
419                         self.timer.afterevent = []
420                 else:
421                         afterevent = {"nothing": AFTEREVENT.NONE, "deepstandby": AFTEREVENT.DEEPSTANDBY, "standby": AFTEREVENT.STANDBY}[self.afterevent.value]
422                         # AfterEvent Timespan
423                         if self.afterevent_timespan.value:
424                                 start = self.afterevent_timespanbegin.value
425                                 end = self.afterevent_timespanend.value
426                                 self.timer.afterevent = [(afterevent, (start, end))]
427                         else:
428                                 self.timer.afterevent = [(afterevent, None)]
429
430                 # Maxduration
431                 if self.duration.value:
432                         self.timer.maxduration = self.durationlength.value*60
433                 else:
434                         self.timer.maxduration = None
435
436                 # Ex-&Includes
437                 if self.filterSet:
438                         self.timer.exclude = self.excludes
439                         self.timer.include = self.includes
440                 else:
441                         self.timer.exclude = None
442                         self.timer.include = None
443
444                 # Counter
445                 if self.counter.value:
446                         self.timer.matchCount = self.counter.value
447                         if self.counterLeft.value <= self.counter.value:
448                                 self.timer.matchLeft = self.counterLeft.value
449                         else:
450                                 self.timer.matchLeft = self.counter.value
451                         if self.counterFormatString.value:
452                                 self.timer.matchFormatString = self.counterFormatString.value
453                         else:
454                                 self.timer.matchFormatString = ''
455                 else:
456                         self.timer.matchCount = 0
457                         self.timer.matchLeft = 0
458                         self.timer.matchFormatString = ''
459
460                 self.timer.avoidDuplicateDescription = self.avoidDuplicateDescription.value
461
462                 # Close
463                 self.close(self.timer)
464
465 class AutoTimerFilterEditor(Screen, ConfigListScreen):
466         """Edit AutoTimer Filter"""
467
468         skin = """<screen name="AutoFilterEditor" title="Edit AutoTimer Filters" position="75,150" size="565,245">
469                 <widget name="config" position="5,5" size="555,200" scrollbarMode="showOnDemand" />
470                 <ePixmap position="5,205" zPosition="4" size="140,40" pixmap="skin_default/key-red.png" transparent="1" alphatest="on" />
471                 <ePixmap position="145,205" zPosition="4" size="140,40" pixmap="skin_default/key-green.png" transparent="1" alphatest="on" />
472                 <ePixmap position="285,205" zPosition="4" size="140,40" pixmap="skin_default/key-yellow.png" transparent="1" alphatest="on" />
473                 <ePixmap position="425,205" zPosition="4" size="140,40" pixmap="skin_default/key-blue.png" transparent="1" alphatest="on" />
474                 <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" />
475                 <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" />
476                 <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" />
477                 <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" />
478         </screen>"""
479
480         def __init__(self, session, filterset, excludes, includes):
481                 Screen.__init__(self, session)
482
483                 # Summary
484                 self.setup_title = "AutoTimer Filters"
485                 self.onChangedEntry = []
486
487                 self.typeSelection = ConfigSelection(choices = [("title", _("in Title")), ("short", _("in Shortdescription")), ("desc", _("in Description")), ("day", _("on Weekday"))])
488                 self.typeSelection.addNotifier(self.refresh, initial_call = False)
489
490                 self.enabled = ConfigEnableDisable(default = filterset)
491
492                 self.excludes = excludes
493                 self.includes = includes
494
495                 self.reloadList()
496
497                 ConfigListScreen.__init__(self, self.list, session = session, on_change = self.changed)
498
499                 # Initialize Buttons
500                 self["key_red"] = Button(_("Cancel"))
501                 self["key_green"] = Button(_("Save"))
502                 self["key_yellow"] = Button(_("delete"))
503                 self["key_blue"] = Button(_("New"))
504
505                 # Define Actions
506                 self["actions"] = ActionMap(["SetupActions", "ColorActions"],
507                         {
508                                 "cancel": self.cancel,
509                                 "save": self.save,
510                                 "yellow": self.remove,
511                                 "blue": self.new
512                         }
513                 )
514
515                 # Trigger change
516                 self.changed()
517
518         def changed(self):
519                 for x in self.onChangedEntry:
520                         try:
521                                 x()
522                         except:
523                                 pass
524
525         def getCurrentEntry(self):
526                 return self["config"].getCurrent()[0]
527
528         def getCurrentValue(self):
529                 return str(self["config"].getCurrent()[1].getText())
530
531         def createSummary(self):
532                 return SetupSummary
533
534         def saveCurrent(self):
535                 del self.excludes[self.idx][:]
536                 del self.includes[self.idx][:]
537
538                 # Warning, accessing a ConfigListEntry directly might be considered evil!
539
540                 idx = -1
541                 for item in self["config"].getList():
542                         idx += 1
543                         # Skip empty entries (and those which are no filters)
544                         if item[1].value == "" or idx < 2:
545                                 continue
546                         elif idx < self.lenExcludes:
547                                 self.excludes[self.idx].append(item[1].value.encode("UTF-8"))
548                         else:
549                                 self.includes[self.idx].append(item[1].value.encode("UTF-8"))
550
551         def refresh(self, value):
552                 self.saveCurrent()
553
554                 self.reloadList()
555                 self["config"].setList(self.list)
556
557         def reloadList(self):
558                 self.list = [
559                         getConfigListEntry(_("Enable Filtering"), self.enabled),
560                         getConfigListEntry(_("Filter"), self.typeSelection)
561                 ]
562
563                 if self.typeSelection.value == "day":
564                         self.idx = 3
565
566                         # Weekdays are presented as ConfigSelection
567                         self.list.extend([
568                                 getConfigListEntry(_("Exclude"), ConfigSelection(choices = weekdays, default = x))
569                                         for x in self.excludes[3]
570                         ])
571                         self.lenExcludes = len(self.list)
572                         self.list.extend([
573                                 getConfigListEntry(_("Include"), ConfigSelection(choices = weekdays, default = x))
574                                         for x in self.includes[3]
575                         ])
576                         return
577                 elif self.typeSelection.value == "title":
578                         self.idx = 0
579                 elif self.typeSelection.value == "short":
580                         self.idx = 1
581                 else: # self.typeSelection.value == "desc":
582                         self.idx = 2
583
584                 self.list.extend([
585                         getConfigListEntry(_("Exclude"), ConfigText(default = x, fixed_size = False))
586                                 for x in self.excludes[self.idx]
587                 ])
588                 self.lenExcludes = len(self.list)
589                 self.list.extend([
590                         getConfigListEntry(_("Include"), ConfigText(default = x, fixed_size = False))
591                                 for x in self.includes[self.idx]
592                 ])
593
594         def remove(self):
595                 idx = self["config"].getCurrentIndex()
596                 if idx and idx > 1:
597                         if idx < self.lenExcludes:
598                                 self.lenExcludes -= 1
599
600                         list = self["config"].getList()
601                         list.remove(self["config"].getCurrent())
602                         self["config"].setList(list)
603
604         def new(self):
605                 self.session.openWithCallback(
606                         self.typeSelected,
607                         ChoiceBox,
608                         _("Select type of Filter"),
609                         [
610                                 (_("Exclude"), 0),
611                                 (_("Include"), 1),
612                         ]
613                 )
614
615         def typeSelected(self, ret):
616                 if ret is not None:
617                         list = self["config"].getList()
618
619                         if ret[1] == 0:
620                                 pos = self.lenExcludes
621                                 self.lenExcludes += 1
622                                 text = ret[0]
623                         else:
624                                 pos = len(self.list)
625                                 text = ret[0]
626
627                         if self.typeSelection.value == "day":
628                                 entry = getConfigListEntry(text, ConfigSelection(choices = weekdays))
629                         else:
630                                 entry = getConfigListEntry(text, ConfigText(fixed_size = False))
631
632                         list.insert(pos, entry)
633                         self["config"].setList(list)
634
635         def cancel(self):
636                 if self["config"].isChanged():
637                         self.session.openWithCallback(
638                                 self.cancelConfirm,
639                                 MessageBox,
640                                 _("Really close without saving settings?")
641                         )
642                 else:
643                         self.close(None)
644
645         def cancelConfirm(self, ret):
646                 if ret:
647                         self.close(None)
648
649         def save(self):
650                 self.saveCurrent()
651
652                 self.close((
653                         self.enabled.value,
654                         self.excludes,
655                         self.includes
656                 ))
657
658 class AutoTimerChannelEditor(Screen, ConfigListScreen):
659         """Edit allowed Channels of a AutoTimer"""
660
661         skin = """<screen name="AutoChannelEditor" title="Edit AutoTimer Channels" position="75,150" size="565,245">
662                 <widget name="config" position="5,5" size="555,200" scrollbarMode="showOnDemand" />
663                 <ePixmap position="5,205" zPosition="4" size="140,40" pixmap="skin_default/key-red.png" transparent="1" alphatest="on" />
664                 <ePixmap position="145,205" zPosition="4" size="140,40" pixmap="skin_default/key-green.png" transparent="1" alphatest="on" />
665                 <ePixmap position="285,205" zPosition="4" size="140,40" pixmap="skin_default/key-yellow.png" transparent="1" alphatest="on" />
666                 <ePixmap position="425,205" zPosition="4" size="140,40" pixmap="skin_default/key-blue.png" transparent="1" alphatest="on" />
667                 <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" />
668                 <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" />
669                 <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" />
670                 <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" />
671         </screen>"""
672
673         def __init__(self, session, servicerestriction, servicelist):
674                 Screen.__init__(self, session)
675
676                 # Summary
677                 self.setup_title = "AutoTimer Channels"
678                 self.onChangedEntry = []
679
680                 self.list = [
681                         getConfigListEntry(_("Enable Channel Restriction"), ConfigEnableDisable(default = servicerestriction))
682                 ]
683
684                 self.list.extend([
685                         getConfigListEntry(_("Record on"), ConfigSelection(choices = [(str(x), ServiceReference(str(x)).getServiceName().replace('\xc2\x86', '').replace('\xc2\x87', ''))]))
686                                 for x in servicelist
687                 ])
688
689                 ConfigListScreen.__init__(self, self.list, session = session, on_change = self.changed)
690
691                 # Initialize Buttons
692                 self["key_red"] = Button(_("Cancel"))
693                 self["key_green"] = Button(_("OK"))
694                 self["key_yellow"] = Button(_("delete"))
695                 self["key_blue"] = Button(_("New"))
696
697                 # Define Actions
698                 self["actions"] = ActionMap(["SetupActions", "ColorActions"],
699                         {
700                                 "cancel": self.cancel,
701                                 "save": self.save,
702                                 "yellow": self.removeChannel,
703                                 "blue": self.newChannel
704                         }
705                 )
706
707                 # Trigger change
708                 self.changed()
709
710         def changed(self):
711                 for x in self.onChangedEntry:
712                         try:
713                                 x()
714                         except:
715                                 pass
716
717         def getCurrentEntry(self):
718                 return self["config"].getCurrent()[0]
719
720         def getCurrentValue(self):
721                 return str(self["config"].getCurrent()[1].getText())
722
723         def createSummary(self):
724                 return SetupSummary
725
726         def removeChannel(self):
727                 if self["config"].getCurrentIndex() != 0:
728                         list = self["config"].getList()
729                         list.remove(self["config"].getCurrent())
730                         self["config"].setList(list)
731
732         def newChannel(self):
733                 self.session.openWithCallback(
734                         self.finishedChannelSelection,
735                         SimpleChannelSelection,
736                         _("Select channel to record from")
737                 )
738
739         def finishedChannelSelection(self, *args):
740                 if len(args):
741                         list = self["config"].getList()
742                         sname = args[0].toString()
743
744                         # strip all after last :
745                         pos = sname.rfind(':')
746                         if pos != -1:
747                                 sname = sname[:pos+1]
748
749                         list.append(getConfigListEntry(_("Record on"), ConfigSelection(choices = [(sname, ServiceReference(args[0]).getServiceName().replace('\xc2\x86', '').replace('\xc2\x87', ''))])))
750                         self["config"].setList(list)
751
752         def cancel(self):
753                 if self["config"].isChanged():
754                         self.session.openWithCallback(
755                                 self.cancelConfirm,
756                                 MessageBox,
757                                 _("Really close without saving settings?")
758                         )
759                 else:
760                         self.close(None)
761
762         def cancelConfirm(self, ret):
763                 if ret:
764                         self.close(None)
765
766         def save(self):
767                 list = self["config"].getList()
768                 restriction = list.pop(0)
769
770                 # Warning, accessing a ConfigListEntry directly might be considered evil!
771                 self.close((
772                         restriction[1].value,
773                         [
774                                 x[1].value.encode("UTF-8")
775                                         for x in list
776                         ]
777                 ))
778
779 def addAutotimerFromEvent(session, evt = None, service = None):
780         from AutoTimerComponent import AutoTimerComponent
781
782         name = evt and evt.getEventName() or "New AutoTimer"
783         match = evt and evt.getEventName() or ""
784         servicelist = []
785         if service is not None:
786                 service = str(service)
787                 # strip all after last :
788                 pos = service.rfind(':')
789                 if pos != -1:
790                         service = service[:pos+1]
791
792                 servicelist.append(service)
793         if evt:
794                 begin = evt.getBeginTime()
795                 end = begin + evt.getDuration()
796                 timetuple = (begin-3600, end+3600) # timespan defaults to +- 1h
797         else:
798                 timetuple = None
799
800         session.openWithCallback(
801                 addCallback,
802                 AutoTimerEditor,
803                 AutoTimerComponent(
804                         self.autotimer.getUniqueId(),   # Id
805                         name,                                                   # Name
806                         match,                                                  # Match
807                         True,                                                   # Enabled
808                         timespan = timetuple,
809                         services = servicelist
810                 )
811         )
812
813 def addCallback(ret):
814         if ret:
815                 from plugin import autotimer
816                 
817                 # Create instance if needed
818                 if autotimer is None:
819                         from AutoTimer import AutoTimer
820                         autotimer = AutoTimer()
821
822                 autotimer.add(ret)
823                 
824                 # Remove instance if not running in background
825                 if not config.plugins.autotimer.autopoll.value:
826                         # Save xml
827                         autotimer.writeXml()
828                         autotimer = None