fix start with blue button if MoviePlayer is working
[enigma2-plugins.git] / merlinepg / src / plugin.py
1 #######################################################################
2 #
3 #    Merlin Programm Guide for Dreambox-Enigma2
4 #    Coded by Vali (c)2010
5 #    Support: www.dreambox-tools.info
6 #
7 #
8 #  This plugin is licensed under the Creative Commons 
9 #  Attribution-NonCommercial-ShareAlike 3.0 Unported License.
10 #  To view a copy of this license, visit http://creativecommons.org/licenses/by-nc-sa/3.0/
11 #  or send a letter to Creative Commons, 559 Nathan Abbott Way, Stanford, California 94305, USA.
12 #
13 #  Alternatively, this plugin may be distributed and executed on hardware which
14 #  is licensed by Dream Multimedia GmbH.
15 #
16 #
17 #  This plugin is NOT free software. It is open source, you are allowed to
18 #  modify it (if you keep the license), but it may not be commercially 
19 #  distributed other than under the conditions noted above.
20 #
21 #
22 #######################################################################
23
24
25
26 from Plugins.Plugin import PluginDescriptor
27 from Screens.Screen import Screen
28 from Screens.EventView import EventViewSimple
29 from Screens.MessageBox import MessageBox
30 from Screens.TimerEntry import TimerEntry
31 from Screens.TimerEdit import TimerSanityConflict
32 from Components.ConfigList import ConfigListScreen
33 from Components.ActionMap import ActionMap
34 from Components.MenuList import MenuList
35 from Components.Label import Label
36 from Components.EpgList import EPGList, EPG_TYPE_SINGLE, Rect
37 from Components.config import config, ConfigSubsection, ConfigYesNo, ConfigInteger, getConfigListEntry
38 from Tools.Directories import resolveFilename, SCOPE_CURRENT_SKIN
39 from Tools.LoadPixmap import LoadPixmap
40 from enigma import eServiceReference, eServiceCenter, getDesktop, eTimer, gFont, eListboxPythonMultiContent, RT_HALIGN_LEFT, RT_WRAP
41 from RecordTimer import RecordTimerEntry, parseEvent, AFTEREVENT
42 from ServiceReference import ServiceReference
43 from ShowMe import ShowMe
44 from time import localtime
45
46
47
48 config.plugins.MerlinEPG = ConfigSubsection()
49 config.plugins.MerlinEPG.Columns = ConfigYesNo(default=True)
50 config.plugins.MerlinEPG.StartFirst = ConfigYesNo(default=False)
51 config.plugins.MerlinEPG.Primetime  = ConfigInteger(default=20, limits=(0, 23))
52 config.plugins.MerlinEPG.PTlow  = ConfigInteger(default=10, limits=(0, 59))
53 config.plugins.MerlinEPG.PThi  = ConfigInteger(default=20, limits=(0, 59))
54 config.plugins.MerlinEPG.AutoPT  = ConfigYesNo(default=False)
55 config.plugins.MerlinEPG.ZapOnOK  = ConfigYesNo(default=False)
56 config.plugins.MerlinEPG.PageUDonBouquets  = ConfigYesNo(default=True)
57
58
59
60 def Plugins(**kwargs):
61         list = [(PluginDescriptor(name="Merlin Programm Guide", description="Merlin Programm Guide", where = PluginDescriptor.WHERE_EVENTINFO, fnc=startMerlinPG))]
62         list.append(PluginDescriptor(name="Merlin Programm Guide", where = PluginDescriptor.WHERE_EXTENSIONSMENU, fnc=startMerlinPGnew))
63         return list
64
65
66
67 def startMerlinPG(session, servicelist, **kwargs):
68         if config.plugins.MerlinEPG.Columns.value:
69                 session.open(Merlin_PGII, servicelist)
70         else:
71                 session.open(Merlin_PGd, servicelist)
72
73
74
75 def startMerlinPGnew(session, **kwargs):
76         if config.plugins.MerlinEPG.Columns.value:
77                 session.open(Merlin_PGII)
78         else:
79                 session.open(Merlin_PGd)
80
81
82
83 class MerlinPGsetup(ConfigListScreen, Screen):
84         skin = """
85                 <screen position="center,center" size="600,300" title="Merlin Programm Guide">
86                         <widget name="config" position="10,10" size="580,280" scrollbarMode="showOnDemand" />
87                 </screen>"""
88
89         def __init__(self, session):
90                 Screen.__init__(self, session)
91                 clist = []
92                 clist.append(getConfigListEntry(_("Show EPG in columns:"), config.plugins.MerlinEPG.Columns))
93                 clist.append(getConfigListEntry(_("Start allways on channel 1:"), config.plugins.MerlinEPG.StartFirst))
94                 clist.append(getConfigListEntry(_("Primetime (h):"), config.plugins.MerlinEPG.Primetime))
95                 clist.append(getConfigListEntry(_("Primetime from (m):"), config.plugins.MerlinEPG.PTlow))
96                 clist.append(getConfigListEntry(_("Primetime to (m):"), config.plugins.MerlinEPG.PThi))
97                 clist.append(getConfigListEntry(_("Auto-Primetime:"), config.plugins.MerlinEPG.AutoPT))
98                 clist.append(getConfigListEntry(_("Zap with OK button (false=EventInfo):"), config.plugins.MerlinEPG.ZapOnOK))
99                 clist.append(getConfigListEntry(_("Page-up/down with bouquet+/- :"), config.plugins.MerlinEPG.PageUDonBouquets))
100                 ConfigListScreen.__init__(self, clist)
101                 self["actions"] = ActionMap(["OkCancelActions"], {"ok": self.set, "cancel": self.exit}, -2)
102
103         def set(self):
104                 if not config.plugins.MerlinEPG.PThi.value > config.plugins.MerlinEPG.PTlow.value:
105                         return
106                 for x in self["config"].list:
107                         x[1].save()
108                 self.close()
109
110         def exit(self):
111                 for x in self["config"].list:
112                         x[1].cancel()
113                 self.close()
114
115
116
117 class MerlinEPGList(EPGList):
118         def __init__(self, type=EPG_TYPE_SINGLE, selChangedCB=None, timer = None):
119                 EPGList.__init__(self, type, selChangedCB, timer)
120                 self.l.setFont(0, gFont("Regular", 18))
121                 self.PTpicture = LoadPixmap(cached=True, path="/usr/lib/enigma2/python/Plugins/Extensions/MerlinEPG/primetime.png")
122                 self.evCnt = 0
123
124         def recalcEntrySize(self):
125                 esize = self.l.getItemSize()
126                 width = esize.width()
127                 height = esize.height()
128                 self.weekday_rect = Rect(120, -10, 200, 20)
129                 self.datetime_rect = Rect(0, 0, 120, 20)
130                 self.descr_rect = Rect(0, 22, width, height-23)
131                 self.evCnt = 0
132
133         def buildSingleEntry(self, service, eventId, beginTime, duration, EventName):
134                 (clock_pic, rec) = self.getPixmapForEntry(service, eventId, beginTime, duration)
135                 r1=self.weekday_rect
136                 r2=self.datetime_rect
137                 r3=self.descr_rect
138                 t = localtime(beginTime)
139                 self.evCnt = self.evCnt + 1
140                 if (t[3]==config.plugins.MerlinEPG.Primetime.value) and (t[4]>=config.plugins.MerlinEPG.PTlow.value) and (t[4]<config.plugins.MerlinEPG.PThi.value):
141                         res = [
142                                 None,
143                                 (eListboxPythonMultiContent.TYPE_TEXT, r1.left(), r1.top(), r1.width(), r1.height(), 0, RT_HALIGN_LEFT, "  _________________"),
144                                 (eListboxPythonMultiContent.TYPE_PIXMAP_ALPHATEST, 100, 1, 21, 21, self.PTpicture),
145                                 (eListboxPythonMultiContent.TYPE_TEXT, r2.left(), r2.top(), r2.width(), r1.height(), 0, RT_HALIGN_LEFT, (("%02d:%02d"%(t[3],t[4]))+" - "+self.days[t[6]]))
146                         ]
147                 else:
148                         res = [
149                                 None,
150                                 (eListboxPythonMultiContent.TYPE_TEXT, r1.left(), r1.top(), r1.width(), r1.height(), 0, RT_HALIGN_LEFT, "___________________"),
151                                 (eListboxPythonMultiContent.TYPE_TEXT, r2.left(), r2.top(), r2.width(), r1.height(), 0, RT_HALIGN_LEFT, (("%02d:%02d"%(t[3],t[4]))+" - "+self.days[t[6]]))
152                         ]
153                 if rec:
154                         res.extend((
155                                 (eListboxPythonMultiContent.TYPE_PIXMAP_ALPHATEST, r3.left(), r3.top(), 21, 21, clock_pic),
156                                 (eListboxPythonMultiContent.TYPE_TEXT, r3.left() + 25, r3.top(), r3.width(), r3.height(), 0, RT_HALIGN_LEFT|RT_WRAP, EventName)
157                         ))
158                 else:
159                         res.append((eListboxPythonMultiContent.TYPE_TEXT, r3.left(), r3.top(), r3.width(), r3.height(), 0, RT_HALIGN_LEFT|RT_WRAP, EventName))
160                 return res
161
162         def getBgTime(self):
163                 tmp = self.l.getCurrentSelection()
164                 if tmp is None:
165                         return ( None )
166                 bt = localtime(tmp[2])
167                 return ( bt[3], bt[4] )
168
169         def foudPrimetime(self):
170                 for OneLine in range(0,self.evCnt):
171                         evBgTime, evBgMin = self.getBgTime()
172                         if evBgTime is not None:
173                                 if (evBgTime==config.plugins.MerlinEPG.Primetime.value) and (evBgMin>=config.plugins.MerlinEPG.PTlow.value) and (evBgMin<config.plugins.MerlinEPG.PThi.value):
174                                         break
175                                 self.moveDown()
176                         else:
177                                 break
178
179
180
181 class Merlin_PGII(Screen):
182         sz_w = getDesktop(0).size().width()
183         if sz_w == 1280:
184                 skin = """
185                 <screen flags="wfNoBorder" name="Merlin_PG" position="0,0" size="1280,720" title="Merlin Program Guide">
186                 <!-- DO NOT CHANGE THIS LINE !!!!!!!!!!!!!!! --><widget enableWrapAround="0" itemHeight="25" name="prg_list" position="-200,-200" size="50,125"/>
187                         <widget font="Regular;18" halign="center" valign="center" name="currCh1" position="60,40" size="231,24" transparent="1" zPosition="2"/>
188                         <widget font="Regular;18" halign="center" valign="center" name="currCh2" position="291,40" size="231,24" transparent="1" zPosition="2"/>
189                         <widget font="Regular;18" halign="center" valign="center" name="currCh3" position="522,40" size="231,24" transparent="1" zPosition="2"/>
190                         <widget font="Regular;18" halign="center" valign="center" name="currCh4" position="753,40" size="231,24" transparent="1" zPosition="2"/>
191                         <widget font="Regular;18" halign="center" valign="center" name="currCh5" position="984,40" size="231,24" transparent="1" zPosition="2"/>
192                         <widget backgroundColor="#10444649" name="Active1" position="60,80" size="225,560" transparent="0" zPosition="3"/>
193                         <widget backgroundColor="#10444649" name="Active2" position="291,80" size="225,560" transparent="0" zPosition="3"/>
194                         <widget backgroundColor="#10444649" name="Active3" position="522,80" size="225,560" transparent="0" zPosition="3"/>
195                         <widget backgroundColor="#10444649" name="Active4" position="753,80" size="225,560" transparent="0" zPosition="3"/>
196                         <widget backgroundColor="#10444649" name="Active5" position="984,80" size="225,560" transparent="0" zPosition="3"/>
197                         <widget itemHeight="70" name="epg_list1" position="60,80" scrollbarMode="showOnDemand" size="225,560" transparent="1" zPosition="4"/>
198                         <widget itemHeight="70" name="epg_list2" position="291,80" scrollbarMode="showOnDemand" size="225,560" transparent="1" zPosition="4"/>
199                         <widget itemHeight="70" name="epg_list3" position="522,80" scrollbarMode="showOnDemand" size="225,560" transparent="1" zPosition="4"/>
200                         <widget itemHeight="70" name="epg_list4" position="753,80" scrollbarMode="showOnDemand" size="225,560" transparent="1" zPosition="4"/>
201                         <widget itemHeight="70" name="epg_list5" position="984,80" scrollbarMode="showOnDemand" size="225,560" transparent="1" zPosition="4"/>
202                         <ePixmap pixmap="/usr/lib/enigma2/python/Plugins/Extensions/MerlinEPG/buttons.png" position="60,655" size="430,24"/>
203                         <widget backgroundColor="background" font="Regular;18" foregroundColor="#ffc000" position="500,655" render="Label" size="200,24" source="global.CurrentTime" transparent="1" valign="center" zPosition="3">     
204                                 <convert type="ClockToText">Format:%H:%M  %a %d. %b</convert>
205                         </widget>
206                 </screen>"""
207         elif sz_w == 1024:
208                 skin = """
209                 <screen flags="wfNoBorder" name="Merlin_PG" position="0,0" size="1024,576" title="Merlin Program Guide">
210                 <!-- DO NOT CHANGE THIS LINE !!!!!!!!!!!!!!! --><widget enableWrapAround="0" itemHeight="25" name="prg_list" position="-200,-200" size="50,100"/>
211                         <widget font="Regular;18" halign="center" valign="center" name="currCh1" position="50,40" size="231,24" transparent="1" zPosition="2"/>
212                         <widget font="Regular;18" halign="center" valign="center" name="currCh2" position="281,40" size="231,24" transparent="1" zPosition="2"/>
213                         <widget font="Regular;18" halign="center" valign="center" name="currCh3" position="512,40" size="231,24" transparent="1" zPosition="2"/>
214                         <widget font="Regular;18" halign="center" valign="center" name="currCh4" position="743,40" size="231,24" transparent="1" zPosition="2"/>
215                         <widget backgroundColor="#10444649" name="Active1" position="50,80" size="225,420" transparent="0" zPosition="3"/>
216                         <widget backgroundColor="#10444649" name="Active2" position="281,80" size="225,420" transparent="0" zPosition="3"/>
217                         <widget backgroundColor="#10444649" name="Active3" position="512,80" size="225,420" transparent="0" zPosition="3"/>
218                         <widget backgroundColor="#10444649" name="Active4" position="743,80" size="225,420" transparent="0" zPosition="3"/>
219                         <widget itemHeight="70" name="epg_list1" position="50,80" scrollbarMode="showOnDemand" size="225,420" transparent="1" zPosition="4"/>
220                         <widget itemHeight="70" name="epg_list2" position="281,80" scrollbarMode="showOnDemand" size="225,420" transparent="1" zPosition="4"/>
221                         <widget itemHeight="70" name="epg_list3" position="512,80" scrollbarMode="showOnDemand" size="225,420" transparent="1" zPosition="4"/>
222                         <widget itemHeight="70" name="epg_list4" position="743,80" scrollbarMode="showOnDemand" size="225,420" transparent="1" zPosition="4"/>
223                         <ePixmap pixmap="/usr/lib/enigma2/python/Plugins/Extensions/MerlinEPG/buttons.png" position="50,518" size="430,24"/>
224                         <widget backgroundColor="background" font="Regular;18" foregroundColor="#ffc000" position="490,518" render="Label" size="200,24" source="global.CurrentTime" transparent="1" valign="center" zPosition="3">     
225                                 <convert type="ClockToText">Format:%H:%M  %a %d. %b</convert>
226                         </widget>
227                         <!-- <widget font="Regular;18" name="fullEventInfo" position="300,200" size="300,200" transparent="0" zPosition="12"/> -->
228                 </screen>"""
229         else:
230                 skin = """
231                 <screen flags="wfNoBorder" name="Merlin_PG" position="0,0" size="720,576" title="Merlin Program Guide">
232                 <!-- DO NOT CHANGE THIS LINE !!!!!!!!!!!!!!! --><widget enableWrapAround="0" itemHeight="25" name="prg_list" position="-200,-200" size="50,100"/>
233                         <widget font="Regular;18" halign="center" valign="center" name="currCh1" position="50,35" size="155,36" transparent="1" zPosition="2"/>
234                         <widget font="Regular;18" halign="center" valign="center" name="currCh2" position="205,35" size="155,36" transparent="1" zPosition="2"/>
235                         <widget font="Regular;18" halign="center" valign="center" name="currCh3" position="360,35" size="155,36" transparent="1" zPosition="2"/>
236                         <widget font="Regular;18" halign="center" valign="center" name="currCh4" position="515,35" size="155,36" transparent="1" zPosition="2"/>
237                         <widget backgroundColor="#10444649" name="Active1" position="50,90" size="155,420" transparent="0" zPosition="3"/>
238                         <widget backgroundColor="#10444649" name="Active2" position="205,90" size="155,420" transparent="0" zPosition="3"/>
239                         <widget backgroundColor="#10444649" name="Active3" position="360,90" size="155,420" transparent="0" zPosition="3"/>
240                         <widget backgroundColor="#10444649" name="Active4" position="515,90" size="155,420" transparent="0" zPosition="3"/>
241                         <widget itemHeight="70" name="epg_list1" position="50,90" scrollbarMode="showOnDemand" size="155,420" transparent="1" zPosition="4"/>
242                         <widget itemHeight="70" name="epg_list2" position="205,90" scrollbarMode="showOnDemand" size="155,420" transparent="1" zPosition="4"/>
243                         <widget itemHeight="70" name="epg_list3" position="360,90" scrollbarMode="showOnDemand" size="155,420" transparent="1" zPosition="4"/>
244                         <widget itemHeight="70" name="epg_list4" position="515,90" scrollbarMode="showOnDemand" size="155,420" transparent="1" zPosition="4"/>
245                         <ePixmap pixmap="/usr/lib/enigma2/python/Plugins/Extensions/MerlinEPG/buttons.png" position="50,518" size="430,24"/>
246                         <widget backgroundColor="background" font="Regular;18" foregroundColor="#ffc000" position="490,518" render="Label" size="200,24" source="global.CurrentTime" transparent="1" valign="center" zPosition="3">     
247                                 <convert type="ClockToText">Format:%H:%M  %a %d. %b</convert>
248                         </widget>
249                 </screen>"""
250
251         def __init__(self, session, servicelist=None):
252                 Screen.__init__(self, session)
253                 self.session = session
254                 self.srvList = servicelist
255                 self.myServices = []
256                 self.myBqts = []
257                 self.list = []
258                 self.chCount = 0
259                 self.ActiveEPG = 1
260                 if getDesktop(0).size().width() == 1280:
261                         self.Fields = 6
262                         self["currCh5"] = Label(" ")
263                         self["Active5"] = Label(" ")
264                         self["epg_list5"] = MerlinEPGList(type = EPG_TYPE_SINGLE, selChangedCB = self.onSelectionChanged, timer = session.nav.RecordTimer)
265                 else:
266                         self.Fields = 5
267                 self.CheckForEPG = eTimer()
268                 self.CheckForEPG.callback.append(self.CheckItNow)
269                 self.AutoPrime = eTimer()
270                 self.AutoPrime.callback.append(self.go2Primetime)
271                 self["prg_list"] = MenuList(self.getChannels())
272                 self["fullEventInfo"] = Label(" ")
273                 self["currCh1"] = Label(" ")
274                 self["currCh2"] = Label(" ")
275                 self["currCh3"] = Label(" ")
276                 self["currCh4"] = Label(" ")
277                 self["Active1"] = Label(" ")
278                 self["Active2"] = Label(" ")
279                 self["Active3"] = Label(" ")
280                 self["Active4"] = Label(" ")
281                 self["epg_list1"] = MerlinEPGList(type = EPG_TYPE_SINGLE, selChangedCB = self.onSelectionChanged, timer = session.nav.RecordTimer)
282                 self["epg_list2"] = MerlinEPGList(type = EPG_TYPE_SINGLE, selChangedCB = self.onSelectionChanged, timer = session.nav.RecordTimer)
283                 self["epg_list3"] = MerlinEPGList(type = EPG_TYPE_SINGLE, selChangedCB = self.onSelectionChanged, timer = session.nav.RecordTimer)
284                 self["epg_list4"] = MerlinEPGList(type = EPG_TYPE_SINGLE, selChangedCB = self.onSelectionChanged, timer = session.nav.RecordTimer)
285                 self["actions"] = ActionMap(["OkCancelActions", "EPGSelectActions", "DirectionActions", "ColorActions", "MenuActions", "NumberActions", "HelpActions"], {
286                                                 "ok": self.UserOK, 
287                                                 "cancel": self.close,
288                                                 "nextBouquet": self.AllUp,
289                                                 "prevBouquet": self.AllDown,
290                                                 "nextService": self.NextPage,
291                                                 "prevService": self.PrevPage,
292                                                 "right": self.right,
293                                                 "rightRepeated": self.right,
294                                                 "left": self.left,
295                                                 "leftRepeated": self.left,
296                                                 "up": self.up,
297                                                 "upRepeated": self.up,
298                                                 "down": self.down,
299                                                 "downRepeated": self.down,
300                                                 "info": self.showEventInfo,
301                                                 "red": self.ZapTo,
302                                                 "green": self.timerAdd,
303                                                 "blue": self.ZapForRefresh,
304                                                 "yellow": self.go2Primetime,
305                                                 "menu": self.menuClicked,
306                                                 "displayHelp": self.myhelp,
307                                                 "0": self.go2now,
308                                                 "1": self.go2first,
309                                                 "7": self.findPrvBqt,
310                                                 "9": self.findNextBqt
311                                                 },-2)
312                 self.onLayoutFinish.append(self.onLayoutReady)
313
314         def getChannels(self):
315                 indx = 0
316                 serviceHandler = eServiceCenter.getInstance()
317                 services = serviceHandler.list(eServiceReference('1:7:1:0:0:0:0:0:0:0:(type == 1) || (type == 17) || (type == 195) || (type == 25) FROM BOUQUET "bouquets.tv" ORDER BY bouquet'))
318                 bouquets = services and services.getContent("SN", True)
319                 for bouquet in bouquets:
320                         services = serviceHandler.list(eServiceReference(bouquet[0]))
321                         channels = services and services.getContent("SN", True)
322                         for channel in channels:
323                                 if not channel[0].startswith("1:64:"):
324                                         indx = indx + 1
325                                         self.list.append(str(indx) + ". " + channel[1].replace('\xc2\x86', '').replace('\xc2\x87', ''))
326                                         self.myServices.append(channel)
327                                         self.myBqts.append(bouquet)
328                 self.chCount = indx - 1
329                 return self.list
330
331         def onLayoutReady(self):
332                 service = self.session.nav.getCurrentService()
333                 info = service and service.info()
334                 if (info is not None) and not(config.plugins.MerlinEPG.StartFirst.value):
335                         nameROH = info.getName().replace('\xc2\x86', '').replace('\xc2\x87', '')
336                         for idx in range(1, len(self.list)):
337                                 name = str(idx) + ". " + nameROH
338                                 if name == self.list[idx-1]:
339                                         break
340                         self["prg_list"].moveToIndex(idx-1)
341                 else:
342                         self["prg_list"].moveToIndex(0)
343                 self.updateInfos()
344
345         def updateInfos(self):
346                 if self.AutoPrime.isActive():
347                         self.AutoPrime.stop()
348                 self.displayActiveEPG()
349                 prgIndex = self["prg_list"].getSelectionIndex()
350                 CurrentPrg = self.myServices[prgIndex]
351                 self["currCh1"].setText(str(CurrentPrg[1]))
352                 l = self["epg_list1"]
353                 l.recalcEntrySize()
354                 myService = ServiceReference(CurrentPrg[0])
355                 l.fillSingleEPG(myService)
356                 prgIndex = prgIndex + 1
357                 if prgIndex < (self.chCount+1):
358                         self["epg_list2"].show()
359                         CurrentPrg = self.myServices[prgIndex]
360                         self["currCh2"].setText(str(CurrentPrg[1]))
361                         l = self["epg_list2"]
362                         l.recalcEntrySize()
363                         myService = ServiceReference(CurrentPrg[0])
364                         l.fillSingleEPG(myService)
365                 else:
366                         self["currCh2"].setText(str(" "))
367                         self["epg_list2"].hide()
368                 prgIndex = prgIndex + 1
369                 if prgIndex < (self.chCount+1):
370                         self["epg_list3"].show()
371                         CurrentPrg = self.myServices[prgIndex]
372                         self["currCh3"].setText(str(CurrentPrg[1]))
373                         l = self["epg_list3"]
374                         l.recalcEntrySize()
375                         myService = ServiceReference(CurrentPrg[0])
376                         l.fillSingleEPG(myService)
377                 else:
378                         self["currCh3"].setText(str(" "))
379                         self["epg_list3"].hide()
380                 prgIndex = prgIndex + 1
381                 if prgIndex < (self.chCount+1):
382                         self["epg_list4"].show()
383                         CurrentPrg = self.myServices[prgIndex]
384                         self["currCh4"].setText(str(CurrentPrg[1]))
385                         CurrentPrg = self.myServices[prgIndex]
386                         self["currCh4"].setText(str(CurrentPrg[1]))
387                         l = self["epg_list4"]
388                         l.recalcEntrySize()
389                         myService = ServiceReference(CurrentPrg[0])
390                         l.fillSingleEPG(myService)
391                 else:
392                         self["currCh4"].setText(str(" "))
393                         self["epg_list4"].hide()
394                 if self.Fields == 6:
395                         prgIndex = prgIndex + 1
396                         if prgIndex < (self.chCount+1):
397                                 self["epg_list5"].show()
398                                 CurrentPrg = self.myServices[prgIndex]
399                                 self["currCh5"].setText(str(CurrentPrg[1]))
400                                 l = self["epg_list5"]
401                                 l.recalcEntrySize()
402                                 myService = ServiceReference(CurrentPrg[0])
403                                 l.fillSingleEPG(myService)
404                         else:
405                                 self["currCh5"].setText(str(" "))
406                                 self["epg_list5"].hide()
407                 if config.plugins.MerlinEPG.AutoPT.value:
408                          self.AutoPrime.start(500)
409
410         def onSelectionChanged(self):           
411                 curEV = self["epg_list"+str(self.ActiveEPG)].getCurrent()
412                 event = curEV[0]
413                 ext = event and event.getExtendedDescription() or ""
414                 self["fullEventInfo"].setText(str(ext))
415
416         def NextPage(self):
417                 self["prg_list"].pageDown()
418                 self.ActiveEPG = 1
419                 self.updateInfos()
420
421         def PrevPage(self):
422                 self["prg_list"].pageUp()
423                 self.ActiveEPG = 1
424                 self.updateInfos()
425
426         def displayActiveEPG(self):
427                 for xA in range(1,self.Fields):
428                         if xA == self.ActiveEPG:
429                                 self["Active"+str(xA)].show()
430                         else:
431                                 self["Active"+str(xA)].hide()
432
433         def getActivePrg(self):
434                 return self["prg_list"].getSelectionIndex()+(self.ActiveEPG-1)
435
436         def ZapTo(self):
437                 if (self.getActivePrg() > self.chCount) or (self.srvList==None):
438                         return
439                 CurrentPrg = self.myServices[self.getActivePrg()]
440                 CurrentBqt = self.myBqts[self.getActivePrg()]
441                 myService = ServiceReference(CurrentPrg[0])
442                 myB = ServiceReference(CurrentBqt[0])
443                 self.srvList.clearPath()
444                 if self.srvList.bouquet_root != myB.ref:
445                         self.srvList.enterPath(self.srvList.bouquet_root)
446                 self.srvList.enterPath(myB.ref)
447                 self.srvList.setCurrentSelection(myService.ref)
448                 self.srvList.zap()
449                 self.close()
450
451         def ZapForRefresh(self):
452                 if (self.getActivePrg() > self.chCount) or (self.srvList==None):
453                         return
454                 CurrentPrg = self.myServices[self.getActivePrg()]
455                 myService = ServiceReference(CurrentPrg[0])
456                 self.session.nav.playService(myService.ref)
457                 self.CheckForEPG.start(4000, True)
458
459         def CheckItNow(self):
460                 self.CheckForEPG.stop()
461                 CurrentPrg = self.myServices[self.getActivePrg()]
462                 l = self["epg_list"+str(self.ActiveEPG)]
463                 l.recalcEntrySize()
464                 myService = ServiceReference(CurrentPrg[0])
465                 l.fillSingleEPG(myService)
466
467         def up(self):
468                 self["epg_list"+str(self.ActiveEPG)].moveUp()
469
470         def down(self):
471                 self["epg_list"+str(self.ActiveEPG)].moveDown()
472
473         def AllUp(self):
474                 if config.plugins.MerlinEPG.PageUDonBouquets.value:
475                         for xU in range(1,self.Fields):
476                                 self["epg_list"+str(xU)].instance.moveSelection(self["epg_list"+str(xU)].instance.pageUp)
477                 else:
478                         for xU in range(1,self.Fields):
479                                 self["epg_list"+str(xU)].moveUp()
480
481         def AllDown(self):
482                 if config.plugins.MerlinEPG.PageUDonBouquets.value:
483                         for xU in range(1,self.Fields):
484                                 self["epg_list"+str(xU)].instance.moveSelection(self["epg_list"+str(xU)].instance.pageDown)
485                 else:
486                         for xD in range(1,self.Fields):
487                                 self["epg_list"+str(xD)].moveDown()
488
489         def go2now(self):
490                 for xD in range(1,self.Fields):
491                         self["epg_list"+str(xD)].instance.moveSelection(self["epg_list"+str(xD)].instance.moveTop)
492
493         def go2first(self):
494                 self["prg_list"].moveToIndex(0)
495                 self.ActiveEPG = 1
496                 self.updateInfos()
497
498         def left(self):
499                 if self.ActiveEPG > 1:
500                         self.ActiveEPG = self.ActiveEPG - 1
501                         self.displayActiveEPG()
502                 else:
503                         self["prg_list"].pageUp()
504                         self.ActiveEPG = (self.Fields-1)
505                         self.updateInfos()
506                 self.onSelectionChanged()
507
508         def right(self):
509                 if self.ActiveEPG < (self.Fields-1):
510                         self.ActiveEPG = self.ActiveEPG + 1
511                         self.displayActiveEPG()
512                 else:
513                         self.NextPage()
514                 self.onSelectionChanged()
515
516         def showEventInfo(self):
517                 curEV = self["epg_list"+str(self.ActiveEPG)].getCurrent()
518                 event = curEV[0]
519                 service = curEV[1]
520                 if event is not None:
521                         self.session.open(EventViewSimple, event, service)
522
523         def timerAdd(self):
524                 cur = self["epg_list"+str(self.ActiveEPG)].getCurrent()
525                 event = cur[0]
526                 serviceref = cur[1]
527                 if event is None:
528                         return
529                 eventid = event.getEventId()
530                 refstr = serviceref.ref.toString()
531                 for timer in self.session.nav.RecordTimer.timer_list:
532                         if timer.eit == eventid and timer.service_ref.ref.toString() == refstr:
533                                 cb_func = lambda ret : not ret or self.removeTimer(timer)
534                                 self.session.openWithCallback(cb_func, MessageBox, _("Do you really want to delete %s?") % event.getEventName())
535                                 break
536                 else:
537                         newEntry = RecordTimerEntry(serviceref, checkOldTimers = True, *parseEvent(event))
538                         self.session.openWithCallback(self.finishedAdd, TimerEntry, newEntry)
539
540         def removeTimer(self, timer):
541                 timer.afterEvent = AFTEREVENT.NONE
542                 self.session.nav.RecordTimer.removeEntry(timer)
543
544         def finishedAdd(self, answer):
545                 if answer[0]:
546                         entry = answer[1]
547                         simulTimerList = self.session.nav.RecordTimer.record(entry)
548                         if simulTimerList is not None:
549                                 for x in simulTimerList:
550                                         if x.setAutoincreaseEnd(entry):
551                                                 self.session.nav.RecordTimer.timeChanged(x)
552                                 simulTimerList = self.session.nav.RecordTimer.record(entry)
553                                 if simulTimerList is not None:
554                                         self.session.openWithCallback(self.finishSanityCorrection, TimerSanityConflict, simulTimerList)
555         
556         def finishSanityCorrection(self, answer):
557                 self.finishedAdd(answer)
558
559         def menuClicked(self):
560                 self.session.open(MerlinPGsetup)
561
562         def findNextBqt(self):
563                 CurrIdx = 0
564                 CurrBqt = self.myBqts[self.getActivePrg()]
565                 for CurrIdx in range(self.getActivePrg(),self.chCount):
566                         NewBqt = self.myBqts[CurrIdx]
567                         if NewBqt != CurrBqt:
568                                 break
569                 self["prg_list"].moveToIndex(CurrIdx)
570                 self.updateInfos()
571
572         def findPrvBqt(self):
573                 CurrIdx = 0
574                 CurrBqt = self.myBqts[self.getActivePrg()]
575                 for CurrIdx in range(self.getActivePrg(),-1,-1):
576                         NewBqt = self.myBqts[CurrIdx]
577                         if NewBqt != CurrBqt:
578                                 break
579                 self["prg_list"].moveToIndex(CurrIdx)
580                 self.updateInfos()
581
582         def go2Primetime(self):
583                 if self.AutoPrime.isActive():
584                         self.AutoPrime.stop()
585                 for xFL in range(1, self.Fields):
586                         self["epg_list"+str(xFL)].instance.moveSelection(self["epg_list"+str(xFL)].instance.moveTop)
587                         for i in range(0,(self.Fields*3)):
588                                 self["epg_list"+str(xFL)].foudPrimetime()
589
590         def myhelp(self):
591                 self.session.open(ShowMe, "/usr/lib/enigma2/python/Plugins/Extensions/MerlinEPG/help.jpg")
592
593         def UserOK(self):
594                 if config.plugins.MerlinEPG.ZapOnOK.value:
595                         self.ZapTo()
596                 else:
597                         self.showEventInfo()
598
599
600
601 class Merlin_PGd(Screen):
602         try:
603                 sz_w = getDesktop(0).size().width()
604         except:
605                 sz_w = 720
606         if sz_w == 1280:
607                 skin = """
608                 <screen backgroundColor="#ffffffff" flags="wfNoBorder" name="Merlin_PG" position="0,0" size="1280,720" title="Merlin Program Guide">
609                         <widget backgroundColor="#ffffffff" position="0,0" render="Pig" size="520,292" source="session.VideoPicture" zPosition="-1"/>
610                         <eLabel backgroundColor="#00111112" position="0,292" size="520,450" zPosition="1"/>
611                         <eLabel backgroundColor="#00111112" position="520,0" size="760,720" zPosition="1"/>
612                         <ePixmap alphatest="on" pixmap="/usr/lib/enigma2/python/Plugins/Extensions/MerlinEPG/epg.png" position="1136,105" size="85,77" zPosition="5"/>
613                         <ePixmap alphatest="on" pixmap="/usr/lib/enigma2/python/Plugins/Extensions/MerlinEPG/channels.png" position="395,306" size="80,80" zPosition="5"/>
614                         <ePixmap alphatest="on" name="red" pixmap="/usr/lib/enigma2/python/Plugins/Extensions/MerlinEPG/red.png" position="70,635" size="35,25" zPosition="2"/>
615                         <ePixmap alphatest="on" name="green" pixmap="/usr/lib/enigma2/python/Plugins/Extensions/MerlinEPG/green.png" position="275,635" size="35,25" zPosition="2"/>
616                         <eLabel backgroundColor="#00111112" font="Regular;18" position="110,635" size="131,24" text="ZAP" transparent="1" zPosition="2"/>
617                         <eLabel backgroundColor="#00111112" font="Regular;18" position="315,635" size="191,24" text="TIMERS" transparent="1" zPosition="2"/>
618                         <widget itemHeight="25" name="prg_list" position="75,306" scrollbarMode="showNever" size="400,300" transparent="1" zPosition="4"/>
619                         <widget itemHeight="27" name="epg_list" position="570,105" scrollbarMode="showNever" size="651,540" transparent="1" zPosition="4"/>
620                         <widget backgroundColor="#00111112" font="Regular;22" foregroundColor="#fcc000" halign="center" name="currCh" position="555,55" size="651,24" transparent="1" valign="center" zPosition="2"/>
621                 </screen>"""
622         elif sz_w == 1024:
623                 skin = """
624                 <screen backgroundColor="#ffffffff" flags="wfNoBorder" name="Merlin_PG" position="0,0" size="1024,576" title="Merlin Program Guide">
625                         <widget backgroundColor="#ffffffff" position="0,0" render="Pig" size="384,216" source="session.VideoPicture" zPosition="-1"/>
626                         <eLabel backgroundColor="#00111112" position="0,216" size="384,366" zPosition="1"/>
627                         <eLabel backgroundColor="#00111112" position="384,0" size="720,576" zPosition="1"/>
628                         <ePixmap alphatest="on" pixmap="/usr/lib/enigma2/python/Plugins/Extensions/MerlinEPG/epg.png" position="900,80" size="85,77" zPosition="5"/>
629                         <ePixmap alphatest="on" pixmap="/usr/lib/enigma2/python/Plugins/Extensions/MerlinEPG/channels.png" position="292,228" size="80,80" zPosition="5"/>
630                         <ePixmap alphatest="on" name="red" pixmap="/usr/lib/enigma2/python/Plugins/Extensions/MerlinEPG/red.png" position="40,520" size="35,25" zPosition="3"/>
631                         <ePixmap alphatest="on" name="green" pixmap="/usr/lib/enigma2/python/Plugins/Extensions/MerlinEPG/green.png" position="185,520" size="35,25" zPosition="3"/>
632                         <eLabel backgroundColor="#00111112" font="Regular;18" position="80,520" size="92,24" text="ZAP" transparent="1" zPosition="2"/>
633                         <eLabel backgroundColor="#00111112" font="Regular;18" position="230,520" size="141,24" text="TIMERS" transparent="1" zPosition="2"/>
634                         <widget itemHeight="25" name="prg_list" position="40,228" scrollbarMode="showNever" size="332,275" transparent="1" zPosition="4"/>
635                         <widget itemHeight="28" name="epg_list" position="395,80" scrollbarMode="showNever" size="590,448" transparent="1" zPosition="4"/>
636                         <widget backgroundColor="#00111112" font="Regular;21" foregroundColor="#fcc000" halign="center" name="currCh" position="395,40" size="590,24" transparent="1" valign="center" zPosition="4"/>
637                 </screen>"""
638         else:
639                 skin = """
640                 <screen flags="wfNoBorder" name="Merlin_PG" position="0,0" size="720,576" title="Merlin Program Guide">
641                         <ePixmap alphatest="on" pixmap="/usr/lib/enigma2/python/Plugins/Extensions/MerlinEPG/mpgbgSD-fs8.png" position="0,0" size="720,576" zPosition="1"/>
642                         <ePixmap alphatest="on" pixmap="/usr/lib/enigma2/python/Plugins/Extensions/MerlinEPG/red.png" position="165,90" size="35,25" zPosition="2"/>
643                         <ePixmap alphatest="on" pixmap="/usr/lib/enigma2/python/Plugins/Extensions/MerlinEPG/green.png" position="165,110" size="35,25" zPosition="2"/>
644                         <eLabel backgroundColor="#1f1f1f" font="Regular;15" foregroundColor="#f0f0f0" position="205,93" size="70,20" text="ZAP" transparent="1" zPosition="2"/>
645                         <eLabel backgroundColor="#1f1f1f" font="Regular;15" foregroundColor="#f0f0f0" position="205,113" size="70,20" text="TIMERS" transparent="1" zPosition="2"/>
646                         <widget name="prg_list" position="342,63" scrollbarMode="showOnDemand" size="327,150" zPosition="2" itemHeight="25"/>
647                         <widget name="epg_list" position="57,238" scrollbarMode="showOnDemand" size="612,270" zPosition="2" itemHeight="27"/>
648                         <widget font="Regular;22" foregroundColor="#ffc000" halign="center" name="currCh" position="57,133" size="252,66" transparent="1" valign="center" zPosition="2"/>
649                         <widget font="LCD;28" halign="left" position="60,95" render="Label" size="91,32" source="global.CurrentTime" transparent="1" zPosition="3">
650                                 <convert type="ClockToText">Default</convert>
651                         </widget>       
652                         <widget font="Regular;16" position="60,65" render="Label" size="276,26" source="global.CurrentTime" transparent="1" zPosition="3">
653                                 <convert type="ClockToText">Date</convert>
654                         </widget>
655                 </screen>"""
656
657         def __init__(self, session, servicelist=None):
658                 Screen.__init__(self, session)
659                 self.session = session
660                 self.myServices = []
661                 self.myBqts = []
662                 self.list = []
663                 self.srvList = servicelist
664                 self.CheckForEPG = eTimer()
665                 self.CheckForEPG.callback.append(self.CheckItNow)
666                 self["currCh"] = Label(_("Channel"))
667                 self["fullEventInfo"] = Label(" ")
668                 self["prg_list"] = MenuList(self.getChannels())
669                 self["epg_list"] = EPGList(type = EPG_TYPE_SINGLE, selChangedCB = self.onSelectionChanged, timer = session.nav.RecordTimer)
670                 self["actions"] = ActionMap(["OkCancelActions", "EPGSelectActions", "ColorActions", "DirectionActions", "MenuActions", "HelpActions"], {
671                                                                         "ok": self.ok, 
672                                                                         "cancel": self.close,
673                                                                         "nextBouquet": self.prgDown,
674                                                                         "prevBouquet": self.prgUp,
675                                                                         "nextService": self.prgPlus,
676                                                                         "prevService": self.prgMinus,
677                                                                         "red": self.ZapTo,
678                                                                         "green": self.timerAdd,
679                                                                         "blue": self.ZapForRefresh,
680                                                                         "yellow": self.go2now,
681                                                                         "info": self.ok,
682                                                                         "menu": self.menuClicked,
683                                                                         "displayHelp": self.myhelp,
684                                                                         "right": self.right,
685                                                                         "rightRepeated": self.right,
686                                                                         "left": self.left,
687                                                                         "leftRepeated": self.left,
688                                                                         "up": self.up,
689                                                                         "upRepeated": self.up,
690                                                                         "down": self.down,
691                                                                         "downRepeated": self.down,
692                                                                         },-2)
693                 self.onLayoutFinish.append(self.onLayoutReady)
694
695         def onLayoutReady(self):
696                 service = self.session.nav.getCurrentService()
697                 info = service and service.info()
698                 if (info is not None) and not(config.plugins.MerlinEPG.StartFirst.value):
699                         nameROH = info.getName().replace('\xc2\x86', '').replace('\xc2\x87', '')
700                         for idx in range(1, len(self.list)):
701                                 name = str(idx) + ". " + nameROH
702                                 if name == self.list[idx-1]:
703                                         break
704                         self["prg_list"].moveToIndex(idx-1)
705                 else:
706                         self["prg_list"].moveToIndex(0)
707                 self.updateInfos()
708
709         def onSelectionChanged(self):
710                 curEV = self["epg_list"].getCurrent()
711                 event = curEV[0]
712                 ext = event and event.getExtendedDescription() or ""
713                 self["fullEventInfo"].setText(str(ext))
714
715         def prgUp(self):
716                 self["prg_list"].down()
717                 self.updateInfos()
718         
719         def prgDown(self):
720                 self["prg_list"].up()
721                 self.updateInfos()
722
723         def prgPlus(self):
724                 self["prg_list"].pageDown()
725                 self.updateInfos()
726
727         def prgMinus(self):
728                 self["prg_list"].pageUp()
729                 self.updateInfos()
730
731         def getChannels(self):
732                 indx = 0
733                 serviceHandler = eServiceCenter.getInstance()
734                 services = serviceHandler.list(eServiceReference('1:7:1:0:0:0:0:0:0:0:(type == 1) || (type == 17) || (type == 195) || (type == 25) FROM BOUQUET "bouquets.tv" ORDER BY bouquet'))
735                 bouquets = services and services.getContent("SN", True)
736                 for bouquet in bouquets:
737                         services = serviceHandler.list(eServiceReference(bouquet[0]))
738                         channels = services and services.getContent("SN", True)
739                         for channel in channels:
740                                 if not channel[0].startswith("1:64:"):
741                                         indx = indx + 1
742                                         self.list.append(str(indx) + ". " + channel[1].replace('\xc2\x86', '').replace('\xc2\x87', ''))
743                                         self.myServices.append(channel)
744                                         self.myBqts.append(bouquet)
745                 return self.list
746
747         def updateInfos(self):
748                 l = self["epg_list"]
749                 l.recalcEntrySize()
750                 CurrentPrg = self.myServices[self["prg_list"].getSelectionIndex()]
751                 self["currCh"].setText(str(CurrentPrg[1]))
752                 myService = ServiceReference(CurrentPrg[0])
753                 l.fillSingleEPG(myService)
754
755         def ok(self):
756                 curEV = self["epg_list"].getCurrent()
757                 event = curEV[0]
758                 service = curEV[1]
759                 if event is not None:
760                         self.session.open(EventViewSimple, event, service)
761                         
762         def ZapTo(self):
763                 if self.srvList==None:
764                         return
765                 CurrentPrg = self.myServices[self["prg_list"].getSelectionIndex()]
766                 CurrentBqt = self.myBqts[self["prg_list"].getSelectionIndex()]
767                 myService = ServiceReference(CurrentPrg[0])
768                 myB = ServiceReference(CurrentBqt[0])
769                 self.srvList.clearPath()
770                 if self.srvList.bouquet_root != myB.ref:
771                         self.srvList.enterPath(self.srvList.bouquet_root)
772                 self.srvList.enterPath(myB.ref)
773                 self.srvList.setCurrentSelection(myService.ref)
774                 self.srvList.zap()
775                 self.close()
776
777         def ZapForRefresh(self):
778                 if self.srvList==None:
779                         return
780                 CurrentPrg = self.myServices[self["prg_list"].getSelectionIndex()]
781                 myService = ServiceReference(CurrentPrg[0])
782                 self.session.nav.playService(myService.ref)
783                 self.CheckForEPG.start(4000, True)
784
785         def CheckItNow(self):
786                 self.CheckForEPG.stop()
787                 self.updateInfos()
788
789         def timerAdd(self):
790                 cur = self["epg_list"].getCurrent()
791                 event = cur[0]
792                 serviceref = cur[1]
793                 if event is None:
794                         return
795                 eventid = event.getEventId()
796                 refstr = serviceref.ref.toString()
797                 for timer in self.session.nav.RecordTimer.timer_list:
798                         if timer.eit == eventid and timer.service_ref.ref.toString() == refstr:
799                                 cb_func = lambda ret : not ret or self.removeTimer(timer)
800                                 self.session.openWithCallback(cb_func, MessageBox, _("Do you really want to delete %s?") % event.getEventName())
801                                 break
802                 else:
803                         newEntry = RecordTimerEntry(serviceref, checkOldTimers = True, *parseEvent(event))
804                         self.session.openWithCallback(self.finishedAdd, TimerEntry, newEntry)
805
806         def removeTimer(self, timer):
807                 timer.afterEvent = AFTEREVENT.NONE
808                 self.session.nav.RecordTimer.removeEntry(timer)
809
810         def finishedAdd(self, answer):
811                 if answer[0]:
812                         entry = answer[1]
813                         simulTimerList = self.session.nav.RecordTimer.record(entry)
814                         if simulTimerList is not None:
815                                 for x in simulTimerList:
816                                         if x.setAutoincreaseEnd(entry):
817                                                 self.session.nav.RecordTimer.timeChanged(x)
818                                 simulTimerList = self.session.nav.RecordTimer.record(entry)
819                                 if simulTimerList is not None:
820                                         self.session.openWithCallback(self.finishSanityCorrection, TimerSanityConflict, simulTimerList)
821
822         def finishSanityCorrection(self, answer):
823                 self.finishedAdd(answer)
824
825         def menuClicked(self):
826                 self.session.open(MerlinPGsetup)
827
828         def go2now(self):
829                 self["epg_list"].instance.moveSelection(self["epg_list"].instance.moveTop)
830
831         def myhelp(self):
832                 self.session.open(ShowMe, "/usr/lib/enigma2/python/Plugins/Extensions/MerlinEPG/help.jpg")
833
834         def up(self):
835                 self["epg_list"].moveUp()
836
837         def down(self):
838                 self["epg_list"].moveDown()
839
840         def left(self):
841                 self["epg_list"].instance.moveSelection(self["epg_list"].instance.pageUp)
842
843         def right(self):
844                 self["epg_list"].instance.moveSelection(self["epg_list"].instance.pageDown)
845
846
847
848
849
850
851