5a02c38d7f9722aafe2d07d4e46de12f7c745d5f
[enigma2.git] / lib / python / Components / ConfigList.py
1 from HTMLComponent import HTMLComponent
2 from GUIComponent import GUIComponent
3 from config import KEY_LEFT, KEY_RIGHT, KEY_HOME, KEY_END, KEY_0, KEY_DELETE, KEY_BACKSPACE, KEY_OK, KEY_TOGGLEOW, KEY_ASCII, KEY_TIMEOUT, KEY_NUMBERS, ConfigElement, ConfigText, ConfigPassword
4 from Components.ActionMap import NumberActionMap, ActionMap
5 from enigma import eListbox, eListboxPythonConfigContent, eRCInput, eTimer
6 from Screens.MessageBox import MessageBox
7
8 class ConfigList(HTMLComponent, GUIComponent, object):
9         def __init__(self, list, session = None):
10                 GUIComponent.__init__(self)
11                 self.l = eListboxPythonConfigContent()
12                 self.l.setSeperation(200)
13                 self.timer = eTimer()
14                 self.list = list
15                 self.onSelectionChanged = [ ]
16                 self.current = None
17                 self.session = session
18
19         def execBegin(self):
20                 rcinput = eRCInput.getInstance()
21                 rcinput.setKeyboardMode(rcinput.kmAscii)
22                 self.timer.callback.append(self.timeout)
23
24         def execEnd(self):
25                 rcinput = eRCInput.getInstance()
26                 rcinput.setKeyboardMode(rcinput.kmNone)
27                 self.timer.callback.remove(self.timeout)
28
29         def toggle(self):
30                 selection = self.getCurrent()
31                 selection[1].toggle()
32                 self.invalidateCurrent()
33
34         def handleKey(self, key):
35                 selection = self.getCurrent()
36                 if selection and selection[1].enabled:
37                         selection[1].handleKey(key)
38                         self.invalidateCurrent()
39                         if key in KEY_NUMBERS:
40                                 self.timer.start(1000, 1)
41
42         def getCurrent(self):
43                 return self.l.getCurrentSelection()
44         
45         def getCurrentIndex(self):
46                 return self.l.getCurrentSelectionIndex()
47         
48         def setCurrentIndex(self, index):
49                 if self.instance is not None:
50                         self.instance.moveSelectionTo(index)
51         
52         def invalidateCurrent(self):
53                 self.l.invalidateEntry(self.l.getCurrentSelectionIndex())
54
55         def invalidate(self, entry):
56                 # when the entry to invalidate does not exist, just ignore the request.
57                 # this eases up conditional setup screens a lot.
58                 if entry in self.__list:
59                         self.l.invalidateEntry(self.__list.index(entry))
60
61         GUI_WIDGET = eListbox
62         
63         def selectionChanged(self):
64                 if isinstance(self.current,tuple) and len(self.current) == 2:
65                         self.current[1].onDeselect(self.session)
66                 self.current = self.getCurrent()
67                 if isinstance(self.current,tuple) and len(self.current) == 2:
68                         self.current[1].onSelect(self.session)
69                 else:
70                         return
71                 for x in self.onSelectionChanged:
72                         x()
73
74         def postWidgetCreate(self, instance):
75                 instance.selectionChanged.get().append(self.selectionChanged)
76                 instance.setContent(self.l)
77         
78         def preWidgetRemove(self, instance):
79                 if isinstance(self.current,tuple) and len(self.current) == 2:
80                         self.current[1].onDeselect(self.session)
81                 instance.selectionChanged.get().remove(self.selectionChanged)
82                 instance.setContent(None)
83
84         def setList(self, l):
85                 self.timer.stop()
86                 self.__list = l
87                 self.l.setList(self.__list)
88
89                 if l is not None:
90                         for x in l:
91                                 assert isinstance(x, ConfigElement), "entry in ConfigList " + str(x) + " must be a ConfigElement"
92
93         def getList(self):
94                 return self.__list
95
96         list = property(getList, setList)
97
98         def timeout(self):
99                 self.handleKey(KEY_TIMEOUT)
100
101         def isChanged(self):
102                 is_changed = False
103                 for x in self.list:
104                         is_changed |= x[1].isChanged()
105
106                 return is_changed
107
108 class ConfigListScreen:
109         def __init__(self, list, session = None, on_change = None):
110                 self["config_actions"] = NumberActionMap(["SetupActions", "InputAsciiActions", "KeyboardInputActions"],
111                 {
112                         "gotAsciiCode": self.keyGotAscii,
113                         "ok": self.keyOK,
114                         "left": self.keyLeft,
115                         "right": self.keyRight,
116                         "home": self.keyHome,
117                         "end": self.keyEnd,
118                         "deleteForward": self.keyDelete,
119                         "deleteBackward": self.keyBackspace,
120                         "toggleOverwrite": self.keyToggleOW,
121                         "1": self.keyNumberGlobal,
122                         "2": self.keyNumberGlobal,
123                         "3": self.keyNumberGlobal,
124                         "4": self.keyNumberGlobal,
125                         "5": self.keyNumberGlobal,
126                         "6": self.keyNumberGlobal,
127                         "7": self.keyNumberGlobal,
128                         "8": self.keyNumberGlobal,
129                         "9": self.keyNumberGlobal,
130                         "0": self.keyNumberGlobal
131                 }, -1) # to prevent left/right overriding the listbox
132
133                 self["VirtualKB"] = ActionMap(["VirtualKeyboardActions"],
134                 {
135                         "showVirtualKeyboard": self.KeyText,
136                 }, -2)
137                 self["VirtualKB"].setEnabled(False)
138                 
139                 self["config"] = ConfigList(list, session = session)
140                 
141                 if on_change is not None:
142                         self.__changed = on_change
143                 else:
144                         self.__changed = lambda: None
145                 
146                 if not self.handleInputHelpers in self["config"].onSelectionChanged:
147                         self["config"].onSelectionChanged.append(self.handleInputHelpers)
148
149         def handleInputHelpers(self):
150                 if self["config"].getCurrent() is not None:
151                         if isinstance(self["config"].getCurrent()[1], ConfigText) or isinstance(self["config"].getCurrent()[1], ConfigPassword):
152                                 if self.has_key("VKeyIcon"):
153                                         self["VirtualKB"].setEnabled(True)
154                                         self["VKeyIcon"].boolean = True
155                                 if self.has_key("HelpWindow"):
156                                         if self["config"].getCurrent()[1].help_window.instance is not None:
157                                                 helpwindowpos = self["HelpWindow"].getPosition()
158                                                 from enigma import ePoint
159                                                 self["config"].getCurrent()[1].help_window.instance.move(ePoint(helpwindowpos[0],helpwindowpos[1]))
160                         else:
161                                 if self.has_key("VKeyIcon"):
162                                         self["VirtualKB"].setEnabled(False)
163                                         self["VKeyIcon"].boolean = False
164                 else:
165                         if self.has_key("VKeyIcon"):
166                                 self["VirtualKB"].setEnabled(False)
167                                 self["VKeyIcon"].boolean = False
168
169         def KeyText(self):
170                 from Screens.VirtualKeyBoard import VirtualKeyBoard
171                 self.session.openWithCallback(self.VirtualKeyBoardCallback, VirtualKeyBoard, title = self["config"].getCurrent()[0], text = self["config"].getCurrent()[1].getValue())
172
173         def VirtualKeyBoardCallback(self, callback = None):
174                 if callback is not None and len(callback):
175                         self["config"].getCurrent()[1].setValue(callback)
176                         self["config"].invalidate(self["config"].getCurrent())
177                         
178         def keyOK(self):
179                 self["config"].handleKey(KEY_OK)
180
181         def keyLeft(self):
182                 self["config"].handleKey(KEY_LEFT)
183                 self.__changed()
184
185         def keyRight(self):
186                 self["config"].handleKey(KEY_RIGHT)
187                 self.__changed()
188
189         def keyHome(self):
190                 self["config"].handleKey(KEY_HOME)
191                 self.__changed()
192
193         def keyEnd(self):
194                 self["config"].handleKey(KEY_END)
195                 self.__changed()
196
197         def keyDelete(self):
198                 self["config"].handleKey(KEY_DELETE)
199                 self.__changed()
200
201         def keyBackspace(self):
202                 self["config"].handleKey(KEY_BACKSPACE)
203                 self.__changed()
204
205         def keyToggleOW(self):
206                 self["config"].handleKey(KEY_TOGGLEOW)
207                 self.__changed()
208
209         def keyGotAscii(self):
210                 self["config"].handleKey(KEY_ASCII)
211                 self.__changed()
212
213         def keyNumberGlobal(self, number):
214                 self["config"].handleKey(KEY_0 + number)
215                 self.__changed()
216                 
217         def saveAll(self):
218                 for x in self["config"].list:
219                         x[1].save()
220
221         # keySave and keyCancel are just provided in case you need them.
222         # you have to call them by yourself.
223         def keySave(self):
224                 self.saveAll()
225                 self.close()
226         
227         def cancelConfirm(self, result):
228                 if not result:
229                         return
230
231                 for x in self["config"].list:
232                         x[1].cancel()
233                 self.close()
234
235         def keyCancel(self):
236                 if self["config"].isChanged():
237                         self.session.openWithCallback(self.cancelConfirm, MessageBox, _("Really close without saving settings?"))
238                 else:
239                         self.close()