6 # Coded by Dr.Best (c) 2010
7 # Coding idea and design by Vali
8 # Support: www.dreambox-tools.info
10 # This plugin is licensed under the Creative Commons
11 # Attribution-NonCommercial-ShareAlike 3.0 Unported
12 # License. To view a copy of this license, visit
13 # http://creativecommons.org/licenses/by-nc-sa/3.0/ or send a letter to Creative
14 # Commons, 559 Nathan Abbott Way, Stanford, California 94305, USA.
16 # Alternatively, this plugin may be distributed and executed on hardware which
17 # is licensed by Dream Multimedia GmbH.
19 # This plugin is NOT free software. It is open source, you are allowed to
20 # modify it (if you keep the license), but it may not be commercially
21 # distributed other than under the conditions noted above.
24 from Plugins.Plugin import PluginDescriptor
\r
25 from Screens.Screen import Screen
\r
26 from Components.ActionMap import ActionMap, NumberActionMap
\r
27 from Components.Label import Label
\r
28 from enigma import eServiceReference, eTimer, getDesktop
\r
29 from ServiceReference import ServiceReference
\r
30 from Components.SystemInfo import SystemInfo
31 from enigma import eServiceCenter, getBestPlayableServiceReference
32 from Components.VideoWindow import VideoWindow
33 from enigma import ePoint, eEPGCache
34 from time import localtime, time
35 from Screens.InfoBarGenerics import InfoBarShowHide, NumberZap, InfoBarPiP
36 from Screens.InfoBar import InfoBar
38 from Components.Sources.StaticText import StaticText
39 from Screens.MessageBox import MessageBox
40 from Screens.Standby import TryQuitMainloop
42 from Screens.EpgSelection import EPGSelection
43 from Screens.EventView import EventViewEPGSelect
44 from Screens.PictureInPicture import PictureInPicture
46 InfoBarShowHideINIT = None
48 from Components.config import config, ConfigSubsection, ConfigSelection, ConfigYesNo, getConfigListEntry, configfile, ConfigPosition, ConfigText, ConfigInteger
49 from Components.ConfigList import ConfigList, ConfigListScreen
51 # for localized messages
54 config.plugins.virtualzap = ConfigSubsection()
55 config.plugins.virtualzap.mode = ConfigSelection(default="0", choices = [("0", _("as plugin in extended bar")),("1", _("with long OK press")), ("2", _("with exit button"))])
56 config.plugins.virtualzap.usepip = ConfigYesNo(default = True)
57 config.plugins.virtualzap.showpipininfobar = ConfigYesNo(default = True)
58 config.plugins.virtualzap.saveLastService = ConfigYesNo(default = False)
59 config.plugins.virtualzap.curref = ConfigText()
60 config.plugins.virtualzap.curbouquet = ConfigText()
61 config.plugins.virtualzap.exittimer = ConfigInteger(0,limits = (0, 20))
63 def autostart(reason, **kwargs):
64 if config.plugins.virtualzap.mode.value != "0":
65 # overide InfoBarShowHide
66 global InfoBarShowHideINIT
67 if InfoBarShowHideINIT is None:
68 InfoBarShowHideINIT = InfoBarShowHide.__init__
69 InfoBarShowHide.__init__ = InfoBarShowHide__init__
71 InfoBarShowHide.showVZ = showVZ
72 InfoBarShowHide.VirtualZapCallback = VirtualZapCallback
73 if config.plugins.virtualzap.mode.value == "2":
74 InfoBarShowHide.newHide = newHide
76 def InfoBarShowHide__init__(self):
77 # initialize InfoBarShowHide with original __init__
78 InfoBarShowHideINIT(self)
79 # delete current key map --> we have to use "ok" with b-flag
80 if config.plugins.virtualzap.mode.value == "1":
81 del self["ShowHideActions"]
82 # initialize own actionmap with ok = b and longOK = l
83 self["myactions"] = ActionMap( ["myShowHideActions"] ,
85 "toggleShow": self.toggleShow,
86 "longOK": self.showVZ,
89 elif config.plugins.virtualzap.mode.value == "2":
90 self["ShowHideActions"] = ActionMap( ["InfobarShowHideActions"] ,
92 "toggleShow": self.toggleShow,
98 from Screens.InfoBarGenerics import InfoBarEPG
99 # check for InfoBarEPG --> only start if true
100 if isinstance(self, InfoBarEPG):
102 if isinstance(self, InfoBarPiP):
103 # check if PiP is already shown
107 if isinstance(self, InfoBar):
108 self.session.openWithCallback(self.VirtualZapCallback, VirtualZap, self.servicelist)
110 def VirtualZapCallback(self, service = None, servicePath = None):
111 if isinstance(self, InfoBarPiP):
112 if service and servicePath:
113 self.session.pip = self.session.instantiateDialog(PictureInPicture)
114 self.session.pip.show()
115 if self.session.pip.playService(service):
116 self.session.pipshown = True
117 self.session.pip.servicePath = servicePath
119 self.session.pipshown = False
121 self.session.openWithCallback(self.close, MessageBox, _("Could not open Picture in Picture"), MessageBox.TYPE_ERROR)
124 # remember if infobar is shown
128 # infobar was not shown, start VZ
131 def Plugins(**kwargs):
132 plist = [PluginDescriptor(name="Virtual Zap Setup", description=_("Virtual Zap Setup"), where = [PluginDescriptor.WHERE_PLUGINMENU], icon = "plugin.png", fnc = setup)]
133 if config.plugins.virtualzap.mode.value == "0":
134 plist.append(PluginDescriptor(name="Virtual Zap", description=_("Virtual (PiP) Zap"), where = [PluginDescriptor.WHERE_EXTENSIONSMENU],icon = "plugin.png", fnc = main))
135 elif config.plugins.virtualzap.mode.value == "1" or config.plugins.virtualzap.mode.value == "2":
136 plist.append(PluginDescriptor(where = [PluginDescriptor.WHERE_SESSIONSTART],fnc = autostart))
139 def setup(session,**kwargs):
140 session.open(VirtualZapConfig)
142 def main(session,**kwargs):
143 session.open(VirtualZap, kwargs["servicelist"])
145 class VirtualZap(Screen):
\r
146 sz_w = getDesktop(0).size().width()
149 # VirtualZap or VirtualZapNoPiP
152 if SystemInfo.get("NumVideoDecoders", 1) > 1 and config.plugins.virtualzap.usepip.value and config.plugins.virtualzap.showpipininfobar.value:
156 <screen backgroundColor="#101214" flags="wfNoBorder" name="VirtualZap" position="0,505" size="1280,220" title="Virtual Zap">
157 <ePixmap alphatest="off" pixmap="/usr/lib/enigma2/python/Plugins/Extensions/VirtualZap/hd.png" position="0,0" size="1280,220" zPosition="0"/>
158 <widget backgroundColor="transparent" name="video" position="60,50" size="214,120" zPosition="1"/>
159 <widget backgroundColor="#101214" font="Regular;26" halign="left" name="NowChannel" position="305,60" size="887,32" transparent="1" zPosition="2"/>
160 <widget backgroundColor="#101214" font="Regular;24" foregroundColor="#fcc000" halign="left" name="NowEPG" position="305,105" size="600,28" transparent="1" zPosition="2"/>
161 <widget backgroundColor="#101214" font="Regular;24" halign="left" name="NextEPG" position="305,140" size="600,28" transparent="1" zPosition="2"/>
162 <widget backgroundColor="#101214" font="Regular;24" foregroundColor="#fcc000" halign="right" name="NowTime" position="1070,105" size="124,28" transparent="1" zPosition="2"/>
163 <widget backgroundColor="#101214" font="Regular;24" halign="right" name="NextTime" position="1070,140" size="124,28" transparent="1" zPosition="2"/>
167 <screen backgroundColor="#101214" flags="wfNoBorder" name="VirtualZap" position="0,420" size="1024,176" title="Virtual Zap">
168 <ePixmap alphatest="off" pixmap="/usr/lib/enigma2/python/Plugins/Extensions/VirtualZap/sd.png" position="0,0" size="1024,176" zPosition="0"/>
169 <widget backgroundColor="transparent" name="video" position="50,20" size="164,92" zPosition="1"/>
170 <widget backgroundColor="#101214" font="Regular;22" halign="left" name="NowChannel" position="230,25" size="741,30" transparent="1" zPosition="2"/>
171 <widget backgroundColor="#101214" font="Regular;20" foregroundColor="#fcc000" halign="left" name="NowEPG" position="230,55" size="600,25" transparent="1" zPosition="2"/>
172 <widget backgroundColor="#101214" font="Regular;20" halign="left" name="NextEPG" position="230,80" size="600,25" transparent="1" zPosition="2"/>
173 <widget backgroundColor="#101214" font="Regular;20" foregroundColor="#fcc000" halign="right" name="NowTime" position="850,55" size="124,25" transparent="1" zPosition="2"/>
174 <widget backgroundColor="#101214" font="Regular;20" halign="right" name="NextTime" position="850,80" size="124,25" transparent="1" zPosition="2"/>
178 <screen backgroundColor="#101214" flags="wfNoBorder" name="VirtualZap" position="0,420" size="720,176" title="Virtual Zap">
179 <ePixmap alphatest="off" pixmap="/usr/lib/enigma2/python/Plugins/Extensions/VirtualZap/sd.png" position="0,0" size="720,176" zPosition="0"/>
180 <widget backgroundColor="transparent" name="video" position="50,25" size="130,73" zPosition="1"/>
181 <widget backgroundColor="#101214" font="Regular;22" halign="left" name="NowChannel" position="190,25" size="480,30" transparent="1" zPosition="2"/>
182 <widget backgroundColor="#101214" font="Regular;20" foregroundColor="#fcc000" halign="left" name="NowEPG" position="190,55" size="360,25" transparent="1" zPosition="2"/>
183 <widget backgroundColor="#101214" font="Regular;20" halign="left" name="NextEPG" position="190,80" size="360,25" transparent="1" zPosition="2"/>
184 <widget backgroundColor="#101214" font="Regular;20" foregroundColor="#fcc000" halign="right" name="NowTime" position="550,55" size="120,25" transparent="1" zPosition="2"/>
185 <widget backgroundColor="#101214" font="Regular;20" halign="right" name="NextTime" position="550,80" size="120,25" transparent="1" zPosition="2"/>
189 if SystemInfo.get("NumVideoDecoders", 1) > 1 and config.plugins.virtualzap.usepip.value and not config.plugins.virtualzap.showpipininfobar.value:
191 config.av.pip = ConfigPosition(default=[0, 0, 0, 0], args = (719, 567, 720, 568))
192 x = config.av.pip.value[0]
193 y = config.av.pip.value[1]
194 w = config.av.pip.value[2]
195 h = config.av.pip.value[3]
205 <screen backgroundColor="transparent" flags="wfNoBorder" name="VirtualZapNoPiP" position="0,0" size="1280,720" title="Virtual Zap">
206 <widget backgroundColor="transparent" name="video" position="%d,%d" size="%d,%d" zPosition="1"/>
207 <ePixmap alphatest="off" pixmap="/usr/lib/enigma2/python/Plugins/Extensions/VirtualZap/hd.png" position="0,505" size="1280,220" zPosition="0"/>
208 <widget backgroundColor="#101214" font="Regular;26" halign="center" name="NowChannel" position="140,565" size="1000,32" transparent="1" zPosition="2"/>
209 <widget backgroundColor="#101214" font="Regular;24" foregroundColor="#fcc000" halign="left" name="NowEPG" position="140,610" size="860,28" transparent="1" zPosition="2"/>
210 <widget backgroundColor="#101214" font="Regular;24" halign="left" name="NextEPG" position="140,645" size="860,28" transparent="1" zPosition="2"/>
211 <widget backgroundColor="#101214" font="Regular;24" foregroundColor="#fcc000" halign="right" name="NowTime" position="1015,610" size="124,28" transparent="1" zPosition="2"/>
212 <widget backgroundColor="#101214" font="Regular;24" halign="right" name="NextTime" position="1015,645" size="124,28" transparent="1" zPosition="2"/>
213 </screen>""" % (x,y,w,h)
216 <screen backgroundColor="transparent" flags="wfNoBorder" name="VirtualZapNoPiP" position="0,0" size="1024,576" title="Virtual Zap">
217 <widget backgroundColor="transparent" name="video" position="%d,%d" size="%d,%d" zPosition="1"/>
218 <ePixmap alphatest="off" pixmap="/usr/lib/enigma2/python/Plugins/Extensions/VirtualZap/sd.png" position="0,420" size="1024,176" zPosition="0"/>
219 <widget backgroundColor="#101214" font="Regular;22" halign="center" name="NowChannel" position="100,445" size="824,30" transparent="1" zPosition="2"/>
220 <widget backgroundColor="#101214" font="Regular;20" foregroundColor="#fcc000" halign="left" name="NowEPG" position="100,475" size="700,25" transparent="1" zPosition="2"/>
221 <widget backgroundColor="#101214" font="Regular;20" halign="left" name="NextEPG" position="100,500" size="700,25" transparent="1" zPosition="2"/>
222 <widget backgroundColor="#101214" font="Regular;20" foregroundColor="#fcc000" halign="right" name="NowTime" position="800,475" size="124,25" transparent="1" zPosition="2"/>
223 <widget backgroundColor="#101214" font="Regular;20" halign="right" name="NextTime" position="800,500" size="124,25" transparent="1" zPosition="2"/>
224 </screen>""" % (x,y,w,h)
228 <screen backgroundColor="transparent" flags="wfNoBorder" name="VirtualZapNoPiP" position="0,0" size="720,576" title="Virtual Zap">
229 <widget backgroundColor="transparent" name="video" position="%d,%d" size="%d,%d" zPosition="1"/>
230 <ePixmap alphatest="off" pixmap="/usr/lib/enigma2/python/Plugins/Extensions/VirtualZap/sd.png" position="0,420" size="720,176" zPosition="0"/>
231 <widget backgroundColor="#101214" font="Regular;22" halign="center" name="NowChannel" position="50,445" size="620,30" transparent="1" zPosition="2"/>
232 <widget backgroundColor="#101214" font="Regular;20" foregroundColor="#fcc000" halign="left" name="NowEPG" position="50,475" size="500,25" transparent="1" zPosition="2"/>
233 <widget backgroundColor="#101214" font="Regular;20" halign="left" name="NextEPG" position="50,500" size="500,25" transparent="1" zPosition="2"/>
234 <widget backgroundColor="#101214" font="Regular;20" foregroundColor="#fcc000" halign="right" name="NowTime" position="550,475" size="120,25" transparent="1" zPosition="2"/>
235 <widget backgroundColor="#101214" font="Regular;20" halign="right" name="NextTime" position="550,500" size="120,25" transparent="1" zPosition="2"/>
236 </screen>""" % (x,y,w,h)
238 def __init__(self, session, servicelist = None):
\r
239 Screen.__init__(self, session)
\r
240 self.session = session
241 if SystemInfo.get("NumVideoDecoders", 1) > 1 and config.plugins.virtualzap.usepip.value and config.plugins.virtualzap.showpipininfobar.value:
242 self.skinName = "VirtualZap"
243 self.pipAvailable = True
245 self.skinName = "VirtualZapNoPiP"
246 self.pipAvailable = (SystemInfo.get("NumVideoDecoders", 1) > 1) and config.plugins.virtualzap.usepip.value and not config.plugins.virtualzap.showpipininfobar.value
247 self.epgcache = eEPGCache.getInstance()
\r
248 self.CheckForEPG = eTimer()
\r
249 self.CheckForEPG.callback.append(self.CheckItNow)
\r
250 self["NowChannel"] = Label()
\r
251 self["NowEPG"] = Label()
\r
252 self["NextEPG"] = Label()
253 self["NowTime"] = Label()
\r
254 self["NextTime"] = Label()
\r
255 self["actions"] = ActionMap(["OkCancelActions", "DirectionActions", "ChannelSelectBaseActions", "ChannelSelectEPGActions", "ColorActions"],
258 "cancel": self.closing,
\r
259 "right": self.nextService,
\r
260 "left": self.prevService,
261 "nextBouquet": self.nextBouquet,
262 "prevBouquet": self.prevBouquet,
263 "showEPGList": self.openEventView,
264 "blue": self.standardPiP,
265 "yellow": self.switchAndStandardPiP,
267 self["actions2"] = NumberActionMap(["NumberActions"],
270 "1": self.keyNumberGlobal,
271 "2": self.keyNumberGlobal,
272 "3": self.keyNumberGlobal,
273 "4": self.keyNumberGlobal,
274 "5": self.keyNumberGlobal,
275 "6": self.keyNumberGlobal,
276 "7": self.keyNumberGlobal,
277 "8": self.keyNumberGlobal,
278 "9": self.keyNumberGlobal,
280 self.onLayoutFinish.append(self.onLayoutReady)
282 if self.pipAvailable:
283 # activate PiP support
284 if config.plugins.virtualzap.usepip.value and not config.plugins.virtualzap.showpipininfobar.value:
285 # activate standard PiP
286 self["video"] = VideoWindow()
288 # show PiP in Infobar
289 self["video"] = VideoWindow(fb_width = getDesktop(0).size().width(), fb_height = getDesktop(0).size().height())
293 self["video"] = Label()
294 # this is the servicelist from ChannelSelectionBase
295 self.servicelist = servicelist
296 # needed, because if we won't zap, we have to go back to the current bouquet and service
297 self.curRef = ServiceReference(self.servicelist.getCurrentSelection())
298 self.curBouquet = self.servicelist.getRoot()
299 # start with last used service
300 if config.plugins.virtualzap.saveLastService.value:
301 # get service and bouquet ref
302 ref = eServiceReference(config.plugins.virtualzap.curref.value)
303 bouquet = eServiceReference(config.plugins.virtualzap.curbouquet.value)
304 if ref.valid() and bouquet.valid():
305 # select bouquet and ref in servicelist
306 self.setServicelistSelection(bouquet, ref)
308 self.exitTimer = eTimer()
309 self.exitTimer.timeout.get().append(self.standardPiP)
311 def onLayoutReady(self):
314 def resetExitTimer(self):
315 # if enabled, run exit timer
316 if config.plugins.virtualzap.exittimer.value != 0:
317 if self.exitTimer.isActive():
318 self.exitTimer.stop()
319 self.exitTimer.start(config.plugins.virtualzap.exittimer.value * 1000)
321 def nextService(self):
323 if self.servicelist.inBouquet():
324 prev = self.servicelist.getCurrentSelection()
326 prev = prev.toString()
328 if config.usage.quickzap_bouquet_change.value and self.servicelist.atEnd():
329 self.servicelist.nextBouquet()
331 self.servicelist.moveDown()
332 cur = self.servicelist.getCurrentSelection()
333 if not cur or (not (cur.flags & 64)) or cur.toString() == prev:
336 self.servicelist.moveDown()
337 if self.isPlayable():
342 def prevService(self):
343 # get previous service
344 if self.servicelist.inBouquet():
345 prev = self.servicelist.getCurrentSelection()
347 prev = prev.toString()
349 if config.usage.quickzap_bouquet_change.value:
350 if self.servicelist.atBegin():
351 self.servicelist.prevBouquet()
352 self.servicelist.moveUp()
353 cur = self.servicelist.getCurrentSelection()
354 if not cur or (not (cur.flags & 64)) or cur.toString() == prev:
357 self.servicelist.moveUp()
358 if self.isPlayable():
363 def isPlayable(self):
364 # check if service is playable
365 current = ServiceReference(self.servicelist.getCurrentSelection())
366 return not (current.ref.flags & (eServiceReference.isMarker|eServiceReference.isDirectory))
369 def nextBouquet(self):
370 # next bouquet with first service
371 if config.usage.multibouquet.value:
372 self.servicelist.nextBouquet()
375 def prevBouquet(self):
376 # previous bouquet with first service
377 if config.usage.multibouquet.value:
378 self.servicelist.prevBouquet()
382 def updateInfos(self):
383 self.resetExitTimer()
385 current = ServiceReference(self.servicelist.getCurrentSelection())
386 self["NowChannel"].setText(current.getServiceName())
387 nowepg, nowtimedisplay = self.getEPGNowNext(current.ref,0)
388 nextepg, nexttimedisplay = self.getEPGNowNext(current.ref,1)
389 self["NowEPG"].setText(nowepg)
390 self["NextEPG"].setText(nextepg)
391 self["NowTime"].setText(nowtimedisplay)
392 self["NextTime"].setText(nexttimedisplay)
394 # no epg found --> let's try it again, but only if PiP is activated
395 if self.pipAvailable:
396 self.CheckForEPG.start(3000, True)
397 if self.pipAvailable:
398 # play in videowindow
399 self.playService(current.ref)
401 def getEPGNowNext(self,ref, modus):
402 # get now || next event
403 if self.epgcache is not None:
404 event = self.epgcache.lookupEvent(['IBDCTSERNX', (ref.toString(), modus, -1)])
407 t = localtime(event[0][1])
408 duration = event[0][2]
410 timedisplay = "+%d min" % (((event[0][1] + duration) - time()) / 60)
412 timedisplay = "%d min" % (duration / 60)
413 return "%02d:%02d %s" % (t[3],t[4], event[0][4]), timedisplay
418 def openSingleServiceEPG(self):
420 current = ServiceReference(self.servicelist.getCurrentSelection())
421 self.session.open(EPGSelection, current.ref)
423 def openEventView(self):
425 if self.exitTimer.isActive():
426 self.exitTimer.stop()
429 self.epglist = epglist
430 service = ServiceReference(self.servicelist.getCurrentSelection())
432 evt = self.epgcache.lookupEventTime(ref, -1)
435 evt = self.epgcache.lookupEventTime(ref, -1, 1)
439 self.session.openWithCallback(self.EventViewEPGSelectCallBack, EventViewEPGSelect, epglist[0], service, self.eventViewCallback, self.openSingleServiceEPG, self.openMultiServiceEPG, self.openSimilarList)
441 def EventViewEPGSelectCallBack(self):
442 # if enabled, start ExitTimer
443 self.resetExitTimer()
445 def eventViewCallback(self, setEvent, setService, val):
446 epglist = self.epglist
449 epglist[0] = epglist[1]
453 def openMultiServiceEPG(self):
457 def openSimilarList(self, eventid, refstr):
458 self.session.open(EPGSelection, refstr, None, eventid)
460 def setServicelistSelection(self, bouquet, service):
461 # we need to select the old service with bouquet
462 if self.servicelist.getRoot() != bouquet: #already in correct bouquet?
463 self.servicelist.clearPath()
464 self.servicelist.enterPath(self.servicelist.bouquet_root)
465 self.servicelist.enterPath(bouquet)
466 self.servicelist.setCurrentSelection(service) #select the service in servicelist
469 if self.pipAvailable:
470 self.pipservice = None
471 # save last used service and bouqet ref
472 self.saveLastService(self.servicelist.getCurrentSelection().toString(), self.servicelist.getRoot().toString())
473 # select running service in servicelist again
474 self.setServicelistSelection(self.curBouquet, self.curRef.ref)
478 # we have to close PiP first, otherwise the service-display is freezed
479 if self.pipAvailable:
480 self.pipservice = None
481 # play selected service and close virtualzap
482 self.servicelist.zap()
483 # save last used service and bouqet ref
484 self.saveLastService(self.curRef.ref.toString(), self.curBouquet.toString())
487 def standardPiP(self):
488 if not self.pipAvailable:
491 self.pipservice = None
492 # save current selected service for standard PiP
493 service = ServiceReference(self.servicelist.getCurrentSelection()).ref
494 servicePath = self.servicelist.getCurrentServicePath() # same bug as in channelselection
495 # save last used service and bouqet ref
496 self.saveLastService(self.servicelist.getCurrentSelection().toString(), self.servicelist.getRoot().toString())
497 # select running service in servicelist
498 self.setServicelistSelection(self.curBouquet, self.curRef.ref)
499 # close VZ and start standard PiP
500 self.close(service, servicePath)
502 def switchAndStandardPiP(self):
503 if not self.pipAvailable:
505 self.pipservice = None
506 # save current selected servicePath for standard PiP
507 servicePath = self.servicelist.getCurrentServicePath()
508 # save last used service and bouqet ref
509 self.saveLastService(self.curRef.ref.toString(), self.curBouquet.toString())
510 # play selected service
511 self.servicelist.zap()
512 # close VZ and start standard PiP
513 self.close(self.curRef.ref, servicePath)
515 def saveLastService(self, ref, bouquet):
516 if config.plugins.virtualzap.saveLastService.value:
517 # save last VZ service
518 config.plugins.virtualzap.curref.value = ref
519 config.plugins.virtualzap.curbouquet.value = bouquet
520 config.plugins.virtualzap.save()
522 if self.exitTimer.isActive():
523 self.exitTimer.stop()
525 def CheckItNow(self):
\r
526 self.CheckForEPG.stop()
\r
529 # if available play service in PiP
530 def playService(self, service):
531 if service and (service.flags & eServiceReference.isGroup):
532 ref = getBestPlayableServiceReference(service, eServiceReference())
535 if ref and ref.toString() != self.currentPiP:
536 self.pipservice = eServiceCenter.getInstance().play(ref)
537 if self.pipservice and not self.pipservice.setTarget(1):
538 self.pipservice.start()
539 self.currentPiP = ref.toString()
541 self.pipservice = None
545 # switch with numbers
546 def keyNumberGlobal(self, number):
547 self.session.openWithCallback(self.numberEntered, NumberZap, number)
549 def numberEntered(self, retval):
551 self.zapToNumber(retval)
553 def searchNumberHelper(self, serviceHandler, num, bouquet):
554 servicelist = serviceHandler.list(bouquet)
555 if not servicelist is None:
557 serviceIterator = servicelist.getNext()
558 if not serviceIterator.valid(): #check end of list
560 playable = not (serviceIterator.flags & (eServiceReference.isMarker|eServiceReference.isDirectory))
563 if not num: #found service with searched number ?
564 return serviceIterator, 0
567 def zapToNumber(self, number):
568 bouquet = self.servicelist.bouquet_root
570 serviceHandler = eServiceCenter.getInstance()
571 bouquetlist = serviceHandler.list(bouquet)
572 if not bouquetlist is None:
574 bouquet = bouquetlist.getNext()
575 if not bouquet.valid(): #check end of list
577 if bouquet.flags & eServiceReference.isDirectory:
578 service, number = self.searchNumberHelper(serviceHandler, number, bouquet)
579 if not service is None:
580 self.setServicelistSelection(bouquet, service)
581 # update infos, no matter if service is none or not
584 def swap(self, number):
585 # save old values for selecting it in servicelist after zapping
586 currentRef = self.curRef
587 currentBouquet = self.curBouquet
588 # we have to close PiP first, otherwise the service-display is freezed
589 if self.pipAvailable:
590 self.pipservice = None
591 # zap and set new values for the new reference and bouquet
592 self.servicelist.zap()
593 self.curRef = ServiceReference(self.servicelist.getCurrentSelection())
594 self.curBouquet = self.servicelist.getRoot()
595 # select old values in servicelist
596 self.setServicelistSelection(currentBouquet, currentRef.ref)
597 # play old service in PiP
600 class VirtualZapConfig(Screen, ConfigListScreen):
603 <screen position="center,center" size="560,180" title="Virtual Zap Config" >
604 <ePixmap pixmap="skin_default/buttons/red.png" position="0,0" zPosition="0" size="140,40" transparent="1" alphatest="on" />
605 <ePixmap pixmap="skin_default/buttons/green.png" position="140,0" zPosition="0" size="140,40" transparent="1" alphatest="on" />
606 <ePixmap pixmap="skin_default/buttons/yellow.png" position="280,0" zPosition="0" size="140,40" transparent="1" alphatest="on" />
607 <ePixmap pixmap="skin_default/buttons/blue.png" position="420,0" zPosition="0" size="140,40" transparent="1" alphatest="on" />
608 <widget render="Label" source="key_red" position="0,0" size="140,40" zPosition="5" valign="center" halign="center" backgroundColor="red" font="Regular;21" transparent="1" foregroundColor="white" shadowColor="black" shadowOffset="-1,-1" />
609 <widget render="Label" source="key_green" position="140,0" size="140,40" zPosition="5" valign="center" halign="center" backgroundColor="red" font="Regular;21" transparent="1" foregroundColor="white" shadowColor="black" shadowOffset="-1,-1" />
610 <widget name="config" position="20,50" size="520,330" scrollbarMode="showOnDemand" />
613 def __init__(self, session):
614 Screen.__init__(self, session)
615 self["key_red"] = StaticText(_("Cancel"))
616 self["key_green"] = StaticText(_("OK"))
618 self.list.append(getConfigListEntry(_("Usage"), config.plugins.virtualzap.mode))
619 if SystemInfo.get("NumVideoDecoders", 1) > 1:
620 self.list.append(getConfigListEntry(_("Use PiP"), config.plugins.virtualzap.usepip))
621 self.list.append(getConfigListEntry(_("Show PiP in Infobar"), config.plugins.virtualzap.showpipininfobar))
622 self.list.append(getConfigListEntry(_("Start standard PiP after x secs (0 = disabled)"), config.plugins.virtualzap.exittimer))
623 self.list.append(getConfigListEntry(_("Remember last service"), config.plugins.virtualzap.saveLastService))
624 ConfigListScreen.__init__(self, self.list, session)
625 self["setupActions"] = ActionMap(["SetupActions", "ColorActions"],
627 "green": self.keySave,
628 "cancel": self.keyClose,
632 for x in self["config"].list:
635 restartbox = self.session.openWithCallback(self.restartGUI,MessageBox,_("GUI needs a restart to apply the new settings.\nDo you want to Restart the GUI now?"), MessageBox.TYPE_YESNO)
636 restartbox.setTitle(_("Restart GUI now?"))
640 for x in self["config"].list:
644 def restartGUI(self, answer):
646 self.session.open(TryQuitMainloop, 3)