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