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