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