2 from Screens.Screen import Screen
3 from Screens.MessageBox import MessageBox
4 from Components.ActionMap import ActionMap
5 from Components.Label import Label
6 from Components.Input import Input
7 from Components.GUIComponent import *
8 from Components.Pixmap import Pixmap
9 from Components.MenuList import MenuList
10 from Components.FileList import FileEntryComponent, FileList
11 from Navigation import Navigation
12 import NavigationInstance
13 from Screens.ChannelSelection import SimpleChannelSelection
14 from ServiceReference import ServiceReference
15 from Plugins.Plugin import PluginDescriptor
16 from Tools.Directories import resolveFilename, SCOPE_CONFIG
17 import xml.dom.minidom
18 from Tools.XMLTools import elementsWithTag
24 def addAlternative(service1, service2):
25 if not alternatives.has_key(service1):
26 alternatives[service1] = []
27 alternatives[service1].append(service2)
28 if not alternatives.has_key(service2):
29 alternatives[service2] = []
30 alternatives[service2].append(service1)
32 def removeAlternative(service1, service2):
33 alternatives[service1].remove(service2)
34 alternatives[service2].remove(service1)
35 if len(alternatives[service1]) == 0:
36 del alternatives[service1]
37 if len(alternatives[service2]) == 0:
38 del alternatives[service2]
40 def loadAlternatives():
41 doc = xml.dom.minidom.parse(resolveFilename(SCOPE_CONFIG, "alternatives.xml"))
43 root = doc.childNodes[0]
44 for service in elementsWithTag(root.childNodes, 'service'):
45 newService = str(service.getAttribute('ref'))
46 for alternative in elementsWithTag(service.childNodes, 'alternative'):
47 newAlternative = str(alternative.getAttribute('ref'))
48 addAlternative(newService, newAlternative)
51 return str.lower(ServiceReference(x).getServiceName().strip())
53 class AlternativeZapping(Screen):
55 <screen position="100,100" size="560,400" title="Services alternatives setup..." >
56 <widget name="red" position="0,0" size="140,40" backgroundColor="red" halign="center" valign="center" font="Regular;21" />
57 <widget name="green" position="140,0" size="140,40" backgroundColor="green" halign="center" valign="center" font="Regular;21" />
58 <widget name="yellow" position="280,0" size="140,40" backgroundColor="yellow" halign="center" valign="center" font="Regular;21" />
59 <widget name="blue" position="420,0" size="140,40" backgroundColor="blue" halign="center" valign="center" font="Regular;21" />
60 <widget name="serviceslist" position="0,40" size="280,360" scrollbarMode="showOnDemand" />
61 <widget name="alternativeslist" position="280,40" size="280,360" selectionDisabled="1" scrollbarMode="showOnDemand" />
63 def __init__(self, session):
64 self.skin = AlternativeZapping.skin
65 Screen.__init__(self, session)
67 self.filename = resolveFilename(SCOPE_CONFIG, "alternatives.xml")
70 self["red"] = self.red
71 self.green = Label(_("Add service"))
72 self["green"] = self.green
73 self.yellow = Label("")
74 self["yellow"] = self.yellow
76 self["blue"] = self.blue
78 self.alternatives = {}
80 self.serviceslist = []
81 self.alternativeslist = []
84 self.loadAlternatives()
87 self["serviceslist"] = MenuList(self.serviceslist)
88 self["alternativeslist"] = MenuList(self.alternativeslist)
90 self.onShown.append(self.updateServices)
91 self.onShown.append(self.updateAlternatives)
93 self["actions"] = ActionMap(["DirectionActions", "OkCancelActions", "ColorActions"],
102 "green": self.greenKey,
103 "yellow": self.yellowKey,
104 "blue": self.blueKey,
107 def saveAlternatives(self):
108 doc = xml.dom.minidom.Document()
109 root_element = doc.createElement('alternatives')
110 doc.appendChild(root_element)
111 root_element.appendChild(doc.createTextNode("\n"))
113 for alternative in self.alternatives.keys():
114 t = doc.createTextNode("\t")
115 root_element.appendChild(t)
116 t = doc.createElement('service')
117 t.setAttribute("ref", alternative)
118 root_element.appendChild(t)
119 t.appendChild(doc.createTextNode("\n"))
120 for x in self.alternatives[alternative]:
121 t.appendChild(doc.createTextNode("\t\t"))
122 l = doc.createElement('alternative')
123 l.setAttribute("ref", str(x))
125 t.appendChild(doc.createTextNode("\n"))
126 t.appendChild(doc.createTextNode("\t"))
127 root_element.appendChild(t)
128 t = doc.createTextNode("\n")
129 root_element.appendChild(t)
130 file = open(self.filename, "w")
135 def loadAlternatives(self):
136 self.alternatives = {}
138 doc = xml.dom.minidom.parse(self.filename)
140 root = doc.childNodes[0]
141 for service in elementsWithTag(root.childNodes, 'service'):
142 newService = str(service.getAttribute('ref'))
143 if not self.alternatives.has_key(newService):
144 self.alternatives[newService] = []
145 for alternative in elementsWithTag(service.childNodes, 'alternative'):
146 newAlternative = str(alternative.getAttribute('ref'))
147 self.alternatives[newService].append(newAlternative)
148 addAlternative(newService, newAlternative)
151 self.saveAlternatives()
155 self["serviceslist"].instance.moveSelection(self["serviceslist"].instance.moveUp)
156 self.updateAlternatives()
159 self["serviceslist"].instance.moveSelection(self["serviceslist"].instance.moveDown)
160 self.updateAlternatives()
169 for x in self.alternatives[self["serviceslist"].getCurrent()[1]]:
170 removeAlternative(self["serviceslist"].getCurrent()[1], x)
171 if len(self.serviceslist) > 0:
172 del self.alternatives[self["serviceslist"].getCurrent()[1]]
173 self.updateServices()
174 self.updateAlternatives()
176 def finishedAlternativeSelection(self, args):
177 self.alternatives[self["serviceslist"].getCurrent()[1]].append(str(ServiceReference(args)))
178 addAlternative(self["serviceslist"].getCurrent()[1], str(ServiceReference(args)))
179 self.updateAlternatives()
181 def updateServices(self):
182 self.serviceslist = []
183 keys = self.alternatives.keys()
184 keys.sort(key = sortKey)
186 self.serviceslist.append((ServiceReference(x).getServiceName(), x))
188 self["serviceslist"].setList(self.serviceslist)
189 if len(self.serviceslist) > 0:
190 self.yellow.setText(_("Add alternative"))
191 self.red.setText(_("Remove service"))
193 self.yellow.setText("")
196 def selectService(self, ref):
198 for x in self["serviceslist"].list:
200 self["serviceslist"].instance.moveSelectionTo(count)
205 def updateAlternatives(self):
206 self.alternativeslist = []
208 if len(self.serviceslist) > 0:
209 alternativelist = self.alternatives[self["serviceslist"].getCurrent()[1]]
211 for x in alternativelist:
212 self.alternativeslist.append((ServiceReference(x).getServiceName(), x))
214 self["alternativeslist"].setList(self.alternativeslist)
217 self.session.openWithCallback(self.finishedChannelSelection, SimpleChannelSelection, _("Select reference service"))
219 def finishedChannelSelection(self, *args):
221 serviceString = str(ServiceReference(args[0]))
222 if not self.alternatives.has_key(serviceString):
223 self.alternatives[serviceString] = []
224 self.updateServices()
225 self.selectService(serviceString)
226 self.updateAlternatives()
229 if len(self.serviceslist) > 0:
230 self.session.openWithCallback(self.finishedAlternativeSelection, SimpleChannelSelection, _("Select alternative service"))
236 oldPlayService = None
238 from Components.PerServiceDisplay import PerServiceDisplay
240 class ServiceChanged(PerServiceDisplay):
241 def __init__(self, navcore):
242 PerServiceDisplay.__init__(self, navcore,
244 iPlayableService.evTuneFailed: self.tuneFailed,
245 iPlayableService.evStart: self.start
248 self.lastPlayAction = None
252 # print "+++++++++++++++++++++++++++++++++++++++++++++++++Start", self.lastPlayAction
253 if self.lastPlayAction is not None:
254 self.lastPlayAction = None
256 def tuneFailed(self):
257 # print "+++++++++++++++++++++++++++++++++++++++++++++++++Tuning failed!", self.lastPlayAction
258 ref = self.lastPlayAction
260 # print "Alternatives: failed to play service"
262 if alternatives.has_key(ref):
263 # print "Alternatives: trying alternatives"
264 if len(alternatives[ref]) > self.nextPlayTry:
265 # print "Alternatives: trying alternative", alternatives[ref][self.nextPlayTry]
266 if oldPlayService(ServiceReference(alternatives[ref][self.nextPlayTry]).ref) == 0:
267 self.nextPlayTry += 1
268 # print "Alternatives: Alternative found!"
270 self.nextPlayTry += 1
271 # print "Alternatives: Alternative doesn't play either"
274 self.lastPlayAction = None
276 #print "Alternatives: No playable alternative found!"
278 servicechanged = None
280 def playService(self, ref, **kwargs):
281 #print "--------------------Alternatives: trying to play service", str(ServiceReference(ref))
283 servicechanged.lastPlayAction = str(ServiceReference(ref))
284 servicechanged.nextPlayTry = 0
285 result = oldPlayService(ref, **kwargs)
288 def sessionstart(reason, session, **kwargs):
292 except: # FIXME, THIS IS ILLEGAL CODE AND WILL BE PROSECUTED!
295 # attach to this sessions navigation instance.
296 global oldPlayService, servicechanged
297 oldPlayService = session.nav.playService
298 session.nav.playService = type(session.nav.playService)(playService, NavigationInstance, Navigation)
299 servicechanged = ServiceChanged(session.nav)
301 def AlternativeZappingSetup(session, **kwargs):
302 session.open(AlternativeZapping)
304 def Plugins(**kwargs):
305 return [PluginDescriptor(where = PluginDescriptor.WHERE_SESSIONSTART, fnc = sessionstart),
306 PluginDescriptor(name="Alternative services setup" , description="Defines alternatives for services.", where = PluginDescriptor.WHERE_PLUGINMENU, fnc=AlternativeZappingSetup)]