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