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