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