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