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):
220 serviceString = str(ServiceReference(args))
221 if not self.alternatives.has_key(serviceString):
222 self.alternatives[serviceString] = []
223 self.updateServices()
224 self.selectService(serviceString)
225 self.updateAlternatives()
228 if len(self.serviceslist) > 0:
229 self.session.openWithCallback(self.finishedAlternativeSelection, SimpleChannelSelection, _("Select alternative service"))
235 oldPlayService = None
237 from Components.PerServiceDisplay import PerServiceDisplay
239 class ServiceChanged(PerServiceDisplay):
240 def __init__(self, navcore):
241 PerServiceDisplay.__init__(self, navcore,
243 iPlayableService.evTuneFailed: self.tuneFailed,
244 iPlayableService.evStart: self.start
247 self.lastPlayAction = None
251 # print "+++++++++++++++++++++++++++++++++++++++++++++++++Start", self.lastPlayAction
252 if self.lastPlayAction is not None:
253 self.lastPlayAction = None
255 def tuneFailed(self):
256 # print "+++++++++++++++++++++++++++++++++++++++++++++++++Tuning failed!", self.lastPlayAction
257 ref = self.lastPlayAction
259 # print "Alternatives: failed to play service"
261 if alternatives.has_key(ref):
262 # print "Alternatives: trying alternatives"
263 if len(alternatives[ref]) > self.nextPlayTry:
264 # print "Alternatives: trying alternative", alternatives[ref][self.nextPlayTry]
265 if oldPlayService(ServiceReference(alternatives[ref][self.nextPlayTry]).ref) == 0:
266 self.nextPlayTry += 1
267 # print "Alternatives: Alternative found!"
269 self.nextPlayTry += 1
270 # print "Alternatives: Alternative doesn't play either"
273 self.lastPlayAction = None
275 #print "Alternatives: No playable alternative found!"
277 servicechanged = None
279 def playService(self, ref):
280 #print "--------------------Alternatives: trying to play service", str(ServiceReference(ref))
282 servicechanged.lastPlayAction = str(ServiceReference(ref))
283 servicechanged.nextPlayTry = 0
284 result = oldPlayService(ref)
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)]