Merge branch 'master' of /home/tmbinc/enigma2-git into tmbinc/FixTimingBugs
[enigma2.git] / 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 RecordTimer import RecordTimerEntry, parseEvent, AFTEREVENT
8 from Screen import Screen
9 from Screens.ChoiceBox import ChoiceBox
10 from Screens.MessageBox import MessageBox
11 from ServiceReference import ServiceReference
12 from TimerEntry import TimerEntry, TimerLog
13 from Tools.BoundFunction import boundFunction
14 from time import time
15
16 class TimerEditList(Screen):
17         EMPTY = 0
18         ENABLE = 1
19         DISABLE = 2
20         CLEANUP = 3
21         DELETE = 4
22         
23         def __init__(self, session):
24                 Screen.__init__(self, session)
25                 
26                 list = [ ]
27                 self.list = list
28                 self.fillTimerList()
29                 
30                 print "EMPTY:",self.EMPTY
31                 print "ENABLE:",self.ENABLE
32                 print "DISABLE:",self.DISABLE
33                 print "CLEANUP:",self.CLEANUP
34                 print "DELETE:",self.DELETE
35
36                 self["timerlist"] = TimerList(list)
37                 
38                 self.key_red_choice = self.EMPTY
39                 self.key_yellow_choice = self.EMPTY
40                 self.key_blue_choice = self.EMPTY
41                 
42                 self["key_red"] = Button(" ")
43                 self["key_green"] = Button(_("Add"))
44                 self["key_yellow"] = Button(" ")
45                 self["key_blue"] = Button(" ")
46
47                 print "key_red_choice:",self.key_red_choice
48
49                 self["actions"] = ActionMap(["OkCancelActions", "DirectionActions", "ShortcutActions", "TimerEditActions"], 
50                         {
51                                 "ok": self.openEdit,
52                                 "cancel": self.leave,
53                                 "green": self.addCurrentTimer,
54                                 "log": self.showLog,
55                                 "left": self.left,
56                                 "right": self.right,
57                                 "up": self.up,
58                                 "down": self.down
59                         }, -1)
60                 self.session.nav.RecordTimer.on_state_change.append(self.onStateChange)
61                 self.onShown.append(self.updateState)
62
63         def up(self):
64                 self["timerlist"].instance.moveSelection(self["timerlist"].instance.moveUp)
65                 self.updateState()
66                 
67         def down(self):
68                 self["timerlist"].instance.moveSelection(self["timerlist"].instance.moveDown)
69                 self.updateState()
70
71         def left(self):
72                 self["timerlist"].instance.moveSelection(self["timerlist"].instance.pageUp)
73                 self.updateState()
74                 
75         def right(self):
76                 self["timerlist"].instance.moveSelection(self["timerlist"].instance.pageDown)
77                 self.updateState()
78                 
79         def toggleDisabledState(self):
80                 cur=self["timerlist"].getCurrent()
81                 if cur:
82                         t = cur
83                         if t.disabled:
84                                 print "try to ENABLE timer"
85                                 t.enable()
86                                 timersanitycheck = TimerSanityCheck(self.session.nav.RecordTimer.timer_list, cur)
87                                 if not timersanitycheck.check():
88                                         t.disable()
89                                         print "Sanity check failed"
90                                         self.session.openWithCallback(self.finishedEdit, TimerSanityConflict, timersanitycheck.getSimulTimerList())
91                                 else:
92                                         print "Sanity check passed"
93                                         if timersanitycheck.doubleCheck():
94                                                 t.disable()
95                         else:
96                                 if t.isRunning():
97                                         if t.repeated:
98                                                 list = (
99                                                         (_("Stop current event but not coming events"), "stoponlycurrent"),
100                                                         (_("Stop current event and disable coming events"), "stopall"),
101                                                         (_("Don't stop current event but disable coming events"), "stoponlycoming")
102                                                 )
103                                                 self.session.openWithCallback(boundFunction(self.runningEventCallback, t), ChoiceBox, title=_("Repeating event currently recording... What do you want to do?"), list = list)
104                                 else:
105                                         t.disable()
106                         self.session.nav.RecordTimer.timeChanged(t)
107                         self.refill()
108                         self.updateState()
109
110         def runningEventCallback(self, t, result):
111                 if result is not None:
112                         if result[1] == "stoponlycurrent" or result[1] == "stopall":
113                                 t.enable()
114                                 t.processRepeated(findRunningEvent = False)
115                                 self.session.nav.RecordTimer.doActivate(t)
116                         if result[1] == "stoponlycoming" or result[1] == "stopall":
117                                 t.disable()
118                         self.session.nav.RecordTimer.timeChanged(t)
119                         self.refill()
120                         self.updateState()
121
122         def removeAction(self, descr):
123                 actions = self["actions"].actions
124                 if descr in actions:
125                         del actions[descr]
126
127         def updateState(self):
128                 cur = self["timerlist"].getCurrent()
129                 if cur:
130                         if self.key_red_choice != self.DELETE:
131                                 self["actions"].actions.update({"red":self.removeTimerQuestion})
132                                 self["key_red"].setText(_("Delete"))
133                                 self.key_red_choice = self.DELETE
134                         
135                         if cur.disabled and (self.key_yellow_choice != self.ENABLE):
136                                 self["actions"].actions.update({"yellow":self.toggleDisabledState})
137                                 self["key_yellow"].setText(_("Enable"))
138                                 self.key_yellow_choice = self.ENABLE
139                         elif cur.isRunning() and not cur.repeated and (self.key_yellow_choice != self.EMPTY):
140                                 self.removeAction("yellow")
141                                 self["key_yellow"].setText(" ")
142                                 self.key_yellow_choice = self.EMPTY
143                         elif ((not cur.isRunning())or cur.repeated ) and (not cur.disabled) and (self.key_yellow_choice != self.DISABLE):
144                                 self["actions"].actions.update({"yellow":self.toggleDisabledState})
145                                 self["key_yellow"].setText(_("Disable"))
146                                 self.key_yellow_choice = self.DISABLE
147                 else:
148                         if self.key_red_choice != self.EMPTY:
149                                 self.removeAction("red")
150                                 self["key_red"].setText(" ")
151                                 self.key_red_choice = self.EMPTY
152                         if self.key_yellow_choice != self.EMPTY:
153                                 self.removeAction("yellow")
154                                 self["key_yellow"].setText(" ")
155                                 self.key_yellow_choice = self.EMPTY
156                 
157                 showCleanup = True
158                 for x in self.list:
159                         if (not x[0].disabled) and (x[1] == True):
160                                 break
161                 else:
162                         showCleanup = False
163                 
164                 if showCleanup and (self.key_blue_choice != self.CLEANUP):
165                         self["actions"].actions.update({"blue":self.cleanupQuestion})
166                         self["key_blue"].setText(_("Cleanup"))
167                         self.key_blue_choice = self.CLEANUP
168                 elif (not showCleanup) and (self.key_blue_choice != self.EMPTY):
169                         self.removeAction("blue")
170                         self["key_blue"].setText(" ")
171                         self.key_blue_choice = self.EMPTY
172
173         def fillTimerList(self):
174                 del self.list[:]
175                 
176                 for timer in self.session.nav.RecordTimer.timer_list:
177                         self.list.append((timer, False))
178                 
179                 for timer in self.session.nav.RecordTimer.processed_timers:
180                         self.list.append((timer, True))
181                 self.list.sort(cmp = lambda x, y: x[0].begin < y[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 = config.movielist.last_timer_videodir.value, *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                                 succsess = 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