Merge branch 'bug_723_infobarext_pvr'
[vuplus_dvbapp] / lib / python / Screens / TimerEdit.py
1 from Components.ActionMap import ActionMap
2 from Components.Button import Button
3 from Components.config import config
4 from Components.MenuList import MenuList
5 from Components.TimerList import TimerList
6 from Components.TimerSanityCheck import TimerSanityCheck
7 from Components.UsageConfig import preferredTimerPath
8 from RecordTimer import RecordTimerEntry, parseEvent, AFTEREVENT
9 from Screen import Screen
10 from Screens.ChoiceBox import ChoiceBox
11 from Screens.MessageBox import MessageBox
12 from ServiceReference import ServiceReference
13 from TimerEntry import TimerEntry, TimerLog
14 from Tools.BoundFunction import boundFunction
15 from time import time
16
17 class TimerEditList(Screen):
18         EMPTY = 0
19         ENABLE = 1
20         DISABLE = 2
21         CLEANUP = 3
22         DELETE = 4
23         
24         def __init__(self, session):
25                 Screen.__init__(self, session)
26                 
27                 list = [ ]
28                 self.list = list
29                 self.fillTimerList()
30                 
31                 print "EMPTY:",self.EMPTY
32                 print "ENABLE:",self.ENABLE
33                 print "DISABLE:",self.DISABLE
34                 print "CLEANUP:",self.CLEANUP
35                 print "DELETE:",self.DELETE
36
37                 self["timerlist"] = TimerList(list)
38                 
39                 self.key_red_choice = self.EMPTY
40                 self.key_yellow_choice = self.EMPTY
41                 self.key_blue_choice = self.EMPTY
42                 
43                 self["key_red"] = Button(" ")
44                 self["key_green"] = Button(_("Add"))
45                 self["key_yellow"] = Button(" ")
46                 self["key_blue"] = Button(" ")
47
48                 print "key_red_choice:",self.key_red_choice
49
50                 self["actions"] = ActionMap(["OkCancelActions", "DirectionActions", "ShortcutActions", "TimerEditActions"], 
51                         {
52                                 "ok": self.openEdit,
53                                 "cancel": self.leave,
54                                 "green": self.addCurrentTimer,
55                                 "log": self.showLog,
56                                 "left": self.left,
57                                 "right": self.right,
58                                 "up": self.up,
59                                 "down": self.down
60                         }, -1)
61                 self.session.nav.RecordTimer.on_state_change.append(self.onStateChange)
62                 self.onShown.append(self.updateState)
63
64         def up(self):
65                 self["timerlist"].instance.moveSelection(self["timerlist"].instance.moveUp)
66                 self.updateState()
67                 
68         def down(self):
69                 self["timerlist"].instance.moveSelection(self["timerlist"].instance.moveDown)
70                 self.updateState()
71
72         def left(self):
73                 self["timerlist"].instance.moveSelection(self["timerlist"].instance.pageUp)
74                 self.updateState()
75                 
76         def right(self):
77                 self["timerlist"].instance.moveSelection(self["timerlist"].instance.pageDown)
78                 self.updateState()
79                 
80         def toggleDisabledState(self):
81                 cur=self["timerlist"].getCurrent()
82                 if cur:
83                         t = cur
84                         if t.disabled:
85                                 print "try to ENABLE timer"
86                                 t.enable()
87                                 timersanitycheck = TimerSanityCheck(self.session.nav.RecordTimer.timer_list, cur)
88                                 if not timersanitycheck.check():
89                                         t.disable()
90                                         print "Sanity check failed"
91                                         simulTimerList = timersanitycheck.getSimulTimerList()
92                                         if simulTimerList is not None:
93                                                 self.session.openWithCallback(self.finishedEdit, TimerSanityConflict, simulTimerList)
94                                 else:
95                                         print "Sanity check passed"
96                                         if timersanitycheck.doubleCheck():
97                                                 t.disable()
98                         else:
99                                 if t.isRunning():
100                                         if t.repeated:
101                                                 list = (
102                                                         (_("Stop current event but not coming events"), "stoponlycurrent"),
103                                                         (_("Stop current event and disable coming events"), "stopall"),
104                                                         (_("Don't stop current event but disable coming events"), "stoponlycoming")
105                                                 )
106                                                 self.session.openWithCallback(boundFunction(self.runningEventCallback, t), ChoiceBox, title=_("Repeating event currently recording... What do you want to do?"), list = list)
107                                 else:
108                                         t.disable()
109                         self.session.nav.RecordTimer.timeChanged(t)
110                         self.refill()
111                         self.updateState()
112
113         def runningEventCallback(self, t, result):
114                 if result is not None:
115                         if result[1] == "stoponlycurrent" or result[1] == "stopall":
116                                 t.enable()
117                                 t.processRepeated(findRunningEvent = False)
118                                 self.session.nav.RecordTimer.doActivate(t)
119                         if result[1] == "stoponlycoming" or result[1] == "stopall":
120                                 t.disable()
121                         self.session.nav.RecordTimer.timeChanged(t)
122                         self.refill()
123                         self.updateState()
124
125         def removeAction(self, descr):
126                 actions = self["actions"].actions
127                 if descr in actions:
128                         del actions[descr]
129
130         def updateState(self):
131                 cur = self["timerlist"].getCurrent()
132                 if cur:
133                         if self.key_red_choice != self.DELETE:
134                                 self["actions"].actions.update({"red":self.removeTimerQuestion})
135                                 self["key_red"].setText(_("Delete"))
136                                 self.key_red_choice = self.DELETE
137                         
138                         if cur.disabled and (self.key_yellow_choice != self.ENABLE):
139                                 self["actions"].actions.update({"yellow":self.toggleDisabledState})
140                                 self["key_yellow"].setText(_("Enable"))
141                                 self.key_yellow_choice = self.ENABLE
142                         elif cur.isRunning() and not cur.repeated and (self.key_yellow_choice != self.EMPTY):
143                                 self.removeAction("yellow")
144                                 self["key_yellow"].setText(" ")
145                                 self.key_yellow_choice = self.EMPTY
146                         elif ((not cur.isRunning())or cur.repeated ) and (not cur.disabled) and (self.key_yellow_choice != self.DISABLE):
147                                 self["actions"].actions.update({"yellow":self.toggleDisabledState})
148                                 self["key_yellow"].setText(_("Disable"))
149                                 self.key_yellow_choice = self.DISABLE
150                 else:
151                         if self.key_red_choice != self.EMPTY:
152                                 self.removeAction("red")
153                                 self["key_red"].setText(" ")
154                                 self.key_red_choice = self.EMPTY
155                         if self.key_yellow_choice != self.EMPTY:
156                                 self.removeAction("yellow")
157                                 self["key_yellow"].setText(" ")
158                                 self.key_yellow_choice = self.EMPTY
159                 
160                 showCleanup = True
161                 for x in self.list:
162                         if (not x[0].disabled) and (x[1] == True):
163                                 break
164                 else:
165                         showCleanup = False
166                 
167                 if showCleanup and (self.key_blue_choice != self.CLEANUP):
168                         self["actions"].actions.update({"blue":self.cleanupQuestion})
169                         self["key_blue"].setText(_("Cleanup"))
170                         self.key_blue_choice = self.CLEANUP
171                 elif (not showCleanup) and (self.key_blue_choice != self.EMPTY):
172                         self.removeAction("blue")
173                         self["key_blue"].setText(" ")
174                         self.key_blue_choice = self.EMPTY
175
176         def fillTimerList(self):
177                 list = self.list
178                 del list[:]
179                 list.extend([(timer, False) for timer in self.session.nav.RecordTimer.timer_list])
180                 list.extend([(timer, True) for timer in self.session.nav.RecordTimer.processed_timers])
181                 list.sort(key = lambda x: x[0].begin)
182
183         def showLog(self):
184                 cur=self["timerlist"].getCurrent()
185                 if cur:
186                         self.session.openWithCallback(self.finishedEdit, TimerLog, cur)
187
188         def openEdit(self):
189                 cur=self["timerlist"].getCurrent()
190                 if cur:
191                         self.session.openWithCallback(self.finishedEdit, TimerEntry, cur)
192
193         def cleanupQuestion(self):
194                 self.session.openWithCallback(self.cleanupTimer, MessageBox, _("Really delete done timers?"))
195         
196         def cleanupTimer(self, delete):
197                 if delete:
198                         self.session.nav.RecordTimer.cleanup()
199                         self.refill()
200                         self.updateState()
201
202         def removeTimerQuestion(self):
203                 cur = self["timerlist"].getCurrent()
204                 if not cur:
205                         return
206
207                 self.session.openWithCallback(self.removeTimer, MessageBox, _("Do you really want to delete %s?") % (cur.name))
208
209         def removeTimer(self, result):
210                 if not result:
211                         return
212                 list = self["timerlist"]
213                 cur = list.getCurrent()
214                 if cur:
215                         timer = cur
216                         timer.afterEvent = AFTEREVENT.NONE
217                         self.session.nav.RecordTimer.removeEntry(timer)
218                         self.refill()
219                         self.updateState()
220
221         
222         def refill(self):
223                 oldsize = len(self.list)
224                 self.fillTimerList()
225                 lst = self["timerlist"]
226                 newsize = len(self.list)
227                 if oldsize and oldsize != newsize:
228                         idx = lst.getCurrentIndex()
229                         lst.entryRemoved(idx)
230                 else:
231                         lst.invalidate()
232         
233         def addCurrentTimer(self):
234                 event = None
235                 service = self.session.nav.getCurrentService()
236                 if service is not None:
237                         info = service.info()
238                         if info is not None:
239                                 event = info.getEvent(0)
240
241                 # FIXME only works if already playing a service
242                 serviceref = ServiceReference(self.session.nav.getCurrentlyPlayingServiceReference())
243                 
244                 if event is None:       
245                         data = (int(time()), int(time() + 60), "", "", None)
246                 else:
247                         data = parseEvent(event, description = False)
248
249                 self.addTimer(RecordTimerEntry(serviceref, checkOldTimers = True, dirname = preferredTimerPath(), *data))
250                 
251         def addTimer(self, timer):
252                 self.session.openWithCallback(self.finishedAdd, TimerEntry, timer)
253                         
254                 
255         def finishedEdit(self, answer):
256                 print "finished edit"
257                 
258                 if answer[0]:
259                         print "Edited timer"
260                         entry = answer[1]
261                         timersanitycheck = TimerSanityCheck(self.session.nav.RecordTimer.timer_list, entry)
262                         success = False
263                         if not timersanitycheck.check():
264                                 simulTimerList = timersanitycheck.getSimulTimerList()
265                                 if simulTimerList is not None:
266                                         for x in simulTimerList:
267                                                 if x.setAutoincreaseEnd(entry):
268                                                         self.session.nav.RecordTimer.timeChanged(x)
269                                         if not timersanitycheck.check():
270                                                 simulTimerList = timersanitycheck.getSimulTimerList()
271                                                 if simulTimerList is not None:
272                                                         self.session.openWithCallback(self.finishedEdit, TimerSanityConflict, timersanitycheck.getSimulTimerList())
273                                         else:
274                                                 success = True
275                         else:
276                                 success = True
277                         if success:
278                                 print "Sanity check passed"
279                                 self.session.nav.RecordTimer.timeChanged(entry)
280                         
281                         self.fillTimerList()
282                         self.updateState()
283                 else:
284                         print "Timeredit aborted"
285
286         def finishedAdd(self, answer):
287                 print "finished add"
288                 if answer[0]:
289                         entry = answer[1]
290                         simulTimerList = self.session.nav.RecordTimer.record(entry)
291                         if simulTimerList is not None:
292                                 for x in simulTimerList:
293                                         if x.setAutoincreaseEnd(entry):
294                                                 self.session.nav.RecordTimer.timeChanged(x)
295                                 simulTimerList = self.session.nav.RecordTimer.record(entry)
296                                 if simulTimerList is not None:
297                                         self.session.openWithCallback(self.finishSanityCorrection, TimerSanityConflict, simulTimerList)
298                         self.fillTimerList()
299                         self.updateState()
300                 else:
301                         print "Timeredit aborted"
302
303         def finishSanityCorrection(self, answer):
304                 self.finishedAdd(answer)
305
306         def leave(self):
307                 self.session.nav.RecordTimer.on_state_change.remove(self.onStateChange)
308                 self.close()
309
310         def onStateChange(self, entry):
311                 self.refill()
312                 self.updateState()
313
314 class TimerSanityConflict(Screen):
315         EMPTY = 0
316         ENABLE = 1
317         DISABLE = 2
318         EDIT = 3
319         
320         def __init__(self, session, timer):
321                 Screen.__init__(self, session)
322                 self.timer = timer
323                 print "TimerSanityConflict"
324                         
325                 self["timer1"] = TimerList(self.getTimerList(timer[0]))
326                 self.list = []
327                 self.list2 = []
328                 count = 0
329                 for x in timer:
330                         if count != 0:
331                                 self.list.append((_("Conflicting timer") + " " + str(count), x))
332                                 self.list2.append((timer[count], False))
333                         count += 1
334                 if count == 1:
335                         self.list.append((_("Channel not in services list")))
336
337                 self["list"] = MenuList(self.list)
338                 self["timer2"] = TimerList(self.list2)
339
340                 self["key_red"] = Button("Edit")
341                 self["key_green"] = Button(" ")
342                 self["key_yellow"] = Button(" ")
343                 self["key_blue"] = Button(" ")
344
345                 self.key_green_choice = self.EMPTY
346                 self.key_yellow_choice = self.EMPTY
347                 self.key_blue_choice = self.EMPTY
348
349                 self["actions"] = ActionMap(["OkCancelActions", "DirectionActions", "ShortcutActions", "TimerEditActions"], 
350                         {
351                                 "ok": self.leave_ok,
352                                 "cancel": self.leave_cancel,
353                                 "red": self.editTimer1,
354                                 "up": self.up,
355                                 "down": self.down
356                         }, -1)
357                 self.onShown.append(self.updateState)
358
359         def getTimerList(self, timer):
360                 return [(timer, False)]
361
362         def editTimer1(self):
363                 self.session.openWithCallback(self.finishedEdit, TimerEntry, self["timer1"].getCurrent())
364
365         def toggleTimer1(self):
366                 if self.timer[0].disabled:
367                         self.timer[0].disabled = False
368                 else:
369                         if not self.timer[0].isRunning():
370                                 self.timer[0].disabled = True
371                 self.finishedEdit((True, self.timer[0]))
372         
373         def editTimer2(self):
374                 self.session.openWithCallback(self.finishedEdit, TimerEntry, self["timer2"].getCurrent())
375
376         def toggleTimer2(self):
377                 x = self["list"].getSelectedIndex() + 1 # the first is the new timer so we do +1 here
378                 if self.timer[x].disabled:
379                         self.timer[x].disabled = False
380                 elif not self.timer[x].isRunning():
381                                 self.timer[x].disabled = True
382                 self.finishedEdit((True, self.timer[0]))
383         
384         def finishedEdit(self, answer):
385                 self.leave_ok()
386         
387         def leave_ok(self):
388                 self.close((True, self.timer[0]))
389         
390         def leave_cancel(self):
391                 self.close((False, self.timer[0]))
392
393         def up(self):
394                 self["list"].instance.moveSelection(self["list"].instance.moveUp)
395                 self["timer2"].moveToIndex(self["list"].getSelectedIndex())
396                 
397         def down(self):
398                 self["list"].instance.moveSelection(self["list"].instance.moveDown)
399                 self["timer2"].moveToIndex(self["list"].getSelectedIndex())
400
401         def removeAction(self, descr):
402                 actions = self["actions"].actions
403                 if descr in actions:
404                         del actions[descr]
405
406         def updateState(self):
407                 if self.timer[0] is not None:
408                         if self.timer[0].disabled and self.key_green_choice != self.ENABLE:
409                                 self["actions"].actions.update({"green":self.toggleTimer1})
410                                 self["key_green"].setText(_("Enable"))
411                                 self.key_green_choice = self.ENABLE
412                         elif self.timer[0].isRunning() and not self.timer[0].repeated and self.key_green_choice != self.EMPTY:
413                                 self.removeAction("green")
414                                 self["key_green"].setText(" ")
415                                 self.key_green_choice = self.EMPTY
416                         elif (not self.timer[0].isRunning() or self.timer[0].repeated ) and self.key_green_choice != self.DISABLE:
417                                 self["actions"].actions.update({"green":self.toggleTimer1})
418                                 self["key_green"].setText(_("Disable"))
419                                 self.key_green_choice = self.DISABLE
420                 
421                 if len(self.timer) > 1:
422                         x = self["list"].getSelectedIndex()
423                         if self.timer[x] is not None:
424                                 if self.key_yellow_choice == self.EMPTY:
425                                         self["actions"].actions.update({"yellow":self.editTimer2})
426                                         self["key_yellow"].setText(_("Edit"))
427                                         self.key_yellow_choice = self.EDIT
428                                 if self.timer[x].disabled and self.key_blue_choice != self.ENABLE:
429                                         self["actions"].actions.update({"blue":self.toggleTimer2})
430                                         self["key_blue"].setText(_("Enable"))
431                                         self.key_blue_choice = self.ENABLE
432                                 elif self.timer[x].isRunning() and not self.timer[x].repeated and self.key_blue_choice != self.EMPTY:
433                                         self.removeAction("blue")
434                                         self["key_blue"].setText(" ")
435                                         self.key_blue_choice = self.EMPTY
436                                 elif (not self.timer[x].isRunning() or self.timer[x].repeated ) and self.key_blue_choice != self.DISABLE:
437                                         self["actions"].actions.update({"blue":self.toggleTimer2})
438                                         self["key_blue"].setText(_("Disable"))
439                                         self.key_blue_choice = self.DISABLE
440                 else:
441 #FIXME.... this doesnt hide the buttons self.... just the text
442                         if self.key_yellow_choice != self.EMPTY:
443                                 self.removeAction("yellow")
444                                 self["key_yellow"].setText(" ")
445                                 self.key_yellow_choice = self.EMPTY
446                         if self.key_blue_choice != self.EMPTY:
447                                 self.removeAction("blue")
448                                 self["key_blue"].setText(" ")
449                                 self.key_blue_choice = self.EMPTY