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
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)
58 def autostart(reason, **kwargs):
59 if config.plugins.virtualzap.mode.value != "0":
60 # overide InfoBarShowHide
61 global InfoBarShowHideINIT
62 if InfoBarShowHideINIT is None:
63 InfoBarShowHideINIT = InfoBarShowHide.__init__
64 InfoBarShowHide.__init__ = InfoBarShowHide__init__
66 InfoBarShowHide.showVZ = showVZ
67 InfoBarShowHide.VirtualZapCallback = VirtualZapCallback
68 if config.plugins.virtualzap.mode.value == "2":
69 InfoBarShowHide.newHide = newHide
71 def InfoBarShowHide__init__(self):
72 # initialize InfoBarShowHide with original __init__
73 InfoBarShowHideINIT(self)
74 # delete current key map --> we have to use "ok" with b-flag
75 if config.plugins.virtualzap.mode.value == "1":
76 del self["ShowHideActions"]
77 # initialize own actionmap with ok = b and longOK = l
78 self["myactions"] = ActionMap( ["myShowHideActions"] ,
80 "toggleShow": self.toggleShow,
81 "longOK": self.showVZ,
84 elif config.plugins.virtualzap.mode.value == "2":
85 self["ShowHideActions"] = ActionMap( ["InfobarShowHideActions"] ,
87 "toggleShow": self.toggleShow,
93 from Screens.InfoBarGenerics import InfoBarEPG
94 # check for InfoBarEPG --> only start if true
95 if isinstance(self, InfoBarEPG):
97 if isinstance(self, InfoBarPiP):
98 # check if PiP is already shown
102 if isinstance(self, InfoBar):
103 self.session.openWithCallback(self.VirtualZapCallback, VirtualZap, self.servicelist)
105 def VirtualZapCallback(self, service = None, servicePath = None):
106 if isinstance(self, InfoBarPiP):
107 if service and servicePath:
108 self.session.pip = self.session.instantiateDialog(PictureInPicture)
109 self.session.pip.show()
110 if self.session.pip.playService(service):
111 self.session.pipshown = True
112 self.session.pip.servicePath = servicePath
114 self.session.pipshown = False
116 self.session.openWithCallback(self.close, MessageBox, _("Could not open Picture in Picture"), MessageBox.TYPE_ERROR)
119 # remember if infobar is shown
123 # infobar was not shown, start VZ
126 def Plugins(**kwargs):
127 plist = [PluginDescriptor(name="Virtual Zap Setup", description=_("Virtual Zap Setup"), where = [PluginDescriptor.WHERE_PLUGINMENU], icon = "plugin.png", fnc = setup)]
128 if config.plugins.virtualzap.mode.value == "0":
129 plist.append(PluginDescriptor(name="Virtual Zap", description=_("Virtual (PiP) Zap"), where = [PluginDescriptor.WHERE_EXTENSIONSMENU],icon = "plugin.png", fnc = main))
130 elif config.plugins.virtualzap.mode.value == "1" or config.plugins.virtualzap.mode.value == "2":
131 plist.append(PluginDescriptor(where = [PluginDescriptor.WHERE_SESSIONSTART],fnc = autostart))
134 def setup(session,**kwargs):
135 session.open(VirtualZapConfig)
137 def main(session,**kwargs):
138 session.open(VirtualZap, kwargs["servicelist"])
140 class VirtualZap(Screen):
\r
141 sz_w = getDesktop(0).size().width()
144 # VirtualZap or VirtualZapNoPiP
147 if SystemInfo.get("NumVideoDecoders", 1) > 1 and config.plugins.virtualzap.usepip.value:
150 <screen backgroundColor="#101214" flags="wfNoBorder" name="VirtualZap" position="0,505" size="1280,220" title="Virtual Zap">
151 <ePixmap alphatest="off" pixmap="/usr/lib/enigma2/python/Plugins/Extensions/VirtualZap/hd.png" position="0,0" size="1280,220" zPosition="0"/>
152 <widget backgroundColor="transparent" name="video" position="60,50" size="214,120" zPosition="1"/>
153 <widget backgroundColor="#101214" font="Regular;26" halign="left" name="NowChannel" position="305,60" size="887,32" transparent="1" zPosition="2"/>
154 <widget backgroundColor="#101214" font="Regular;24" foregroundColor="#fcc000" halign="left" name="NowEPG" position="305,105" size="600,28" transparent="1" zPosition="2"/>
155 <widget backgroundColor="#101214" font="Regular;24" halign="left" name="NextEPG" position="305,140" size="600,28" transparent="1" zPosition="2"/>
156 <widget backgroundColor="#101214" font="Regular;24" foregroundColor="#fcc000" halign="right" name="NowTime" position="1070,105" size="124,28" transparent="1" zPosition="2"/>
157 <widget backgroundColor="#101214" font="Regular;24" halign="right" name="NextTime" position="1070,140" size="124,28" transparent="1" zPosition="2"/>
161 <screen backgroundColor="#101214" flags="wfNoBorder" name="VirtualZap" position="0,420" size="1024,176" title="Virtual Zap">
162 <ePixmap alphatest="off" pixmap="/usr/lib/enigma2/python/Plugins/Extensions/VirtualZap/sd.png" position="0,0" size="1024,176" zPosition="0"/>
163 <widget backgroundColor="transparent" name="video" position="50,20" size="164,92" zPosition="1"/>
164 <widget backgroundColor="#101214" font="Regular;22" halign="left" name="NowChannel" position="230,25" size="741,30" transparent="1" zPosition="2"/>
165 <widget backgroundColor="#101214" font="Regular;20" foregroundColor="#fcc000" halign="left" name="NowEPG" position="230,55" size="600,25" transparent="1" zPosition="2"/>
166 <widget backgroundColor="#101214" font="Regular;20" halign="left" name="NextEPG" position="230,80" size="600,25" transparent="1" zPosition="2"/>
167 <widget backgroundColor="#101214" font="Regular;20" foregroundColor="#fcc000" halign="right" name="NowTime" position="850,55" size="124,25" transparent="1" zPosition="2"/>
168 <widget backgroundColor="#101214" font="Regular;20" halign="right" name="NextTime" position="850,80" size="124,25" transparent="1" zPosition="2"/>
172 <screen backgroundColor="#101214" flags="wfNoBorder" name="VirtualZap" position="0,420" size="720,176" title="Virtual Zap">
173 <ePixmap alphatest="off" pixmap="/usr/lib/enigma2/python/Plugins/Extensions/VirtualZap/sd.png" position="0,0" size="720,176" zPosition="0"/>
174 <widget backgroundColor="transparent" name="video" position="50,25" size="130,73" zPosition="1"/>
175 <widget backgroundColor="#101214" font="Regular;22" halign="left" name="NowChannel" position="190,25" size="480,30" transparent="1" zPosition="2"/>
176 <widget backgroundColor="#101214" font="Regular;20" foregroundColor="#fcc000" halign="left" name="NowEPG" position="190,55" size="360,25" transparent="1" zPosition="2"/>
177 <widget backgroundColor="#101214" font="Regular;20" halign="left" name="NextEPG" position="190,80" size="360,25" transparent="1" zPosition="2"/>
178 <widget backgroundColor="#101214" font="Regular;20" foregroundColor="#fcc000" halign="right" name="NowTime" position="550,55" size="120,25" transparent="1" zPosition="2"/>
179 <widget backgroundColor="#101214" font="Regular;20" halign="right" name="NextTime" position="550,80" size="120,25" transparent="1" zPosition="2"/>
184 <screen backgroundColor="#101214" flags="wfNoBorder" name="VirtualZapNoPiP" position="0,505" size="1280,220" title="Virtual Zap">
185 <ePixmap alphatest="off" pixmap="/usr/lib/enigma2/python/Plugins/Extensions/VirtualZap/hd.png" position="0,0" size="1280,220" zPosition="0"/>
186 <widget backgroundColor="#101214" font="Regular;26" halign="center" name="NowChannel" position="140,60" size="1000,32" transparent="1" zPosition="2"/>
187 <widget backgroundColor="#101214" font="Regular;24" foregroundColor="#fcc000" halign="left" name="NowEPG" position="140,105" size="860,28" transparent="1" zPosition="2"/>
188 <widget backgroundColor="#101214" font="Regular;24" halign="left" name="NextEPG" position="140,140" size="860,28" transparent="1" zPosition="2"/>
189 <widget backgroundColor="#101214" font="Regular;24" foregroundColor="#fcc000" halign="right" name="NowTime" position="1015,105" size="124,28" transparent="1" zPosition="2"/>
190 <widget backgroundColor="#101214" font="Regular;24" halign="right" name="NextTime" position="1015,140" size="124,28" transparent="1" zPosition="2"/>
194 <screen backgroundColor="#101214" flags="wfNoBorder" name="VirtualZapNoPiP" position="0,420" size="1024,176" title="Virtual Zap">
195 <ePixmap alphatest="off" pixmap="/usr/lib/enigma2/python/Plugins/Extensions/VirtualZap/sd.png" position="0,0" size="1024,176" zPosition="0"/>
196 <widget backgroundColor="#101214" font="Regular;22" halign="center" name="NowChannel" position="100,25" size="824,30" transparent="1" zPosition="2"/>
197 <widget backgroundColor="#101214" font="Regular;20" foregroundColor="#fcc000" halign="left" name="NowEPG" position="100,55" size="700,25" transparent="1" zPosition="2"/>
198 <widget backgroundColor="#101214" font="Regular;20" halign="left" name="NextEPG" position="100,80" size="700,25" transparent="1" zPosition="2"/>
199 <widget backgroundColor="#101214" font="Regular;20" foregroundColor="#fcc000" halign="right" name="NowTime" position="800,55" size="124,25" transparent="1" zPosition="2"/>
200 <widget backgroundColor="#101214" font="Regular;20" halign="right" name="NextTime" position="800,80" size="124,25" transparent="1" zPosition="2"/>
204 <screen backgroundColor="#101214" flags="wfNoBorder" name="VirtualZapNoPiP" position="0,420" size="720,176" title="Virtual Zap">
205 <ePixmap alphatest="off" pixmap="/usr/lib/enigma2/python/Plugins/Extensions/VirtualZap/sd.png" position="0,0" size="720,176" zPosition="0"/>
206 <widget backgroundColor="#101214" font="Regular;22" halign="center" name="NowChannel" position="50,25" size="620,30" transparent="1" zPosition="2"/>
207 <widget backgroundColor="#101214" font="Regular;20" foregroundColor="#fcc000" halign="left" name="NowEPG" position="50,55" size="500,25" transparent="1" zPosition="2"/>
208 <widget backgroundColor="#101214" font="Regular;20" halign="left" name="NextEPG" position="50,80" size="500,25" transparent="1" zPosition="2"/>
209 <widget backgroundColor="#101214" font="Regular;20" foregroundColor="#fcc000" halign="right" name="NowTime" position="550,55" size="120,25" transparent="1" zPosition="2"/>
210 <widget backgroundColor="#101214" font="Regular;20" halign="right" name="NextTime" position="550,80" size="120,25" transparent="1" zPosition="2"/>
214 def __init__(self, session, servicelist = None):
\r
215 Screen.__init__(self, session)
\r
216 self.session = session
217 self.pipAvailable = False
218 if SystemInfo.get("NumVideoDecoders", 1) > 1 and config.plugins.virtualzap.usepip.value:
219 self.skinName = "VirtualZap"
220 self.pipAvailable = True
222 self.skinName = "VirtualZapNoPiP"
223 self.epgcache = eEPGCache.getInstance()
\r
224 self.CheckForEPG = eTimer()
\r
225 self.CheckForEPG.callback.append(self.CheckItNow)
\r
226 self["NowChannel"] = Label()
\r
227 self["NowEPG"] = Label()
\r
228 self["NextEPG"] = Label()
229 self["NowTime"] = Label()
\r
230 self["NextTime"] = Label()
\r
231 self["actions"] = ActionMap(["OkCancelActions", "DirectionActions", "ChannelSelectBaseActions", "ChannelSelectEPGActions", "ColorActions"],
234 "cancel": self.closing,
\r
235 "right": self.nextService,
\r
236 "left": self.prevService,
237 "nextBouquet": self.nextBouquet,
238 "prevBouquet": self.prevBouquet,
239 "showEPGList": self.openEventView,
240 "blue": self.standardPiP,
241 "yellow": self.switchAndStandardPiP,
243 self["actions2"] = NumberActionMap(["NumberActions"],
246 "1": self.keyNumberGlobal,
247 "2": self.keyNumberGlobal,
248 "3": self.keyNumberGlobal,
249 "4": self.keyNumberGlobal,
250 "5": self.keyNumberGlobal,
251 "6": self.keyNumberGlobal,
252 "7": self.keyNumberGlobal,
253 "8": self.keyNumberGlobal,
254 "9": self.keyNumberGlobal,
256 self.onLayoutFinish.append(self.onLayoutReady)
258 if self.pipAvailable:
259 # activate PiP support
260 self["video"] = VideoWindow(fb_width = getDesktop(0).size().width(), fb_height = getDesktop(0).size().height())
262 # this is the servicelist from ChannelSelectionBase
263 self.servicelist = servicelist
264 # needed, because if we won't zap, we habe to go back to the current bouquet and service
265 self.curRef = ServiceReference(self.servicelist.getCurrentSelection())
266 self.curBouquet = self.servicelist.getRoot()
268 def onLayoutReady(self):
271 def nextService(self):
273 if self.servicelist.inBouquet():
274 prev = self.servicelist.getCurrentSelection()
276 prev = prev.toString()
278 if config.usage.quickzap_bouquet_change.value and self.servicelist.atEnd():
279 self.servicelist.nextBouquet()
281 self.servicelist.moveDown()
282 cur = self.servicelist.getCurrentSelection()
283 if not cur or (not (cur.flags & 64)) or cur.toString() == prev:
286 self.servicelist.moveDown()
287 if self.isPlayable():
292 def prevService(self):
293 # get previous service
294 if self.servicelist.inBouquet():
295 prev = self.servicelist.getCurrentSelection()
297 prev = prev.toString()
299 if config.usage.quickzap_bouquet_change.value:
300 if self.servicelist.atBegin():
301 self.servicelist.prevBouquet()
302 self.servicelist.moveUp()
303 cur = self.servicelist.getCurrentSelection()
304 if not cur or (not (cur.flags & 64)) or cur.toString() == prev:
307 self.servicelist.moveUp()
308 if self.isPlayable():
313 def isPlayable(self):
314 # check if service is playable
315 current = ServiceReference(self.servicelist.getCurrentSelection())
316 return not (current.ref.flags & (eServiceReference.isMarker|eServiceReference.isDirectory))
319 def nextBouquet(self):
320 # next bouquet with first service
321 if config.usage.multibouquet.value:
322 self.servicelist.nextBouquet()
325 def prevBouquet(self):
326 # previous bouquet with first service
327 if config.usage.multibouquet.value:
328 self.servicelist.prevBouquet()
332 def updateInfos(self):
334 current = ServiceReference(self.servicelist.getCurrentSelection())
335 self["NowChannel"].setText(current.getServiceName())
336 nowepg, nowtimedisplay = self.getEPGNowNext(current.ref,0)
337 nextepg, nexttimedisplay = self.getEPGNowNext(current.ref,1)
338 self["NowEPG"].setText(nowepg)
339 self["NextEPG"].setText(nextepg)
340 self["NowTime"].setText(nowtimedisplay)
341 self["NextTime"].setText(nexttimedisplay)
343 # no epg found --> let's try it again, but only if PiP is activated
344 if self.pipAvailable:
345 self.CheckForEPG.start(3000, True)
346 if self.pipAvailable:
347 # play in videowindow
348 self.playService(current.ref)
350 def getEPGNowNext(self,ref, modus):
351 # get now || next event
352 if self.epgcache is not None:
353 event = self.epgcache.lookupEvent(['IBDCTSERNX', (ref.toString(), modus, -1)])
356 t = localtime(event[0][1])
357 duration = event[0][2]
359 timedisplay = "+%d min" % (((event[0][1] + duration) - time()) / 60)
361 timedisplay = "%d min" % (duration / 60)
362 return "%02d:%02d %s" % (t[3],t[4], event[0][4]), timedisplay
367 def openSingleServiceEPG(self):
369 current = ServiceReference(self.servicelist.getCurrentSelection())
370 self.session.open(EPGSelection, current.ref)
372 def openEventView(self):
375 self.epglist = epglist
376 service = ServiceReference(self.servicelist.getCurrentSelection())
378 evt = self.epgcache.lookupEventTime(ref, -1)
381 evt = self.epgcache.lookupEventTime(ref, -1, 1)
385 self.session.open(EventViewEPGSelect, epglist[0], service, self.eventViewCallback, self.openSingleServiceEPG, self.openMultiServiceEPG, self.openSimilarList)
387 def eventViewCallback(self, setEvent, setService, val):
388 epglist = self.epglist
391 epglist[0] = epglist[1]
395 def openMultiServiceEPG(self):
399 def openSimilarList(self, eventid, refstr):
400 self.session.open(EPGSelection, refstr, None, eventid)
402 def setServicelistSelection(self, bouquet, service):
403 # we need to select the old service with bouquet
404 if self.servicelist.getRoot() != bouquet: #already in correct bouquet?
405 self.servicelist.clearPath()
406 if self.servicelist.bouquet_root != bouquet:
407 self.servicelist.enterPath(self.servicelist.bouquet_root)
408 self.servicelist.enterPath(bouquet)
409 self.servicelist.setCurrentSelection(service) #select the service in servicelist
412 if self.pipAvailable:
413 self.pipservice = None
414 self.setServicelistSelection(self.curBouquet, self.curRef.ref)
418 # we have to close PiP first, otherwise the service-display is freezed
419 if self.pipAvailable:
420 self.pipservice = None
421 # play selected service and close virtualzap
422 self.servicelist.zap()
\r
425 def standardPiP(self):
426 if not self.pipAvailable:
429 self.pipservice = None
430 # save current selected service for standard PiP
431 service = ServiceReference(self.servicelist.getCurrentSelection()).ref
432 servicePath = self.servicelist.getCurrentServicePath() # same bug as in channelselection
433 self.setServicelistSelection(self.curBouquet, self.curRef.ref)
434 # close VZ and start standard PiP
435 self.close(service, servicePath)
437 def switchAndStandardPiP(self):
438 if not self.pipAvailable:
440 self.pipservice = None
441 # save current selected servicePath for standard PiP
442 servicePath = self.servicelist.getCurrentServicePath()
443 # play selected service and close virtualzap
444 self.servicelist.zap()
445 # close VZ and start standard PiP
446 self.close(self.curRef.ref, servicePath)
448 def CheckItNow(self):
\r
449 self.CheckForEPG.stop()
\r
452 # if available play service in PiP
453 def playService(self, service):
454 if service and (service.flags & eServiceReference.isGroup):
455 ref = getBestPlayableServiceReference(service, eServiceReference())
458 if ref and ref.toString() != self.currentPiP:
459 self.pipservice = eServiceCenter.getInstance().play(ref)
460 if self.pipservice and not self.pipservice.setTarget(1):
461 self.pipservice.start()
462 self.currentPiP = ref.toString()
464 self.pipservice = None
468 # switch with numbers
469 def keyNumberGlobal(self, number):
470 self.session.openWithCallback(self.numberEntered, NumberZap, number)
472 def numberEntered(self, retval):
474 self.zapToNumber(retval)
476 def searchNumberHelper(self, serviceHandler, num, bouquet):
477 servicelist = serviceHandler.list(bouquet)
478 if not servicelist is None:
480 serviceIterator = servicelist.getNext()
481 if not serviceIterator.valid(): #check end of list
483 playable = not (serviceIterator.flags & (eServiceReference.isMarker|eServiceReference.isDirectory))
486 if not num: #found service with searched number ?
487 return serviceIterator, 0
490 def zapToNumber(self, number):
491 bouquet = self.servicelist.bouquet_root
493 serviceHandler = eServiceCenter.getInstance()
494 bouquetlist = serviceHandler.list(bouquet)
495 if not bouquetlist is None:
497 bouquet = bouquetlist.getNext()
498 if not bouquet.valid(): #check end of list
500 if bouquet.flags & eServiceReference.isDirectory:
501 service, number = self.searchNumberHelper(serviceHandler, number, bouquet)
502 if not service is None:
503 self.setServicelistSelection(bouquet, service)
504 # update infos, no matter if service is none or not
507 def swap(self, number):
508 # save old values for selecting it in servicelist after zapping
509 currentRef = self.curRef
510 currentBouquet = self.curBouquet
511 # we have to close PiP first, otherwise the service-display is freezed
512 if self.pipAvailable:
513 self.pipservice = None
514 # zap and set new values for the new reference and bouquet
515 self.servicelist.zap()
516 self.curRef = ServiceReference(self.servicelist.getCurrentSelection())
517 self.curBouquet = self.servicelist.getRoot()
518 # select old values in servicelist
519 self.setServicelistSelection(currentBouquet, currentRef.ref)
520 # play old service in PiP
523 class VirtualZapConfig(Screen, ConfigListScreen):
526 <screen position="center,center" size="560,110" title="Virtual Zap Config" >
527 <ePixmap pixmap="skin_default/buttons/red.png" position="0,0" zPosition="0" size="140,40" transparent="1" alphatest="on" />
528 <ePixmap pixmap="skin_default/buttons/green.png" position="140,0" zPosition="0" size="140,40" transparent="1" alphatest="on" />
529 <ePixmap pixmap="skin_default/buttons/yellow.png" position="280,0" zPosition="0" size="140,40" transparent="1" alphatest="on" />
530 <ePixmap pixmap="skin_default/buttons/blue.png" position="420,0" zPosition="0" size="140,40" transparent="1" alphatest="on" />
531 <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" />
532 <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" />
533 <widget name="config" position="20,50" size="520,330" scrollbarMode="showOnDemand" />
536 def __init__(self, session):
537 Screen.__init__(self, session)
538 self["key_red"] = StaticText(_("Cancel"))
539 self["key_green"] = StaticText(_("OK"))
541 self.list.append(getConfigListEntry(_("Usage"), config.plugins.virtualzap.mode))
542 if SystemInfo.get("NumVideoDecoders", 1) > 1:
543 self.list.append(getConfigListEntry(_("Show with PiP"), config.plugins.virtualzap.usepip))
544 ConfigListScreen.__init__(self, self.list, session)
545 self["setupActions"] = ActionMap(["SetupActions", "ColorActions"],
547 "green": self.keySave,
548 "cancel": self.keyClose,
552 for x in self["config"].list:
555 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)
556 restartbox.setTitle(_("Restart GUI now?"))
560 for x in self["config"].list:
564 def restartGUI(self, answer):
566 self.session.open(TryQuitMainloop, 3)