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