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