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