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