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