Revert "Advanced functions(edit/delete/disable) repeated timers in EPG list"
[openblackhole/openblackhole-enigma2.git] / lib / python / Screens / EpgSelection.py
1 from Screen import Screen
2 import ChannelSelection
3 from Components.config import config, ConfigClock
4 from Components.Button import Button
5 from Components.Pixmap import Pixmap
6 from Components.Label import Label
7 from Components.EpgList import EPGList, EPG_TYPE_SINGLE, EPG_TYPE_SIMILAR, EPG_TYPE_MULTI
8 from Components.ActionMap import ActionMap
9 from Components.TimerSanityCheck import TimerSanityCheck
10 from Components.UsageConfig import preferredTimerPath
11 from Components.Sources.ServiceEvent import ServiceEvent
12 from Components.Sources.Event import Event
13 from Screens.ChoiceBox import ChoiceBox
14 from Screens.TimerEdit import TimerSanityConflict, TimerEditList
15 from Screens.EventView import EventViewSimple
16 from Screens.MessageBox import MessageBox
17 from TimeDateInput import TimeDateInput
18 from enigma import eServiceReference
19 from RecordTimer import RecordTimerEntry, parseEvent, AFTEREVENT
20 from TimerEntry import TimerEntry
21 from ServiceReference import ServiceReference
22 from time import localtime, time
23 from Components.PluginComponent import plugins
24 from Plugins.Plugin import PluginDescriptor
25 from Tools.BoundFunction import boundFunction
26
27 mepg_config_initialized = False
28
29 class EPGSelection(Screen):
30         EMPTY = 0
31         ADD_TIMER = 1
32         REMOVE_TIMER = 2
33
34         ZAP = 1
35
36         def __init__(self, session, service, zapFunc=None, eventid=None, bouquetChangeCB=None, serviceChangeCB=None):
37                 Screen.__init__(self, session)
38                 self.bouquetChangeCB = bouquetChangeCB
39                 self.serviceChangeCB = serviceChangeCB
40                 self.ask_time = -1 #now
41                 self["key_red"] = Button("")
42                 self.closeRecursive = False
43                 self.saved_title = None
44                 self["Service"] = ServiceEvent()
45                 self["Event"] = Event()
46                 self.session = session
47                 if isinstance(service, str) and eventid != None:
48                         self.type = EPG_TYPE_SIMILAR
49                         self["key_yellow"] = Button()
50                         self["key_blue"] = Button()
51                         self["key_red"] = Button()
52                         self.currentService=service
53                         self.eventid = eventid
54                         self.zapFunc = None
55                 elif isinstance(service, eServiceReference) or isinstance(service, str):
56                         self.type = EPG_TYPE_SINGLE
57                         self["key_yellow"] = Button()
58                         self["key_blue"] = Button(_("Select Channel"))
59                         self.currentService=ServiceReference(service)
60                         self.zapFunc = zapFunc
61                         self.sort_type = 0
62                         self.setSortDescription()
63                 else:
64                         self.skinName = "EPGSelectionMulti"
65                         self.type = EPG_TYPE_MULTI
66                         self["key_yellow"] = Button(pgettext("button label, 'previous screen'", "Prev"))
67                         self["key_blue"] = Button(pgettext("button label, 'next screen'", "Next"))
68                         self["now_button"] = Pixmap()
69                         self["next_button"] = Pixmap()
70                         self["more_button"] = Pixmap()
71                         self["now_button_sel"] = Pixmap()
72                         self["next_button_sel"] = Pixmap()
73                         self["more_button_sel"] = Pixmap()
74                         self["now_text"] = Label()
75                         self["next_text"] = Label()
76                         self["more_text"] = Label()
77                         self["date"] = Label()
78                         self.services = service
79                         self.zapFunc = zapFunc
80                 self["key_green"] = Button(_("Add timer"))
81                 self.key_green_choice = self.ADD_TIMER
82                 self.key_red_choice = self.EMPTY
83                 self["list"] = EPGList(type = self.type, selChangedCB = self.onSelectionChanged, timer = session.nav.RecordTimer)
84
85                 self["actions"] = ActionMap(["EPGSelectActions", "OkCancelActions"],
86                         {
87                                 "cancel": self.closeScreen,
88                                 "ok": self.eventSelected,
89                                 "timerAdd": self.timerAdd,
90                                 "yellow": self.yellowButtonPressed,
91                                 "blue": self.blueButtonPressed,
92                                 "info": self.infoKeyPressed,
93                                 "red": self.zapTo,
94                                 "menu": self.furtherOptions,
95                                 "nextBouquet": self.nextBouquet, # just used in multi epg yet
96                                 "prevBouquet": self.prevBouquet, # just used in multi epg yet
97                                 "nextService": self.nextService, # just used in single epg yet
98                                 "prevService": self.prevService, # just used in single epg yet
99                                 "preview": self.eventPreview,
100                         })
101                 self["actions"].csel = self
102                 self.onLayoutFinish.append(self.onCreate)
103
104         def nextBouquet(self):
105                 if self.bouquetChangeCB:
106                         self.bouquetChangeCB(1, self)
107
108         def prevBouquet(self):
109                 if self.bouquetChangeCB:
110                         self.bouquetChangeCB(-1, self)
111
112         def nextService(self):
113                 if self.serviceChangeCB:
114                         self.serviceChangeCB(1, self)
115
116         def prevService(self):
117                 if self.serviceChangeCB:
118                         self.serviceChangeCB(-1, self)
119
120         def enterDateTime(self):
121                 if self.type == EPG_TYPE_MULTI:
122                         global mepg_config_initialized
123                         if not mepg_config_initialized:
124                                 config.misc.prev_mepg_time=ConfigClock(default = time())
125                                 mepg_config_initialized = True
126                         self.session.openWithCallback(self.onDateTimeInputClosed, TimeDateInput, config.misc.prev_mepg_time )
127
128         def furtherOptions(self):
129                 menu = []
130                 text = _("Select action")
131                 event = self["list"].getCurrent()[0]
132                 if event:
133                         menu = [(p.name, boundFunction(self.runPlugin, p)) for p in plugins.getPlugins(where = PluginDescriptor.WHERE_EVENTINFO) \
134                                 if 'selectedevent' in p.__call__.func_code.co_varnames]
135                         if menu:
136                                 text += _(": %s") % event.getEventName()
137                 if self.type == EPG_TYPE_MULTI:
138                         menu.append((_("Goto specific date/time"),self.enterDateTime))
139                 menu.append((_("Timer Overview"), self.openTimerOverview))
140                 if len(menu) == 1:
141                         menu and menu[0][1]()
142                 elif len(menu) > 1:
143                         def boxAction(choice):
144                                 if choice:
145                                         choice[1]()
146                         self.session.openWithCallback(boxAction, ChoiceBox, title=text, list=menu)
147
148         def runPlugin(self, plugin):
149                 event = self["list"].getCurrent()
150                 plugin(session=self.session, selectedevent=event)
151
152         def openTimerOverview(self):
153                 self.session.open(TimerEditList)
154
155         def onDateTimeInputClosed(self, ret):
156                 if len(ret) > 1:
157                         if ret[0]:
158                                 self.ask_time=ret[1]
159                                 self["list"].fillMultiEPG(self.services, ret[1])
160
161         def closeScreen(self):
162                 if self.zapFunc:
163                         self.zapFunc(None, zapback = True)
164                 self.close(self.closeRecursive)
165
166         def infoKeyPressed(self):
167                 cur = self["list"].getCurrent()
168                 event = cur[0]
169                 service = cur[1]
170                 if event is not None:
171                         if self.type != EPG_TYPE_SIMILAR:
172                                 self.session.open(EventViewSimple, event, service, self.eventViewCallback, self.openSimilarList)
173                         else:
174                                 self.session.open(EventViewSimple, event, service, self.eventViewCallback)
175
176         def openSimilarList(self, eventid, refstr):
177                 self.session.open(EPGSelection, refstr, None, eventid)
178
179         def setServices(self, services):
180                 self.services = services
181                 self.onCreate()
182
183         def setService(self, service):
184                 self.currentService = service
185                 self.onCreate()
186
187         #just used in multipeg
188         def onCreate(self):
189                 l = self["list"]
190                 l.recalcEntrySize()
191                 if self.type == EPG_TYPE_MULTI:
192                         l.fillMultiEPG(self.services, self.ask_time)
193                         l.moveToService(self.session.nav.getCurrentlyPlayingServiceOrGroup())
194                 elif self.type == EPG_TYPE_SINGLE:
195                         service = self.currentService
196                         self["Service"].newService(service.ref)
197                         if self.saved_title is None:
198                                 self.saved_title = self.instance.getTitle()
199                         title = self.saved_title + ' - ' + service.getServiceName()
200                         self.instance.setTitle(title)
201                         l.fillSingleEPG(service)
202                 else:
203                         l.fillSimilarList(self.currentService, self.eventid)
204
205         def eventViewCallback(self, setEvent, setService, val):
206                 l = self["list"]
207                 old = l.getCurrent()
208                 if val == -1:
209                         self.moveUp()
210                 elif val == +1:
211                         self.moveDown()
212                 cur = l.getCurrent()
213                 if self.type == EPG_TYPE_MULTI and cur[0] is None and cur[1].ref != old[1].ref:
214                         self.eventViewCallback(setEvent, setService, val)
215                 else:
216                         setService(cur[1])
217                         setEvent(cur[0])
218
219         def zapTo(self):
220                 if self.key_red_choice == self.ZAP and self.zapFunc:
221                         self.closeRecursive = True
222                         from Components.ServiceEventTracker import InfoBarCount
223                         if InfoBarCount > 1:
224                                 self.eventPreview()
225                         else:
226                                 self.zapSelectedService()
227                                 self.close(self.closeRecursive)
228
229         def zapSelectedService(self, prev=False):
230                 lst = self["list"]
231                 count = lst.getCurrentChangeCount()
232                 if count == 0:
233                         ref = lst.getCurrent()[1]
234                         if ref is not None:
235                                 self.zapFunc(ref.ref, preview = prev)
236
237         def eventPreview(self):
238                 if self.zapFunc:
239                         # if enabled, then closed whole EPG with EXIT:
240                         # self.closeRecursive = True
241                         self.zapSelectedService(True)
242
243         def eventSelected(self):
244                 if self.skinName == "EPGSelectionMulti":
245                         cur = self["list"].getCurrent()
246                         event = cur[0]
247                         ref = cur[1] and cur[1].ref.toString()
248                         if ref and event:
249                                 self.session.open(EPGSelection, ref)
250                 else:
251                         self.infoKeyPressed()
252
253         def yellowButtonPressed(self):
254                 if self.type == EPG_TYPE_MULTI:
255                         self["list"].updateMultiEPG(-1)
256                 elif self.type == EPG_TYPE_SINGLE:
257                         if self.sort_type == 0:
258                                 self.sort_type = 1
259                         else:
260                                 self.sort_type = 0
261                         self["list"].sortSingleEPG(self.sort_type)
262                         self.setSortDescription()
263
264         def setSortDescription(self):
265                 if self.sort_type == 1:
266                         # TRANSLATORS: This must fit into the header button in the EPG-List
267                         self["key_yellow"].setText(_("Sort time"))
268                 else:
269                         # TRANSLATORS: This must fit into the header button in the EPG-List
270                         self["key_yellow"].setText(_("Sort A-Z"))
271
272         def blueButtonPressed(self):
273                 if self.type == EPG_TYPE_MULTI:
274                         self["list"].updateMultiEPG(1)
275                 if self.type == EPG_TYPE_SINGLE:
276                         self.session.openWithCallback(self.channelSelectionCallback, ChannelSelection.SimpleChannelSelection, _("Select channel"), currentBouquet=True)
277
278         def channelSelectionCallback(self, *args):
279                 args and self.setService(ServiceReference(args[0]))
280
281         def removeTimer(self, timer):
282                 timer.afterEvent = AFTEREVENT.NONE
283                 self.session.nav.RecordTimer.removeEntry(timer)
284                 self["key_green"].setText(_("Add timer"))
285                 self.key_green_choice = self.ADD_TIMER
286
287         def disableTimer(self, timer):
288                 timer.disable()
289                 self.session.nav.RecordTimer.timeChanged(timer)
290                 self["key_green"].setText(_("Add timer"))
291                 self.key_green_choice = self.ADD_TIMER
292
293         def timerAdd(self):
294                 cur = self["list"].getCurrent()
295                 event = cur[0]
296                 serviceref = cur[1]
297                 if event is None:
298                         return
299                 eventid = event.getEventId()
300                 refstr = ':'.join(serviceref.ref.toString().split(':')[:11])
301                 for timer in self.session.nav.RecordTimer.timer_list:
302                         if timer.eit == eventid and ':'.join(timer.service_ref.ref.toString().split(':')[:11]) == refstr:
303                                 menu = [(_("Delete timer"), "delete"),(_("Edit timer"), "edit")]
304                                 buttons = ["red", "green"]
305                                 if not timer.isRunning():
306                                         menu.append((_("Disable timer"), "disable"))
307                                         buttons.append("yellow")
308                                 menu.append((_("Timer Overview"), "timereditlist"))
309                                 def timerAction(choice):
310                                         if choice is not None:
311                                                 if choice[1] == "delete":
312                                                         self.removeTimer(timer)
313                                                 elif choice[1] == "edit":
314                                                         self.session.open(TimerEntry, timer)
315                                                 elif choice[1] == "disable":
316                                                         self.disableTimer(timer)
317                                                 elif choice[1] == "timereditlist":
318                                                         self.session.open(TimerEditList)
319                                 self.session.openWithCallback(timerAction, ChoiceBox, title=_("Select action for timer %s:") % event.getEventName(), list=menu, keys=buttons)
320                                 break
321                 else:
322                         newEntry = RecordTimerEntry(serviceref, checkOldTimers = True, dirname = preferredTimerPath(), *parseEvent(event))
323                         self.session.openWithCallback(self.finishedAdd, TimerEntry, newEntry)
324
325         def finishedAdd(self, answer):
326                 print "finished add"
327                 if answer[0]:
328                         entry = answer[1]
329                         simulTimerList = self.session.nav.RecordTimer.record(entry)
330                         if simulTimerList is not None:
331                                 for x in simulTimerList:
332                                         if x.setAutoincreaseEnd(entry):
333                                                 self.session.nav.RecordTimer.timeChanged(x)
334                                 simulTimerList = self.session.nav.RecordTimer.record(entry)
335                                 if simulTimerList is not None:
336                                         if not entry.repeated and not config.recording.margin_before.value and not config.recording.margin_after.value and len(simulTimerList) > 1:
337                                                 change_time = False
338                                                 conflict_begin = simulTimerList[1].begin
339                                                 conflict_end = simulTimerList[1].end
340                                                 if conflict_begin == entry.end:
341                                                         entry.end -= 30
342                                                         change_time = True
343                                                 elif entry.begin == conflict_end:
344                                                         entry.begin += 30
345                                                         change_time = True
346                                                 if change_time:
347                                                         simulTimerList = self.session.nav.RecordTimer.record(entry)
348                                         if simulTimerList is not None:
349                                                 self.session.openWithCallback(self.finishSanityCorrection, TimerSanityConflict, simulTimerList)
350                         self["key_green"].setText(_("Change timer"))
351                         self.key_green_choice = self.REMOVE_TIMER
352                 else:
353                         self["key_green"].setText(_("Add timer"))
354                         self.key_green_choice = self.ADD_TIMER
355                         print "Timeredit aborted"
356
357         def finishSanityCorrection(self, answer):
358                 self.finishedAdd(answer)
359
360         def moveUp(self):
361                 self["list"].moveUp()
362
363         def moveDown(self):
364                 self["list"].moveDown()
365
366         def applyButtonState(self, state):
367                 if state == 0:
368                         self["now_button"].hide()
369                         self["now_button_sel"].hide()
370                         self["next_button"].hide()
371                         self["next_button_sel"].hide()
372                         self["more_button"].hide()
373                         self["more_button_sel"].hide()
374                         self["now_text"].hide()
375                         self["next_text"].hide()
376                         self["more_text"].hide()
377                         self["key_red"].setText("")
378                 else:
379                         if state == 1:
380                                 self["now_button_sel"].show()
381                                 self["now_button"].hide()
382                         else:
383                                 self["now_button"].show()
384                                 self["now_button_sel"].hide()
385
386                         if state == 2:
387                                 self["next_button_sel"].show()
388                                 self["next_button"].hide()
389                         else:
390                                 self["next_button"].show()
391                                 self["next_button_sel"].hide()
392
393                         if state == 3:
394                                 self["more_button_sel"].show()
395                                 self["more_button"].hide()
396                         else:
397                                 self["more_button"].show()
398                                 self["more_button_sel"].hide()
399
400         def onSelectionChanged(self):
401                 cur = self["list"].getCurrent()
402                 if cur is None:
403                         if self.key_green_choice != self.EMPTY:
404                                 self["key_green"].setText("")
405                                 self.key_green_choice = self.EMPTY
406                         if self.key_red_choice != self.EMPTY:
407                                 self["key_red"].setText("")
408                                 self.key_red_choice = self.EMPTY
409                         return
410                 event = cur[0]
411                 self["Event"].newEvent(event)
412                 if self.type == EPG_TYPE_MULTI:
413                         count = self["list"].getCurrentChangeCount()
414                         if self.ask_time != -1:
415                                 self.applyButtonState(0)
416                         elif count > 1:
417                                 self.applyButtonState(3)
418                         elif count > 0:
419                                 self.applyButtonState(2)
420                         else:
421                                 self.applyButtonState(1)
422                         days = [ _("Mon"), _("Tue"), _("Wed"), _("Thu"), _("Fri"), _("Sat"), _("Sun") ]
423                         datestr = ""
424                         if event is not None:
425                                 now = time()
426                                 beg = event.getBeginTime()
427                                 nowTime = localtime(now)
428                                 begTime = localtime(beg)
429                                 if nowTime[2] != begTime[2]:
430                                         datestr = '%s %d.%d.'%(days[begTime[6]], begTime[2], begTime[1])
431                                 else:
432                                         datestr = '%s %d.%d.'%(_("Today"), begTime[2], begTime[1])
433                         self["date"].setText(datestr)
434                         if cur[1] is None:
435                                 self["Service"].newService(None)
436                         else:
437                                 self["Service"].newService(cur[1].ref)
438
439                 if cur[1] is None or cur[1].getServiceName() == "":
440                         if self.key_green_choice != self.EMPTY:
441                                 self["key_green"].setText("")
442                                 self.key_green_choice = self.EMPTY
443                         if self.key_red_choice != self.EMPTY:
444                                 self["key_red"].setText("")
445                                 self.key_red_choice = self.EMPTY
446                         return
447                 elif self.key_red_choice != self.ZAP and self.zapFunc is not None:
448                                 self["key_red"].setText(_("Zap"))
449                                 self.key_red_choice = self.ZAP
450
451                 if event is None:
452                         if self.key_green_choice != self.EMPTY:
453                                 self["key_green"].setText("")
454                                 self.key_green_choice = self.EMPTY
455                         return
456
457                 serviceref = cur[1]
458                 eventid = event.getEventId()
459                 refstr = ':'.join(serviceref.ref.toString().split(':')[:11])
460                 isRecordEvent = False
461                 for timer in self.session.nav.RecordTimer.timer_list:
462                         if timer.eit == eventid and ':'.join(timer.service_ref.ref.toString().split(':')[:11]) == refstr:
463                                 isRecordEvent = True
464                                 break
465                 if isRecordEvent and self.key_green_choice != self.REMOVE_TIMER:
466                         self["key_green"].setText(_("Change timer"))
467                         self.key_green_choice = self.REMOVE_TIMER
468                 elif not isRecordEvent and self.key_green_choice != self.ADD_TIMER:
469                         self["key_green"].setText(_("Add timer"))
470                         self.key_green_choice = self.ADD_TIMER