fix drawing of configSequence string
[enigma2.git] / lib / python / Components / config.py
1 class configFile:
2         def __init__(self):
3                 self.changed = 0
4                 self.configElements = { }
5                 try:
6                         self.file = open("config")
7                 except IOError:
8                         print "cannot open config file"
9                         return 
10                 
11                 while 1:
12                         line = self.file.readline()
13                         if line == "":
14                                 break
15                         
16                         if line.startswith("#"):                #skip comments
17                                 continue        
18                                 
19                         self.addElement(line)
20                 self.file.close()
21
22         def addElement(self, line):
23                 x = line.find("=")
24                 if x > -1:
25                         self.configElements[line[:x]] = line[x + 1:]
26         
27         def getKey(self, key):
28                 return self.configElements[key]
29
30         def setKey(self, key, value):
31                 self.changed = 1
32                 self.configElements[key] = value
33
34         def save(self):
35                 if self.changed == 0:           #no changes, so no write to disk needed
36                         return
37                         
38                 fileHandle = open("config", "w")
39                 
40                 keys = self.configElements.keys()
41                 keys.sort()
42                 for x in keys:
43                         wstr = x + "=" + self.configElements[x]
44                         
45                         if wstr[len(wstr) - 1] != '\n':
46                                 wstr = wstr + "\n"
47
48                         fileHandle.write(wstr)
49
50                 fileHandle.close()              
51
52 class configSelection:
53         def __init__(self, parent):
54                 self.parent = parent
55                 
56         def checkValues(self):
57                 if self.parent.value < 0:
58                         self.parent.value = 0   
59
60                 if(self.parent.value >= (len(self.parent.vals) - 1)):
61                         self.parent.value = len(self.parent.vals) - 1
62
63         def cancel(self):
64                 self.parent.reload()
65
66         def save(self):
67                 self.parent.save()
68
69         def handleKey(self, key):
70                 if key == config.key["prevElement"]:
71                         self.parent.value = self.parent.value - 1
72                 if key == config.key["nextElement"]:
73                         self.parent.value = self.parent.value + 1
74                 
75                 self.checkValues()                      
76
77                 self.parent.change()    
78
79         def __call__(self, selected):                   #needed by configlist
80                 self.checkValues()
81                 return ("text", self.parent.vals[self.parent.value])
82
83 class configSatlist:
84         def __init__(self, parent):
85                 self.parent = parent
86
87         def checkValues(self):
88                 if self.parent.value < 0:
89                         self.parent.value = 0   
90
91                 if(self.parent.value >= (len(self.parent.vals) - 1)):
92                         self.parent.value = len(self.parent.vals) - 1
93                         
94         def cancel(self):
95                 self.parent.reload()
96
97         def save(self):
98                 self.parent.save()
99
100         def handleKey(self, key):
101                 if key == config.key["prevElement"]:
102                         self.parent.value = self.parent.value - 1
103                 if key == config.key["nextElement"]:
104                         self.parent.value = self.parent.value + 1
105                 
106                 self.checkValues()                      
107
108                 self.parent.change()    
109
110         def __call__(self, selected):                   #needed by configlist
111                 self.checkValues()
112                 #fixme
113                 return ("text", str(self.parent.vals[self.parent.value][0]))
114
115 class configSequenceArg:
116         def get(self, type, args = ()):
117                 # configsequencearg.get ("IP")
118                 if (type == "IP"):
119                         return (("."), [(1,255),(1,255),(1,255),(1,255)])
120                 # configsequencearg.get ("MAC")
121                 if (type == "MAC"):
122                         return ((":"), [(1,255),(1,255),(1,255),(1,255),(1,255),(1,255)])
123                 # configsequencearg.get("INTEGER", (min, max)) => x with min <= x <= max
124                 if (type == "INTEGER"):
125                         return ((":"), [args])
126                 # configsequencearg.get("FLOAT", [(min,max),(min1,max1)]) => x.y with min <= x <= max and min1 <= y <= max1
127                 if (type == "FLOAT"):
128                         return (("."), args)
129
130 configsequencearg = configSequenceArg()
131                 
132 class configSequence:
133         def __init__(self, parent):
134                 self.parent = parent
135                 self.markedPos = 0
136                 self.seperator = self.parent.vals[0]
137                 self.valueBounds = self.parent.vals[1]
138
139         def checkValues(self):
140                 maxPos = 0
141                 num = 0
142                 for i in self.parent.value:
143                         maxPos += len(str(self.valueBounds[num][1]))
144                         num += 1
145                 
146                 if self.markedPos >= maxPos:
147                         self.markedPos = maxPos - 1
148                 if self.markedPos < 0:
149                         self.markedPos = 0
150                         
151         def cancel(self):
152                 self.parent.reload()
153
154         def save(self):
155                 self.parent.save()
156
157         def handleKey(self, key):
158                 #this will no change anything on the value itself
159                 #so we can handle it here in gui element
160                 if key == config.key["prevElement"]:
161                         self.markedPos -= 1
162                 if key == config.key["nextElement"]:
163                         self.markedPos += 1
164                 
165                 if key >= config.key["0"] and key <= config.key["9"]:
166                         number = 9 - config.key["9"] + key
167                         # length of numberblock
168                         numberLen = len(str(self.valueBounds[0][1]))
169                         # position in the block
170                         posinblock = self.markedPos % numberLen
171                         # blocknumber
172                         blocknumber = self.markedPos / numberLen
173                         
174                         oldvalue = self.parent.value[blocknumber]
175                         olddec = oldvalue % 10 ** (numberLen - posinblock) - (oldvalue % 10 ** (numberLen - posinblock - 1))
176                         newvalue = oldvalue - olddec + (10 ** (numberLen - posinblock - 1) * number)
177                         
178                         print "You actually pressed a number (" + str(number) + ") which will be added at block number " + str(blocknumber) + " on position " + str(posinblock)
179                         print "Old value: " + str(oldvalue) + " olddec: " + str(olddec) + " newvalue: " + str(newvalue)
180                         self.parent.value[blocknumber] = newvalue
181                         self.markedPos += 1
182                 
183                 self.checkValues()                      
184                 
185                 print "markPos:",
186                 print self.markedPos
187
188                 #FIXME: dont call when press left/right
189                 self.parent.change()    
190
191         def __call__(self, selected):                   #needed by configlist
192                 value = ""
193                 mPos = self.markedPos
194                 print "Positon: " + str(mPos)
195                 num = 0;
196                 for i in self.parent.value:
197                         if len(value):  #fixme no heading separator possible
198                                 value += self.seperator
199                                 if mPos >= len(value) - 1:
200                                         mPos += 1
201                                 
202                         #diff =         self.valueBounds - len(str(i))
203                         #if diff > 0:
204                                 ## if this helps?!
205                                 #value += " " * diff
206                         print (("%0" + str(len(str(self.valueBounds[num][1]))) + "d") % i)
207                         value += ("%0" + str(len(str(self.valueBounds[num][1]))) + "d") % i
208                         num += 1
209                         # only mark cursor when we are selected
210                         # (this code is heavily ink optimized!)
211                 return ("mtext"[1-selected:], value, [mPos])
212
213 class configValue:
214         def __init__(self, obj):
215                 self.obj = obj
216                 
217         def __str__(self):
218                 return self.obj
219
220 class Config:
221         def __init__(self):
222                 self.key = { "choseElement": 0,
223                                          "prevElement": 1,
224                                          "nextElement": 2,
225                                          "0": 10,
226                                          "1": 11,
227                                          "2": 12,
228                                          "3": 13,
229                                          "4": 14,
230                                          "5": 15,
231                                          "6": 16,
232                                          "7": 17,
233                                          "8": 18,
234                                          "9": 19 }
235                 
236 config = Config();
237 configfile = configFile()
238
239 class ConfigSlider:
240         def __init__(self, parent):
241                 self.parent = parent
242
243         def cancel(self):
244                 self.parent.reload()
245
246         def save(self):
247                 self.parent.save()
248
249         def checkValues(self):
250                 if self.parent.value < 0:
251                         self.parent.value = 0   
252
253                 if self.parent.value > 10:
254                         self.parent.value = 10  
255
256         def handleKey(self, key):
257                 if key == config.key["prevElement"]:
258                         self.parent.value = self.parent.value - 1
259                 if key == config.key["nextElement"]:
260                         self.parent.value = self.parent.value + 1
261                                         
262                 self.checkValues()      
263                 self.parent.change()    
264
265         def __call__(self, selected):                   #needed by configlist
266                 self.checkValues()
267                 return ("slider", self.parent.value * 10)
268
269 class ConfigSubsection:
270         def __init__(self):
271                 pass
272
273 class configElement:
274
275         def getIndexbyEntry(self, data):
276                 cnt = 0;
277                 tcnt = -1; #for defaultval
278                 for x in self.vals:
279                         if int(x[1]) == int(data):
280                                         return cnt
281                         if int(x[1]) == int(self.defaultValue):
282                                         tcnt = cnt
283                         cnt += 1
284                 if tcnt != -1:
285                         return tcnt                     
286                 return 0        #prevent bigger then array
287
288         def datafromFile(self, control, data):
289                 if control == ConfigSlider:
290                         return int(data);
291                 elif control == configSelection:
292                         return int(data);
293                 elif control == configSequence:
294                         list = [ ]
295                         part = data.split(self.vals[0])
296                         for x in part:
297                                 list.append(int(x))
298                         return list
299                 elif control == configSatlist:
300                         return self.getIndexbyEntry(data)
301                 else: 
302                         return ""       
303
304         def datatoFile(self, control, data):
305                 if control == ConfigSlider:
306                         return str(data);
307                 elif control == configSelection:
308                         return str(data);
309                 elif control == configSequence:
310                         value = ((len(data) * ("%d" + self.vals[0]))[0:-1]) % tuple(data)
311 #                       just in case you don't understand the above, here an equivalent:
312 #                       value = ""
313 #                       for i in data:
314 #                               if value !="":
315 #                                       value += self.vals[0]
316 #                               value += str(i)
317                         return value
318                 elif control == configSatlist:
319                         return str(self.vals[self.value][1]);
320                 else: 
321                         return ""       
322
323         def loadData(self):
324                 try:
325                         value = self.datafromFile(self.controlType, configfile.getKey(self.configPath))
326                 except:         
327                         value = ""
328
329                 if value == "":
330                         print "value not found - using default"
331
332                         if self.controlType == configSatlist:
333                                 self.value = self.getIndexbyEntry(self.defaultValue)
334                         else:   
335                                 self.value = self.defaultValue
336
337                         self.save()             #add missing value to dict
338                 else:
339                         self.value = value
340                         
341                 #is this right? activate settings after load/cancel and use default     
342                 self.change()
343
344         def __init__(self, configPath, control, defaultValue, vals):
345                 self.configPath = configPath
346                 self.defaultValue = defaultValue
347                 self.controlType = control
348                 self.vals = vals
349                 self.notifierList = [ ]
350                 self.enabled = True
351                 self.loadData()         
352         def addNotifier(self, notifier):
353                 self.notifierList.append(notifier);
354                 notifier(self);
355         def change(self):
356                 for notifier in self.notifierList:
357                         notifier(self)
358         def reload(self):
359                 self.loadData()
360         def save(self):
361                 configfile.setKey(self.configPath, self.datatoFile(self.controlType,self.value))
362
363 class configElement_nonSave(configElement):
364         def __init__(self, configPath, control, defaultValue, vals):
365                 configElement.__init__(self, configPath, control, defaultValue, vals)
366
367         def save(self):
368                 pass
369                 
370 def getConfigListEntry(description, element):
371         b = element
372         item = b.controlType(b)
373         return ((description, item))