improve text editing. Patch by Anders Holst
[vuplus_dvbapp] / 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
4 from Components.ActionMap import NumberActionMap
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(100)
13                 self.timer = eTimer()
14                 self.list = list
15                 self.onSelectionChanged = [ ]
16                 self.current = None
17                 self.help_window = None
18                 self.setHelpWindowSession(session)
19
20         def execBegin(self):
21                 rcinput = eRCInput.getInstance()
22                 rcinput.setKeyboardMode(rcinput.kmAscii)
23                 self.timer.timeout.get().append(self.timeout)
24
25         def execEnd(self):
26                 rcinput = eRCInput.getInstance()
27                 rcinput.setKeyboardMode(rcinput.kmNone)
28                 self.timer.timeout.get().remove(self.timeout)
29
30         def setHelpWindowSession(self, session):
31                 assert self.help_window is None, "you can't move a help window to another session"
32                 self.session = session
33
34         def toggle(self):
35                 selection = self.getCurrent()
36                 selection[1].toggle()
37                 self.invalidateCurrent()
38
39         def handleKey(self, key):
40                 selection = self.getCurrent()
41                 if selection and selection[1].enabled:
42                         selection[1].handleKey(key)
43                         self.invalidateCurrent()
44                         if self.help_window:
45                                 self.help_window.update(selection[1])
46                         if key in KEY_NUMBERS:
47                                 self.timer.start(1000, 1)
48
49         def getCurrent(self):
50                 return self.l.getCurrentSelection()
51         
52         def getCurrentIndex(self):
53                 return self.l.getCurrentSelectionIndex()
54         
55         def setCurrentIndex(self, index):
56                 if self.instance is not None:
57                         self.instance.moveSelectionTo(index)
58         
59         def invalidateCurrent(self):
60                 self.l.invalidateEntry(self.l.getCurrentSelectionIndex())
61
62         def invalidate(self, entry):
63                 # when the entry to invalidate does not exist, just ignore the request.
64                 # this eases up conditional setup screens a lot.
65                 if entry in self.__list:
66                         self.l.invalidateEntry(self.__list.index(entry))
67
68         GUI_WIDGET = eListbox
69         
70         def selectionChanged(self):
71                 n = self.getCurrent()
72                 
73                 if self.help_window:
74                         self.session.deleteDialog(self.help_window)
75                 
76                 nh = n and n[1].helpWindow()
77                 if nh is not None and self.session is not None:
78                         self.help_window = self.session.instantiateDialog(*nh)
79                         self.help_window.show()
80
81                 self.current = n
82                 for x in self.onSelectionChanged:
83                         x()
84
85         def postWidgetCreate(self, instance):
86                 instance.setContent(self.l)
87                 instance.selectionChanged.get().append(self.selectionChanged)
88         
89         def preWidgetRemove(self, instance):
90                 instance.selectionChanged.get().remove(self.selectionChanged)
91         
92         def setList(self, l):
93                 self.timer.stop()
94                 self.__list = l
95                 self.l.setList(self.__list)
96
97                 if l is not None:
98                         for x in l:
99                                 assert isinstance(x[1], ConfigElement), "entry in ConfigList " + str(x[1]) + " must be a ConfigElement"
100
101         def getList(self):
102                 return self.__list
103
104         list = property(getList, setList)
105
106         def timeout(self):
107                 self.handleKey(KEY_TIMEOUT)
108
109         def isChanged(self):
110                 is_changed = False
111                 for x in self.list:
112                         is_changed |= x[1].isChanged()
113
114                 return is_changed
115
116 class ConfigListScreen:
117         def __init__(self, list, session = None, on_change = None):
118                 self["config_actions"] = NumberActionMap(["SetupActions", "InputAsciiActions", "KeyboardInputActions"],
119                 {
120                         "gotAsciiCode": self.keyGotAscii,
121                         "ok": self.keyOK,
122                         "accept": self.keyOK,
123                         "left": self.keyLeft,
124                         "right": self.keyRight,
125                         "moveLeft": self.keyLeft,
126                         "moveRight": self.keyRight,
127                         "moveHome": self.keyHome,
128                         "moveEnd": self.keyEnd,
129                         "deleteForward": self.keyDelete,
130                         "deleteBackward": self.keyBackspace,
131                         "toggleOverwrite": self.keyToggleOW,
132                         "1": self.keyNumberGlobal,
133                         "2": self.keyNumberGlobal,
134                         "3": self.keyNumberGlobal,
135                         "4": self.keyNumberGlobal,
136                         "5": self.keyNumberGlobal,
137                         "6": self.keyNumberGlobal,
138                         "7": self.keyNumberGlobal,
139                         "8": self.keyNumberGlobal,
140                         "9": self.keyNumberGlobal,
141                         "0": self.keyNumberGlobal
142                 }, -1) # to prevent left/right overriding the listbox
143                 
144                 self["config"] = ConfigList(list, session = session)
145                 if on_change is not None:
146                         self.__changed = on_change
147                 else:
148                         self.__changed = lambda: None
149
150         def keyOK(self):
151                 self["config"].handleKey(KEY_OK)
152
153         def keyLeft(self):
154                 self["config"].handleKey(KEY_LEFT)
155                 self.__changed()
156
157         def keyRight(self):
158                 self["config"].handleKey(KEY_RIGHT)
159                 self.__changed()
160
161         def keyHome(self):
162                 self["config"].handleKey(KEY_HOME)
163                 self.__changed()
164
165         def keyEnd(self):
166                 self["config"].handleKey(KEY_END)
167                 self.__changed()
168
169         def keyDelete(self):
170                 self["config"].handleKey(KEY_DELETE)
171                 self.__changed()
172
173         def keyBackspace(self):
174                 self["config"].handleKey(KEY_BACKSPACE)
175                 self.__changed()
176
177         def keyToggleOW(self):
178                 self["config"].handleKey(KEY_TOGGLEOW)
179                 self.__changed()
180
181         def keyGotAscii(self):
182                 self["config"].handleKey(KEY_ASCII)
183                 self.__changed()
184
185         def keyNumberGlobal(self, number):
186                 self["config"].handleKey(KEY_0 + number)
187                 self.__changed()
188
189         # keySave and keyCancel are just provided in case you need them.
190         # you have to call them by yourself.
191         def keySave(self):
192                 for x in self["config"].list:
193                         x[1].save()
194                 self.close()
195         
196         def cancelConfirm(self, result):
197                 if not result:
198                         return
199
200                 for x in self["config"].list:
201                         x[1].cancel()
202                 self.close()
203
204         def keyCancel(self):
205                 if self["config"].isChanged():
206                         self.session.openWithCallback(self.cancelConfirm, MessageBox, _("Really close without saving settings?"))
207                 else:
208                         self.close()