fix getBouquetList
[enigma2.git] / lib / python / Screens / Ci.py
1 from Screen import *
2 from Components.MenuList import MenuList
3 from Components.ActionMap import ActionMap
4 from Components.ActionMap import NumberActionMap
5 from Components.Header import Header
6 from Components.Button import Button
7 from Components.Label import Label
8
9 from Components.HTMLComponent import *
10 from Components.GUIComponent import *
11 from Components.config import config, ConfigSubsection, ConfigSelection, ConfigSubList, getConfigListEntry, KEY_LEFT, KEY_RIGHT, KEY_0, ConfigNothing, ConfigPIN
12 from Components.ConfigList import ConfigList
13
14 from enigma import eTimer, eDVBCI_UI, eListboxPythonStringContent, eListboxPythonConfigContent
15
16 MAX_NUM_CI = 4
17
18 def InitCiConfig():
19         config.ci = ConfigSubList()
20         for slot in range(MAX_NUM_CI):
21                 config.ci.append(ConfigSubsection())
22                 config.ci[slot].canDescrambleMultipleServices = ConfigSelection(choices = [("auto", _("Auto")), ("no", _("No")), ("yes", _("Yes"))], default = "auto")
23
24 class CiMmi(Screen):
25         def __init__(self, session, slotid, action):
26                 Screen.__init__(self, session)
27
28                 print "ciMMI with action" + str(action)
29
30                 self.tag = None
31                 self.slotid = slotid
32
33                 self.timer = eTimer()
34                 self.timer.timeout.get().append(self.keyCancel)
35
36                 #else the skins fails
37                 self["title"] = Label("")
38                 self["subtitle"] = Label("")
39                 self["bottom"] = Label("")
40                 self["entries"] = ConfigList([ ])
41
42                 self["actions"] = NumberActionMap(["SetupActions"],
43                         {
44                                 "ok": self.okbuttonClick,
45                                 "cancel": self.keyCancel,
46                                 #for PIN
47                                 "left": self.keyLeft,
48                                 "right": self.keyRight,
49                                 "1": self.keyNumberGlobal,
50                                 "2": self.keyNumberGlobal,
51                                 "3": self.keyNumberGlobal,
52                                 "4": self.keyNumberGlobal,
53                                 "5": self.keyNumberGlobal,
54                                 "6": self.keyNumberGlobal,
55                                 "7": self.keyNumberGlobal,
56                                 "8": self.keyNumberGlobal,
57                                 "9": self.keyNumberGlobal,
58                                 "0": self.keyNumberGlobal
59                         }, -1)
60
61                 self.action = action
62
63                 if action == 2:         #start MMI
64                         eDVBCI_UI.getInstance().startMMI(self.slotid)
65                         self.showWait()
66                 elif action == 3:               #mmi already there (called from infobar)
67                         self.showScreen()
68
69         def addEntry(self, list, entry):
70                 if entry[0] == "TEXT":          #handle every item (text / pin only?)
71                         list.append( (entry[1], ConfigNothing(), entry[2]) )
72                 if entry[0] == "PIN":
73                         pinlength = entry[1]
74                         if entry[3] == 1:
75                                 # masked pins:
76                                 x = ConfigPIN(0, len = pinlength, censor = "*")
77                         else:
78                                 # unmasked pins:
79                                 x = ConfigPIN(0, len = pinlength)
80                         self["subtitle"].setText(entry[2])
81                         list.append( getConfigListEntry("", x) )
82                         self["bottom"].setText(_("please press OK when ready"))
83
84         def okbuttonClick(self):
85                 self.timer.stop()
86                 if not self.tag:
87                         return
88                 if self.tag == "WAIT":
89                         print "do nothing - wait"
90                 elif self.tag == "MENU":
91                         print "answer MENU"
92                         cur = self["entries"].getCurrent()
93                         if cur:
94                                 eDVBCI_UI.getInstance().answerMenu(self.slotid, cur[2])
95                         else:
96                                 eDVBCI_UI.getInstance().answerMenu(self.slotid, 0)
97                         self.showWait() 
98                 elif self.tag == "LIST":
99                         print "answer LIST"
100                         eDVBCI_UI.getInstance().answerMenu(self.slotid, 0)
101                         self.showWait() 
102                 elif self.tag == "ENQ":
103                         cur = self["entries"].getCurrent()
104                         answer = str(cur[1].value)
105                         length = len(answer)
106                         while length < cur[1].getLength():
107                                 answer = '0'+answer
108                                 length+=1
109                         eDVBCI_UI.getInstance().answerEnq(self.slotid, answer)
110                         self.showWait()
111
112         def closeMmi(self):
113                 self.timer.stop()
114                 self.close(self.slotid)
115
116         def keyCancel(self):
117                 self.timer.stop()
118                 if not self.tag:
119                         return
120                 if self.tag == "WAIT":
121                         eDVBCI_UI.getInstance().stopMMI(self.slotid)
122                         self.closeMmi()
123                 elif self.tag in [ "MENU", "LIST" ]:
124                         print "cancel list"
125                         eDVBCI_UI.getInstance().answerMenu(self.slotid, 0)
126                         self.showWait()
127                 elif self.tag == "ENQ":
128                         print "cancel enq"
129                         eDVBCI_UI.getInstance().cancelEnq(self.slotid)
130                         self.showWait()
131                 else:
132                         print "give cancel action to ci"        
133
134         def keyConfigEntry(self, key):
135                 self.timer.stop()
136                 try:
137                         self["entries"].handleKey(key)
138                 except:
139                         pass
140
141         def keyNumberGlobal(self, number):
142                 self.timer.stop()
143                 self.keyConfigEntry(KEY_0 + number)
144
145         def keyLeft(self):
146                 self.timer.stop()
147                 self.keyConfigEntry(KEY_LEFT)
148
149         def keyRight(self):
150                 self.timer.stop()
151                 self.keyConfigEntry(KEY_RIGHT)
152
153         def updateList(self, list):
154                 List = self["entries"]
155                 try:
156                         List.instance.moveSelectionTo(0)
157                 except:
158                         pass
159                 List.l.setList(list)
160
161         def showWait(self):
162                 self.tag = "WAIT"
163                 self["title"].setText("")
164                 self["subtitle"].setText("")
165                 self["bottom"].setText("")
166                 list = [ ]
167                 list.append( (_("wait for ci..."), ConfigNothing()) )
168                 self.updateList(list)
169
170         def showScreen(self):
171                 screen = eDVBCI_UI.getInstance().getMMIScreen(self.slotid)
172         
173                 list = [ ]
174
175                 self.timer.stop()
176                 if len(screen) > 0 and screen[0][0] == "CLOSE":
177                         timeout = screen[0][1]
178                         if timeout > 0:
179                                 self.timer.start(timeout*1000, True)
180                         else:
181                                 self.keyCancel()
182                 else:
183                         self.tag = screen[0][0]
184                         for entry in screen:
185                                 if entry[0] == "PIN":
186                                         self.addEntry(list, entry)
187                                 else:
188                                         if entry[0] == "TITLE":
189                                                 self["title"].setText(entry[1])
190                                         elif entry[0] == "SUBTITLE":
191                                                 self["subtitle"].setText(entry[1])
192                                         elif entry[0] == "BOTTOM":
193                                                 self["bottom"].setText(entry[1])
194                                         elif entry[0] == "TEXT":
195                                                 self.addEntry(list, entry)
196                         self.updateList(list)
197
198         def ciStateChanged(self):
199                 if self.action == 0:                    #reset
200                         self.closeMmi()
201                 if self.action == 1:                    #init
202                         self.closeMmi()
203
204                 #module still there ?                   
205                 if eDVBCI_UI.getInstance().getState(self.slotid) != 2:
206                         self.closeMmi()
207
208                 #mmi session still active ?                     
209                 if eDVBCI_UI.getInstance().getMMIState(self.slotid) != 1:
210                         self.closeMmi()
211
212                 if self.action > 1 and eDVBCI_UI.getInstance().availableMMI(self.slotid) == 1:
213                         self.showScreen()
214
215                 #FIXME: check for mmi-session closed    
216
217 class CiMessageHandler:
218         def __init__(self):
219                 self.session = None
220                 self.ci = { }
221                 self.dlgs = { }
222                 eDVBCI_UI.getInstance().ciStateChanged.get().append(self.ciStateChanged)
223
224         def setSession(self, session):
225                 self.session = session
226
227         def ciStateChanged(self, slot):
228                 if slot in self.ci:
229                         self.ci[slot](slot)
230                 else:
231                         if slot in self.dlgs:
232                                 self.dlgs[slot].ciStateChanged()
233                         elif eDVBCI_UI.getInstance().availableMMI(slot) == 1:
234                                 if self.session:
235                                         self.dlgs[slot] = self.session.openWithCallback(self.dlgClosed, CiMmi, slot, 3)
236                                 else:
237                                         print "no session"
238
239         def dlgClosed(self, slot):
240                 del self.dlgs[slot]
241
242         def registerCIMessageHandler(self, slot, func):
243                 self.unregisterCIMessageHandler(slot)
244                 self.ci[slot] = func
245
246         def unregisterCIMessageHandler(self, slot):
247                 if slot in self.ci:
248                         del self.ci[slot]
249
250 CiHandler = CiMessageHandler()
251
252 class CiSelection(Screen):
253         def __init__(self, session):
254                 Screen.__init__(self, session)
255
256                 self["actions"] = ActionMap(["OkCancelActions", "CiSelectionActions"],
257                         {
258                                 "left": self.keyLeft,
259                                 "right": self.keyLeft,
260                                 "ok": self.okbuttonClick,
261                                 "cancel": self.cancel
262                         },-1)
263
264                 self.dlg = None
265                 self.state = { }
266                 self.list = [ ]
267
268                 for slot in range(MAX_NUM_CI):
269                         state = eDVBCI_UI.getInstance().getState(slot)
270                         if state != -1:
271                                 self.appendEntries(slot, state)
272                                 CiHandler.registerCIMessageHandler(slot, self.ciStateChanged)
273
274                 menuList = ConfigList(self.list)
275                 menuList.list = self.list
276                 menuList.l.setList(self.list)
277                 self["entries"] = menuList
278
279         def keyConfigEntry(self, key):
280                 try:
281                         self["entries"].handleKey(key)
282                         self["entries"].getCurrent()[1].save()
283                 except:
284                         pass
285
286         def keyLeft(self):
287                 self.keyConfigEntry(KEY_LEFT)
288
289         def keyRight(self):
290                 self.keyConfigEntry(KEY_RIGHT)
291
292         def appendEntries(self, slot, state):
293                 self.state[slot] = state
294                 self.list.append( (_("Reset"), ConfigNothing(), 0, slot) )
295                 self.list.append( (_("Init"), ConfigNothing(), 1, slot) )
296
297                 if self.state[slot] == 0:                       #no module
298                         self.list.append( (_("no module found"), ConfigNothing(), 2, slot) )
299                 elif self.state[slot] == 1:             #module in init
300                         self.list.append( (_("init module"), ConfigNothing(), 2, slot) )
301                 elif self.state[slot] == 2:             #module ready
302                         #get appname
303                         appname = eDVBCI_UI.getInstance().getAppName(slot)
304                         self.list.append( (appname, ConfigNothing(), 2, slot) )
305
306                 self.list.append(getConfigListEntry(_("Multiple service support"), config.ci[slot].canDescrambleMultipleServices))
307
308         def updateState(self, slot):
309                 state = eDVBCI_UI.getInstance().getState(slot)
310                 self.state[slot] = state
311
312                 slotidx=0
313                 while self.list[slotidx][2] != slot:
314                         slotidx += 1
315
316                 slotidx += 1 # do not change Reset
317                 slotidx += 1 # do not change Init
318
319                 if state == 0:                  #no module
320                         self.list[slotidx] = (_("no module found"), ConfigNothing(), 2, slot)
321                 elif state == 1:                #module in init
322                         self.list[slotidx] = (_("init module"), ConfigNothing(), 2, slot)
323                 elif state == 2:                #module ready
324                         #get appname
325                         appname = eDVBCI_UI.getInstance().getAppName(slot)
326                         self.list[slotidx] = (appname, ConfigNothing(), 2, slot)
327
328                 lst = self["entries"]
329                 lst.list = self.list
330                 lst.l.setList(self.list)
331
332         def ciStateChanged(self, slot):
333                 if self.dlg:
334                         self.dlg.ciStateChanged()
335                 else:
336                         state = eDVBCI_UI.getInstance().getState(slot)
337                         if self.state[slot] != state:
338                                 #print "something happens"
339                                 self.state[slot] = state
340                                 self.updateState(slot)
341
342         def dlgClosed(self, slot):
343                 self.dlg = None
344
345         def okbuttonClick(self):
346                 cur = self["entries"].getCurrent()
347                 if cur and len(cur) > 2:
348                         action = cur[2]
349                         slot = cur[3]
350                         if action == 0:         #reset
351                                 eDVBCI_UI.getInstance().setReset(slot)
352                         elif action == 1:               #init
353                                 eDVBCI_UI.getInstance().setInit(slot)
354                         elif self.state[slot] == 2:
355                                 self.dlg = self.session.openWithCallback(self.dlgClosed, CiMmi, slot, action)
356
357         def cancel(self):
358                 CiHandler.unregisterCIMessageHandler(0)
359                 self.close()