]> rtime.felk.cvut.cz Git - CanFestival-3.git/blob - objdictgen/commondialogs.py
Adding DCFEditor Dialog to networkedit
[CanFestival-3.git] / objdictgen / commondialogs.py
1 #!/usr/bin/env python
2 # -*- coding: utf-8 -*-
3
4 #This file is part of CanFestival, a library implementing CanOpen Stack. 
5 #
6 #Copyright (C): Edouard TISSERANT, Francis DUPIN and Laurent BESSARD
7 #
8 #See COPYING file for copyrights details.
9 #
10 #This library is free software; you can redistribute it and/or
11 #modify it under the terms of the GNU Lesser General Public
12 #License as published by the Free Software Foundation; either
13 #version 2.1 of the License, or (at your option) any later version.
14 #
15 #This library is distributed in the hope that it will be useful,
16 #but WITHOUT ANY WARRANTY; without even the implied warranty of
17 #MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
18 #Lesser General Public License for more details.
19 #
20 #You should have received a copy of the GNU Lesser General Public
21 #License along with this library; if not, write to the Free Software
22 #Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
23
24 import wx
25
26 import os
27
28 from node import BE_to_LE, LE_to_BE
29
30 ScriptDirectory = os.path.split(__file__)[0]
31
32 #-------------------------------------------------------------------------------
33 #                          Editing Communication Dialog
34 #-------------------------------------------------------------------------------
35
36
37 [ID_COMMUNICATIONDIALOG, ID_COMMUNICATIONDIALOGPOSSIBLEINDEXES, 
38  ID_COMMUNICATIONDIALOGCURRENTINDEXES, ID_COMMUNICATIONDIALOGSELECT, 
39  ID_COMMUNICATIONDIALOGUNSELECT, ID_COMMUNICATIONDIALOGSTATICTEXT1, 
40  ID_COMMUNICATIONDIALOGSTATICTEXT2
41 ] = [wx.NewId() for _init_ctrls in range(7)]
42
43 class CommunicationDialog(wx.Dialog):
44     def _init_coll_flexGridSizer1_Items(self, parent):
45         parent.AddSizer(self.MainSizer, 0, border=20, flag=wx.GROW|wx.TOP|wx.LEFT|wx.RIGHT)
46         parent.AddSizer(self.ButtonSizer, 0, border=20, flag=wx.ALIGN_RIGHT|wx.BOTTOM|wx.LEFT|wx.RIGHT)
47
48     def _init_coll_flexGridSizer1_Growables(self, parent):
49         parent.AddGrowableCol(0)
50         parent.AddGrowableRow(0)
51
52     def _init_coll_MainSizer_Items(self, parent):
53         parent.AddSizer(self.LeftGridSizer, 0, border=0, flag=wx.GROW)
54         parent.AddSizer(self.MiddleGridSizer, 0, border=0, flag=wx.GROW)
55         parent.AddSizer(self.RightGridSizer, 0, border=0, flag=wx.GROW)
56
57     def _init_coll_MainSizer_Growables(self, parent):
58         parent.AddGrowableCol(0)
59         parent.AddGrowableCol(2)
60         parent.AddGrowableRow(0)
61
62     def _init_coll_LeftGridSizer_Items(self, parent):
63         parent.AddWindow(self.staticText1, 0, border=0, flag=wx.GROW)
64         parent.AddWindow(self.PossibleIndexes, 0, border=0, flag=wx.GROW)
65
66     def _init_coll_LeftGridSizer_Growables(self, parent):
67         parent.AddGrowableCol(0)
68         parent.AddGrowableRow(1)
69
70     def _init_coll_MiddleGridSizer_Items(self, parent):
71         parent.AddWindow(self.Select, 0, border=0, flag=wx.ALIGN_BOTTOM)
72         parent.AddWindow(self.Unselect, 0, border=0, flag=wx.ALIGN_TOP)
73
74     def _init_coll_MiddleGridSizer_Growables(self, parent):
75         parent.AddGrowableCol(0)
76         parent.AddGrowableRow(0)
77         parent.AddGrowableRow(1)
78
79     def _init_coll_RightGridSizer_Items(self, parent):
80         parent.AddWindow(self.staticText2, 0, border=0, flag=wx.GROW)
81         parent.AddWindow(self.CurrentIndexes, 0, border=0, flag=wx.GROW)
82
83     def _init_coll_RightGridSizer_Growables(self, parent):
84         parent.AddGrowableCol(0)
85         parent.AddGrowableRow(1)
86
87     def _init_sizers(self):
88         self.flexGridSizer1 = wx.FlexGridSizer(cols=1, hgap=0, rows=2, vgap=10)
89         self.MainSizer = wx.FlexGridSizer(cols=3, hgap=15, rows=1, vgap=0)
90         self.LeftGridSizer = wx.FlexGridSizer(cols=1, hgap=0, rows=2, vgap=5)
91         self.MiddleGridSizer = wx.FlexGridSizer(cols=1, hgap=0, rows=2, vgap=40)
92         self.RightGridSizer = wx.FlexGridSizer(cols=1, hgap=0, rows=2, vgap=5)
93         
94         self._init_coll_flexGridSizer1_Items(self.flexGridSizer1)
95         self._init_coll_flexGridSizer1_Growables(self.flexGridSizer1)
96         self._init_coll_MainSizer_Items(self.MainSizer)
97         self._init_coll_MainSizer_Growables(self.MainSizer)
98         self._init_coll_LeftGridSizer_Items(self.LeftGridSizer)
99         self._init_coll_LeftGridSizer_Growables(self.LeftGridSizer)
100         self._init_coll_MiddleGridSizer_Items(self.MiddleGridSizer)
101         self._init_coll_MiddleGridSizer_Growables(self.MiddleGridSizer)
102         self._init_coll_RightGridSizer_Items(self.RightGridSizer)
103         self._init_coll_RightGridSizer_Growables(self.RightGridSizer)
104         
105         self.SetSizer(self.flexGridSizer1)
106
107     def _init_ctrls(self, prnt):
108         wx.Dialog.__init__(self, id=ID_COMMUNICATIONDIALOG,
109               name='CommunicationDialog', parent=prnt, pos=wx.Point(234, 216),
110               size=wx.Size(726, 437), style=wx.DEFAULT_DIALOG_STYLE|wx.RESIZE_BORDER,
111               title='Edit Communication Profile')
112         self.SetClientSize(wx.Size(726, 437))
113
114         self.staticText1 = wx.StaticText(id=ID_COMMUNICATIONDIALOGSTATICTEXT1,
115               label='Possible Profile Indexes:', name='staticText1',
116               parent=self, pos=wx.Point(0, 0), size=wx.Size(0,
117               17), style=0)
118
119         self.PossibleIndexes = wx.ListBox(choices=[],
120               id=ID_COMMUNICATIONDIALOGPOSSIBLEINDEXES,
121               name='PossibleIndexes', parent=self, pos=wx.Point(0, 0), 
122               size=wx.Size(0, 0), style=wx.LB_EXTENDED)
123         self.Bind(wx.EVT_LISTBOX_DCLICK, self.OnPossibleIndexesDClick,
124               id=ID_COMMUNICATIONDIALOGPOSSIBLEINDEXES)
125
126         self.Select = wx.Button(id=ID_COMMUNICATIONDIALOGSELECT, label='>>',
127               name='Select', parent=self, pos=wx.Point(0, 0),
128               size=wx.Size(32, 32), style=0)
129         self.Select.Bind(wx.EVT_BUTTON, self.OnSelectButton,
130               id=ID_COMMUNICATIONDIALOGSELECT)
131
132         self.Unselect = wx.Button(id=ID_COMMUNICATIONDIALOGUNSELECT,
133               label='<<', name='Unselect', parent=self,
134               pos=wx.Point(0, 0), size=wx.Size(32, 32), style=0)
135         self.Unselect.Bind(wx.EVT_BUTTON, self.OnUnselectButton,
136               id=ID_COMMUNICATIONDIALOGUNSELECT)
137
138         self.staticText2 = wx.StaticText(id=ID_COMMUNICATIONDIALOGSTATICTEXT2,
139               label='Current Profile Indexes:', name='staticText2',
140               parent=self, pos=wx.Point(0, 0), size=wx.Size(0,
141               17), style=0)
142
143         self.CurrentIndexes = wx.ListBox(choices=[],
144               id=ID_COMMUNICATIONDIALOGCURRENTINDEXES, name='CurrentIndexes',
145               parent=self, pos=wx.Point(0, 0), size=wx.Size(0, 0), 
146               style=wx.LB_EXTENDED)
147         self.Bind(wx.EVT_LISTBOX_DCLICK, self.OnCurrentIndexesDClick,
148               id=ID_COMMUNICATIONDIALOGCURRENTINDEXES)
149
150         self.ButtonSizer = self.CreateButtonSizer(wx.OK|wx.CANCEL)
151         
152         self._init_sizers()
153
154     def __init__(self, parent):
155         self._init_ctrls(parent)
156         self.AllList = []
157         self.CurrentList = []
158         self.IndexDictionary = {}
159
160     def SetIndexDictionary(self, dictionary):
161         self.IndexDictionary = dictionary
162         
163     def SetCurrentList(self, list):
164         self.CurrentList = []
165         self.CurrentList.extend(list)
166         self.CurrentList.sort()
167         
168     def GetCurrentList(self):
169         return self.CurrentList
170         
171     def RefreshLists(self):
172         self.PossibleIndexes.Clear()
173         self.CurrentIndexes.Clear()
174         self.AllList = []
175         for index in self.IndexDictionary.iterkeys():
176             if index not in self.CurrentList:
177                 self.AllList.append(index)
178         self.AllList.sort()
179         for index in self.AllList:
180             self.PossibleIndexes.Append("0x%04X   %s"%(index, self.IndexDictionary[index][0]))
181         for index in self.CurrentList:
182             if index in self.IndexDictionary:
183                 self.CurrentIndexes.Append("0x%04X   %s"%(index, self.IndexDictionary[index][0]))
184
185     def OnPossibleIndexesDClick(self, event):
186         self.SelectPossible()
187         event.Skip()
188
189     def OnCurrentIndexesDClick(self, event):
190         self.UnselectCurrent()
191         event.Skip()
192
193     def OnSelectButton(self, event):
194         self.SelectPossible()
195         event.Skip()
196
197     def OnUnselectButton(self, event):
198         self.UnselectCurrent()
199         event.Skip()
200
201     def SelectPossible(self):
202         selected = self.PossibleIndexes.GetSelections()
203         for i in selected:
204             self.CurrentList.append(self.AllList[i])
205         self.CurrentList.sort()
206         self.RefreshLists()
207
208     def UnselectCurrent(self):
209         selected = self.CurrentIndexes.GetSelections()
210         for i in selected:
211             if not self.IndexDictionary[self.CurrentList[i]][1]:
212                 self.CurrentList.pop(i)
213         self.CurrentList.sort()
214         self.RefreshLists()
215
216
217
218 #-------------------------------------------------------------------------------
219 #                          Create Map Variable Dialog
220 #-------------------------------------------------------------------------------
221
222
223 [ID_MAPVARIABLEDIALOG, ID_MAPVARIABLEDIALOGINDEX, 
224  ID_MAPVARIABLEDIALOGINDEXNAME, ID_MAPVARIABLEDIALOGSPACER, 
225  ID_MAPVARIABLEDIALOGSPACER2, ID_MAPVARIABLEDIALOGNUMBER, 
226  ID_MAPVARIABLEDIALOGRADIOBUTTON1, ID_MAPVARIABLEDIALOGRADIOBUTTON2, 
227  ID_MAPVARIABLEDIALOGRADIOBUTTON3, ID_MAPVARIABLEDIALOGSTATICTEXT1, 
228  ID_MAPVARIABLEDIALOGSTATICTEXT2, ID_MAPVARIABLEDIALOGSTATICTEXT3, 
229  ID_MAPVARIABLEDIALOGSTATICTEXT4, 
230 ] = [wx.NewId() for _init_ctrls in range(13)]
231
232 class MapVariableDialog(wx.Dialog):
233     def _init_coll_flexGridSizer1_Items(self, parent):
234         parent.AddSizer(self.MainSizer, 0, border=20, flag=wx.GROW|wx.TOP|wx.LEFT|wx.RIGHT)
235         parent.AddSizer(self.ButtonSizer, 0, border=20, flag=wx.ALIGN_RIGHT|wx.BOTTOM|wx.LEFT|wx.RIGHT)
236
237     def _init_coll_flexGridSizer1_Growables(self, parent):
238         parent.AddGrowableCol(0)
239         parent.AddGrowableRow(0)
240
241     def _init_coll_MainSizer_Items(self, parent):
242         parent.AddWindow(self.staticText1, 0, border=0, flag=wx.GROW)
243         parent.AddWindow(self.staticText2, 0, border=0, flag=wx.GROW)
244         parent.AddWindow(self.Spacer, 0, border=0, flag=wx.GROW)
245         parent.AddWindow(self.Index, 0, border=0, flag=wx.GROW)
246         parent.AddWindow(self.radioButton1, 0, border=0, flag=wx.GROW)
247         parent.AddWindow(self.Spacer2, 0, border=0, flag=wx.GROW)
248         parent.AddWindow(self.staticText3, 0, border=0, flag=wx.GROW)
249         parent.AddWindow(self.radioButton2, 0, border=0, flag=wx.GROW)
250         parent.AddWindow(self.staticText4, 0, border=0, flag=wx.GROW)
251         parent.AddWindow(self.IndexName, 0, border=0, flag=wx.GROW)
252         parent.AddWindow(self.radioButton3, 0, border=0, flag=wx.GROW)
253         parent.AddWindow(self.Number, 0, border=0, flag=wx.GROW)
254         
255     def _init_coll_MainSizer_Growables(self, parent):
256         parent.AddGrowableCol(0)
257         parent.AddGrowableCol(2)
258
259     def _init_sizers(self):
260         self.flexGridSizer1 = wx.FlexGridSizer(cols=1, hgap=0, rows=2, vgap=10)
261         self.MainSizer = wx.FlexGridSizer(cols=3, hgap=30, rows=4, vgap=5)
262         
263         self._init_coll_flexGridSizer1_Items(self.flexGridSizer1)
264         self._init_coll_flexGridSizer1_Growables(self.flexGridSizer1)
265         self._init_coll_MainSizer_Items(self.MainSizer)
266         self._init_coll_MainSizer_Growables(self.MainSizer)
267         
268         self.SetSizer(self.flexGridSizer1)
269
270     def _init_ctrls(self, prnt):
271         wx.Dialog.__init__(self, id=ID_MAPVARIABLEDIALOG,
272               name='CommunicationDialog', parent=prnt, pos=wx.Point(376, 223),
273               size=wx.Size(444, 186), style=wx.DEFAULT_DIALOG_STYLE,
274               title='Add Map Variable')
275         self.SetClientSize(wx.Size(444, 186))
276
277         self.staticText1 = wx.StaticText(id=ID_MAPVARIABLEDIALOGSTATICTEXT1,
278               label='Index:', name='staticText1', parent=self,
279               pos=wx.Point(0, 0), size=wx.Size(0, 17), style=0)
280
281         self.staticText2 = wx.StaticText(id=ID_MAPVARIABLEDIALOGSTATICTEXT2,
282               label='Type:', name='staticText2', parent=self,
283               pos=wx.Point(0, 0), size=wx.Size(0, 17), style=0)
284
285         self.staticText3 = wx.StaticText(id=ID_MAPVARIABLEDIALOGSTATICTEXT3,
286               label='Name:', name='staticText3', parent=self,
287               pos=wx.Point(0, 0), size=wx.Size(0, 17), style=0)
288
289         self.staticText4 = wx.StaticText(id=ID_MAPVARIABLEDIALOGSTATICTEXT4,
290               label='Number:', name='staticText4', parent=self,
291               pos=wx.Point(0, 0), size=wx.Size(0, 16), style=0)
292
293         self.radioButton1 = wx.RadioButton(id=ID_MAPVARIABLEDIALOGRADIOBUTTON1,
294               label='VAR', name='radioButton1', parent=self,
295               pos=wx.Point(0, 0), size=wx.Size(80, 24), style=wx.RB_GROUP)
296         self.radioButton1.SetValue(True)
297         self.radioButton1.Bind(wx.EVT_RADIOBUTTON, self.OnRadioButton1Click,
298               id=ID_MAPVARIABLEDIALOGRADIOBUTTON1)
299
300         self.radioButton2 = wx.RadioButton(id=ID_MAPVARIABLEDIALOGRADIOBUTTON2,
301               label='ARRAY', name='radioButton2', parent=self,
302               pos=wx.Point(0, 0), size=wx.Size(80, 24), style=wx.RB_SINGLE)
303         self.radioButton2.SetValue(False)
304         self.radioButton2.Bind(wx.EVT_RADIOBUTTON, self.OnRadioButton2Click,
305               id=ID_MAPVARIABLEDIALOGRADIOBUTTON2)
306
307         self.radioButton3 = wx.RadioButton(id=ID_MAPVARIABLEDIALOGRADIOBUTTON3,
308               label='REC', name='radioButton3', parent=self,
309               pos=wx.Point(0, 0), size=wx.Size(80, 24), style=wx.RB_SINGLE)
310         self.radioButton3.SetValue(False)
311         self.radioButton3.Bind(wx.EVT_RADIOBUTTON, self.OnRadioButton3Click,
312               id=ID_MAPVARIABLEDIALOGRADIOBUTTON3)
313
314         self.Index = wx.TextCtrl(id=ID_MAPVARIABLEDIALOGINDEX, name='Index',
315               parent=self, pos=wx.Point(0, 0), size=wx.Size(0, 25), 
316               style=0, value='0x2000')
317         
318         self.IndexName = wx.TextCtrl(id=ID_MAPVARIABLEDIALOGINDEXNAME,
319               name='IndexName', parent=self, pos=wx.Point(0, 0),
320               size=wx.Size(0, 24), style=0, value='Undefined')
321         
322         self.Number = wx.TextCtrl(id=ID_MAPVARIABLEDIALOGNUMBER,
323               name='Number', parent=self, pos=wx.Point(0, 0),
324               size=wx.Size(0, 24), style=wx.TE_RIGHT, value='0')
325         
326         self.Spacer = wx.Panel(id=ID_MAPVARIABLEDIALOGSPACER,
327               name='Spacer', parent=self, pos=wx.Point(0, 0),
328               size=wx.Size(0, 0), style=wx.TAB_TRAVERSAL)
329         
330         self.Spacer2 = wx.Panel(id=ID_MAPVARIABLEDIALOGSPACER2,
331               name='Spacer2', parent=self, pos=wx.Point(0, 0),
332               size=wx.Size(0, 0), style=wx.TAB_TRAVERSAL)
333         
334         self.ButtonSizer = self.CreateButtonSizer(wx.OK|wx.CANCEL)
335         self.Bind(wx.EVT_BUTTON, self.OnOK, id=self.ButtonSizer.GetAffirmativeButton().GetId())
336         
337         self._init_sizers()
338
339     def __init__(self, parent):
340         self._init_ctrls(parent)
341         self.staticText4.Enable(False)
342         self.Number.Enable(False)
343         
344     def SetIndex(self, index):
345         self.Index.SetValue("0x%04X"%index)
346
347     def OnOK(self, event):
348         error = []
349         try:
350             int(self.Index.GetValue(), 16)
351         except:
352             error.append("Index")
353         if self.radioButton2.GetValue() or self.radioButton3.GetValue():
354             try:
355                 int(self.Number.GetValue())
356             except:
357                 error.append("Number")
358         if len(error) > 0:
359             text = ""
360             if len(error) > 1:
361                 suffix = "s"
362             else:
363                 suffix = ""
364             for i, item in enumerate(error):
365                 if i == 0:
366                     text += item
367                 elif i == len(error) - 1:
368                     text += " and %s"%item
369                 else:
370                     text += ", %s"%item
371             message = wx.MessageDialog(self, "Form isn't valid. %s must be integer%s!"%(text,suffix), "Error", wx.OK|wx.ICON_ERROR)
372             message.ShowModal()
373             message.Destroy()
374         else:
375             self.EndModal(wx.ID_OK)
376
377     def GetValues(self):
378         name = self.IndexName.GetValue()
379         index = int(self.Index.GetValue(), 16)
380         if self.radioButton1.GetValue():
381             struct = 1
382             number = None
383         elif self.radioButton2.GetValue():
384             struct = 3
385             number = int(self.Number.GetValue())
386         elif self.radioButton3.GetValue():
387             struct = 7
388             number = int(self.Number.GetValue())
389         return index, name, struct, number
390
391     def OnRadioButton1Click(self, event):
392         self.EnableNumberTyping(False)
393         event.Skip()
394
395     def OnRadioButton2Click(self, event):
396         self.EnableNumberTyping(True)
397         event.Skip()
398
399     def OnRadioButton3Click(self, event):
400         self.EnableNumberTyping(True)
401         event.Skip()
402
403     def EnableNumberTyping(self, enable):
404         self.staticText4.Enable(enable)
405         self.Number.Enable(enable)
406
407
408 #-------------------------------------------------------------------------------
409 #                          Create User Type Dialog
410 #-------------------------------------------------------------------------------
411
412
413 [ID_USERTYPEDIALOG, ID_USERTYPEDIALOGSPACER, 
414  ID_USERTYPEDIALOGTYPE, ID_USERTYPEDIALOGMAX, 
415  ID_USERTYPEDIALOGMIN, ID_USERTYPEDIALOGLENGTH, 
416  ID_USERTYPEDIALOGSTATICBOX1, ID_USERTYPEDIALOGSTATICTEXT1, 
417  ID_USERTYPEDIALOGSTATICTEXT2, ID_USERTYPEDIALOGSTATICTEXT3, 
418  ID_USERTYPEDIALOGSTATICTEXT4,  
419 ] = [wx.NewId() for _init_ctrls in range(11)]
420
421 class UserTypeDialog(wx.Dialog):
422     def _init_coll_flexGridSizer1_Items(self, parent):
423         parent.AddSizer(self.MainSizer, 0, border=20, flag=wx.GROW|wx.TOP|wx.LEFT|wx.RIGHT)
424         parent.AddSizer(self.ButtonSizer, 0, border=20, flag=wx.ALIGN_RIGHT|wx.BOTTOM|wx.LEFT|wx.RIGHT)
425
426     def _init_coll_flexGridSizer1_Growables(self, parent):
427         parent.AddGrowableCol(0)
428         parent.AddGrowableRow(0)
429
430     def _init_coll_MainSizer_Items(self, parent):
431         parent.AddSizer(self.LeftGridSizer, 2, border=5, flag=wx.GROW|wx.RIGHT)
432         parent.AddSizer(self.RightBoxSizer, 3, border=5, flag=wx.GROW|wx.LEFT)
433
434     def _init_coll_LeftGridSizer_Items(self, parent):
435         parent.AddWindow(self.staticText1, 0, border=0, flag=wx.GROW)
436         parent.AddWindow(self.Type, 0, border=0, flag=wx.GROW)
437         parent.AddWindow(self.Spacer, 0, border=0, flag=wx.GROW)
438
439     def _init_coll_LeftGridSizer_Growables(self, parent):
440         parent.AddGrowableCol(0)
441         parent.AddGrowableRow(2)
442
443     def _init_coll_RightBoxSizer_Items(self, parent):
444         parent.AddSizer(self.RightBoxGridSizer, 0, border=10, flag=wx.GROW|wx.ALL)
445
446     def _init_coll_RightBoxGridSizer_Items(self, parent):
447         parent.AddWindow(self.staticText2, 0, border=0, flag=wx.GROW)
448         parent.AddWindow(self.Min, 0, border=0, flag=wx.GROW)
449         parent.AddWindow(self.staticText3, 0, border=0, flag=wx.GROW)
450         parent.AddWindow(self.Max, 0, border=0, flag=wx.GROW)
451         parent.AddWindow(self.staticText4, 0, border=0, flag=wx.GROW)
452         parent.AddWindow(self.Length, 0, border=0, flag=wx.GROW)
453         
454     def _init_coll_RightBoxGridSizer_Growables(self, parent):
455         parent.AddGrowableCol(1)
456         
457     def _init_sizers(self):
458         self.flexGridSizer1 = wx.FlexGridSizer(cols=1, hgap=0, rows=2, vgap=10)
459         self.MainSizer = wx.BoxSizer(wx.HORIZONTAL)
460         self.LeftGridSizer = wx.FlexGridSizer(cols=1, hgap=0, rows=3, vgap=5)
461         self.RightBoxSizer = wx.StaticBoxSizer(self.staticBox1, wx.VERTICAL)
462         self.RightBoxGridSizer = wx.FlexGridSizer(cols=2, hgap=5, rows=3, vgap=10)
463         
464         self._init_coll_flexGridSizer1_Items(self.flexGridSizer1)
465         self._init_coll_flexGridSizer1_Growables(self.flexGridSizer1)
466         self._init_coll_MainSizer_Items(self.MainSizer)
467         self._init_coll_LeftGridSizer_Items(self.LeftGridSizer)
468         self._init_coll_LeftGridSizer_Growables(self.LeftGridSizer)
469         self._init_coll_RightBoxSizer_Items(self.RightBoxSizer)
470         self._init_coll_RightBoxGridSizer_Items(self.RightBoxGridSizer)
471         self._init_coll_RightBoxGridSizer_Growables(self.RightBoxGridSizer)
472         
473         self.SetSizer(self.flexGridSizer1)
474
475     def _init_ctrls(self, prnt):
476         wx.Dialog.__init__(self, id=ID_USERTYPEDIALOG, name='UserTypeDialog',
477               parent=prnt, pos=wx.Point(376, 223), size=wx.Size(444, 210),
478               style=wx.DEFAULT_DIALOG_STYLE, title='Add User Type')
479         self.SetClientSize(wx.Size(444, 210))
480
481         self.staticText1 = wx.StaticText(id=ID_USERTYPEDIALOGSTATICTEXT1,
482               label='Type:', name='staticText1', parent=self,
483               pos=wx.Point(0, 0), size=wx.Size(0, 17), style=0)
484
485         self.Type = wx.Choice(choices=[], id=ID_USERTYPEDIALOGTYPE,
486               name='Type', parent=self, pos=wx.Point(0, 0),
487               size=wx.Size(0, 24), style=0)
488         self.Type.Bind(wx.EVT_CHOICE, self.OnTypeChoice,
489               id=ID_USERTYPEDIALOGTYPE)
490
491         self.Spacer = wx.Panel(id=ID_MAPVARIABLEDIALOGSPACER,
492               name='Spacer', parent=self, pos=wx.Point(0, 0),
493               size=wx.Size(0, 0), style=wx.TAB_TRAVERSAL)
494
495         self.staticBox1 = wx.StaticBox(id=ID_USERTYPEDIALOGSTATICBOX1,
496               label='Values', name='staticBox1', parent=self,
497               pos=wx.Point(0, 0), size=wx.Size(0, 0), style=0)
498
499         self.staticText2 = wx.StaticText(id=ID_USERTYPEDIALOGSTATICTEXT2,
500               label='Minimum:', name='staticText2', parent=self,
501               pos=wx.Point(0, 0), size=wx.Size(80, 17), style=0)
502
503         self.Min = wx.TextCtrl(id=ID_USERTYPEDIALOGMIN, name='Min',
504               parent=self, pos=wx.Point(0, 0), size=wx.Size(0, 24), 
505               style=wx.TE_RIGHT, value='0')
506
507         self.staticText3 = wx.StaticText(id=ID_USERTYPEDIALOGSTATICTEXT3,
508               label='Maximum:', name='staticText3', parent=self,
509               pos=wx.Point(0, 0), size=wx.Size(80, 17), style=0)
510
511         self.Max = wx.TextCtrl(id=ID_USERTYPEDIALOGMAX, name='Max',
512               parent=self, pos=wx.Point(0, 0), size=wx.Size(0, 24), 
513               style=wx.TE_RIGHT, value='0')
514
515         self.staticText4 = wx.StaticText(id=ID_USERTYPEDIALOGSTATICTEXT4,
516               label='Length:', name='staticText4', parent=self,
517               pos=wx.Point(0, 0), size=wx.Size(80, 17), style=0)
518
519         self.Length = wx.TextCtrl(id=ID_USERTYPEDIALOGLENGTH, name='Length',
520               parent=self, pos=wx.Point(0, 0), size=wx.Size(0, 24), 
521               style=wx.TE_RIGHT, value='0')
522
523         self.ButtonSizer = self.CreateButtonSizer(wx.OK|wx.CANCEL)
524         self.Bind(wx.EVT_BUTTON, self.OnOK, id=self.ButtonSizer.GetAffirmativeButton().GetId())
525         
526         self._init_sizers()
527
528     def __init__(self, parent):
529         self._init_ctrls(parent)
530         
531         self.TypeDictionary = {}
532
533     def OnOK(self, event):
534         error = []
535         good = True
536         firstmessage = ""
537         secondmessage = ""
538         name = self.Type.GetStringSelection()
539         if name != "":
540             valuetype = self.TypeDictionary[name][1]
541             if valuetype == 0:
542                 try:
543                     int(self.Min.GetValue(), 16)
544                 except:
545                     error.append("Minimum")
546                     good = False
547                 try:
548                     int(self.Max.GetValue(), 16)
549                 except:
550                     error.append("Maximum")
551                     good = False
552             elif valuetype == 1:
553                 try:
554                     int(self.Length.GetValue(), 16)
555                 except:
556                     error.append("Length")
557                     good = False
558             if len(error) > 0:
559                 secondmessage = ". "
560                 for i, item in enumerate(error):
561                     if i == 0:
562                         secondmessage += item
563                     elif i == len(error) - 1:
564                         secondmessage += " and %s"%item
565                     else:
566                         secondmessage += ", %s"%item
567                 secondmessage += " must be integer"
568                 if len(error) > 1:
569                     secondmessage += "s"
570         else:
571             firstmessage = ". A type must be selected"
572             good = False
573         if not good:
574             message = wx.MessageDialog(self, "Form isn't valid%s%s%s!"%(firstmessage,secondmessage), "Error", wx.OK|wx.ICON_ERROR)
575             message.ShowModal()
576             message.Destroy()
577         else:
578             self.EndModal(wx.ID_OK)
579
580     def SetValues(self, min = None, max = None, length = None):
581         if min != None:
582             self.Min.SetValue(str(min))
583         if max != None:
584             self.Max.SetValue(str(max))
585         if length != None:
586             self.Length.SetValue(str(length))
587
588     def SetTypeList(self, typedic, type = None):
589         self.Type.Clear()
590         list = []
591         for index, (name, valuetype) in typedic.iteritems():
592             self.TypeDictionary[name] = (index, valuetype)
593             list.append((index, name))
594         list.sort()
595         for index, name in list:
596             self.Type.Append(name)
597         if type != None:
598             self.Type.SetStringSelection(typedic[type][0])
599         self.RefreshValues()
600
601     def OnTypeChoice(self, event):
602         self.RefreshValues()
603         event.Skip()
604     
605     def RefreshValues(self):
606         name = self.Type.GetStringSelection()
607         if name != "":
608             valuetype = self.TypeDictionary[name][1]
609             if valuetype == 0:
610                 self.staticText2.Enable(True)
611                 self.staticText3.Enable(True)
612                 self.staticText4.Enable(False)
613                 self.Min.Enable(True)
614                 self.Max.Enable(True)
615                 self.Length.Enable(False)
616             elif valuetype == 1:
617                 self.staticText2.Enable(False)
618                 self.staticText3.Enable(False)
619                 self.staticText4.Enable(True)
620                 self.Min.Enable(False)
621                 self.Max.Enable(False)
622                 self.Length.Enable(True)
623         else:
624             self.staticText2.Enable(False)
625             self.staticText3.Enable(False)
626             self.staticText4.Enable(False)
627             self.Min.Enable(False)
628             self.Max.Enable(False)
629             self.Length.Enable(False)
630
631     def GetValues(self):
632         name = self.Type.GetStringSelection()
633         type = self.TypeDictionary[name][0]
634         min = int(self.Min.GetValue())
635         max = int(self.Max.GetValue())
636         length = int(self.Length.GetValue())
637         return type, min, max, length
638
639
640
641 #-------------------------------------------------------------------------------
642 #                          Editing Node Infos Dialog
643 #-------------------------------------------------------------------------------
644
645
646 [ID_NODEINFOSDIALOG, ID_NODEINFOSDIALOGNAME, 
647  ID_NODEINFOSDIALOGNODEID, ID_NODEINFOSDIALOGDESCRIPTION, 
648  ID_NODEINFOSDIALOGTYPE, ID_NODEINFOSDIALOGSTATICTEXT1, 
649  ID_NODEINFOSDIALOGSTATICTEXT2, ID_NODEINFOSDIALOGSTATICTEXT3, 
650  ID_NODEINFOSDIALOGSTATICTEXT4,  
651 ] = [wx.NewId() for _init_ctrls in range(9)]
652
653 class NodeInfosDialog(wx.Dialog):
654     def _init_coll_flexGridSizer1_Items(self, parent):
655         parent.AddSizer(self.MainSizer, 0, border=20, flag=wx.GROW|wx.TOP|wx.LEFT|wx.RIGHT)
656         parent.AddSizer(self.ButtonSizer, 0, border=20, flag=wx.ALIGN_RIGHT|wx.BOTTOM|wx.LEFT|wx.RIGHT)
657
658     def _init_coll_flexGridSizer1_Growables(self, parent):
659         parent.AddGrowableCol(0)
660         parent.AddGrowableRow(0)
661
662     def _init_coll_MainSizer_Items(self, parent):
663         parent.AddWindow(self.staticText1, 0, border=0, flag=wx.GROW)
664         parent.AddWindow(self.NodeName, 0, border=0, flag=wx.GROW)
665         parent.AddWindow(self.staticText2, 0, border=0, flag=wx.GROW)
666         parent.AddWindow(self.NodeID, 0, border=0, flag=wx.GROW)
667         parent.AddWindow(self.staticText3, 0, border=0, flag=wx.GROW)
668         parent.AddWindow(self.Type, 0, border=0, flag=wx.GROW)
669         parent.AddWindow(self.staticText4, 0, border=0, flag=wx.GROW)
670         parent.AddWindow(self.Description, 0, border=0, flag=wx.GROW)
671
672     def _init_coll_MainSizer_Growables(self, parent):
673         parent.AddGrowableCol(0)
674
675     def _init_sizers(self):
676         self.flexGridSizer1 = wx.FlexGridSizer(cols=1, hgap=0, rows=2, vgap=10)
677         self.MainSizer = wx.FlexGridSizer(cols=1, hgap=0, rows=8, vgap=5)
678         
679         self._init_coll_flexGridSizer1_Items(self.flexGridSizer1)
680         self._init_coll_flexGridSizer1_Growables(self.flexGridSizer1)
681         self._init_coll_MainSizer_Items(self.MainSizer)
682         self._init_coll_MainSizer_Growables(self.MainSizer)
683         
684         self.SetSizer(self.flexGridSizer1)
685         
686     def _init_ctrls(self, prnt):
687         wx.Dialog.__init__(self, id=ID_NODEINFOSDIALOG,
688               name='NodeInfosDialog', parent=prnt, pos=wx.Point(376, 223),
689               size=wx.Size(300, 280), style=wx.DEFAULT_DIALOG_STYLE,
690               title='Node Infos')
691         self.SetClientSize(wx.Size(300, 280))
692
693         self.staticText1 = wx.StaticText(id=ID_NODEINFOSDIALOGSTATICTEXT1,
694               label='Name:', name='staticText1', parent=self,
695               pos=wx.Point(0, 0), size=wx.Size(0, 17), style=0)
696
697         self.NodeName = wx.TextCtrl(id=ID_NODEINFOSDIALOGNAME, name='NodeName',
698               parent=self, pos=wx.Point(0, 0), size=wx.Size(0, 24), 
699               style=0, value='')
700
701         self.staticText2 = wx.StaticText(id=ID_NODEINFOSDIALOGSTATICTEXT2,
702               label='Node ID:', name='staticText2', parent=self,
703               pos=wx.Point(0, 0), size=wx.Size(0, 17), style=0)
704
705         self.NodeID = wx.TextCtrl(id=ID_NODEINFOSDIALOGNODEID, name='NodeID',
706               parent=self, pos=wx.Point(0, 0), size=wx.Size(0, 25), 
707               style=wx.TE_RIGHT, value='')
708
709         self.staticText3 = wx.StaticText(id=ID_NODEINFOSDIALOGSTATICTEXT3,
710               label='Type:', name='staticText3', parent=self,
711               pos=wx.Point(0, 0), size=wx.Size(0, 17), style=0)
712
713         self.Type = wx.Choice(choices=[], id=ID_NODEINFOSDIALOGTYPE,
714               name='Type', parent=self, pos=wx.Point(0, 0),
715               size=wx.Size(0, 25), style=0)
716
717         self.staticText4 = wx.StaticText(id=ID_NODEINFOSDIALOGSTATICTEXT4,
718               label='Description:', name='staticText4', parent=self,
719               pos=wx.Point(0, 0), size=wx.Size(0, 17), style=0)
720
721         self.Description = wx.TextCtrl(id=ID_NODEINFOSDIALOGDESCRIPTION, 
722               name='Description', parent=self, pos=wx.Point(0, 0), 
723               size=wx.Size(0, 24), style=0, value='')
724
725         self.ButtonSizer = self.CreateButtonSizer(wx.OK|wx.CANCEL)
726         self.Bind(wx.EVT_BUTTON, self.OnOK, id=self.ButtonSizer.GetAffirmativeButton().GetId())
727         
728         self._init_sizers()
729
730     def __init__(self, parent):
731         self._init_ctrls(parent)
732         
733         self.staticText2.Hide()
734         self.NodeID.Hide()
735         
736         self.Type.Append("master")
737         self.Type.Append("slave")
738
739     def OnOK(self, event):
740         name = self.NodeName.GetValue()
741         message = ""
742         if name != "":
743             good = not name[0].isdigit()
744             for item in name.split("_"):
745                 good &= item.isalnum()
746             if not good:
747                 message = "Node name can't be undefined or start with a digit and must be composed of alphanumerical characters or underscore!"
748         if message != "":
749             try:
750                 nodeid = int(self.NodeID.GetValue(), 16)
751             except:
752                 message = "Node ID must be integer!"
753         if message != "":
754             message = wx.MessageDialog(self, message, "ERROR", wx.OK|wx.ICON_ERROR)
755             message.ShowModal()
756             message.Destroy()
757             self.NodeName.SetFocus()
758         else:
759             self.EndModal(wx.ID_OK)
760     
761     def SetValues(self, name, id, type, description):
762         self.NodeName.SetValue(name)
763         self.NodeID.SetValue("0x%02X"%id)
764         self.Type.SetStringSelection(type)
765         self.Description.SetValue(description)
766
767     def GetValues(self):
768         name = self.NodeName.GetValue()
769         nodeid = int(self.NodeID.GetValue(), 16)
770         type = self.Type.GetStringSelection()
771         description = self.Description.GetValue()
772         return name, nodeid, type, description
773
774
775
776 #-------------------------------------------------------------------------------
777 #                          Create New Node Dialog
778 #-------------------------------------------------------------------------------
779
780
781 [ID_CREATENODEDIALOG, ID_CREATENODEDIALOGEMERGENCY, 
782  ID_CREATENODEDIALOGGENSYNC, ID_CREATENODEDIALOGSPACER, 
783  ID_CREATENODEDIALOGNAME, ID_CREATENODEDIALOGNMT_HEARTBEAT, 
784  ID_CREATENODEDIALOGNMT_NODEGUARDING, ID_CREATENODEDIALOGNMT_NONE, 
785  ID_CREATENODEDIALOGNODEID, ID_CREATENODEDIALOGPROFILE, 
786  ID_CREATENODEDIALOGSAVECONFIG, ID_CREATENODEDIALOGSTATICTEXT1, 
787  ID_CREATENODEDIALOGSTATICTEXT2, ID_CREATENODEDIALOGSTATICTEXT3, 
788  ID_CREATENODEDIALOGSTATICTEXT4, ID_CREATENODEDIALOGSTATICTEXT5, 
789  ID_CREATENODEDIALOGSTATICTEXT6, ID_CREATENODEDIALOGSTATICTEXT7,
790  ID_CREATENODEDIALOGSTOREEDS, ID_CREATENODEDIALOGDESCRIPTION,
791  ID_CREATENODEDIALOGTYPE, 
792 ] = [wx.NewId() for _init_ctrls in range(21)]
793
794 class CreateNodeDialog(wx.Dialog):
795     def _init_coll_flexGridSizer1_Items(self, parent):
796         parent.AddSizer(self.MainSizer, 0, border=20, flag=wx.GROW|wx.TOP|wx.LEFT|wx.RIGHT)
797         parent.AddSizer(self.ButtonSizer, 0, border=20, flag=wx.ALIGN_RIGHT|wx.BOTTOM|wx.LEFT|wx.RIGHT)
798
799     def _init_coll_flexGridSizer1_Growables(self, parent):
800         parent.AddGrowableCol(0)
801         parent.AddGrowableRow(0)
802
803     def _init_coll_MainSizer_Items(self, parent):
804         parent.AddSizer(self.TopBoxSizer, 0, border=0, flag=wx.GROW)
805         parent.AddWindow(self.staticText7, 0, border=0, flag=wx.GROW)
806         parent.AddWindow(self.Description, 0, border=0, flag=wx.GROW)
807
808     def _init_coll_MainSizer_Growables(self, parent):
809         parent.AddGrowableCol(0)
810         parent.AddGrowableCol(0)
811     
812     def _init_coll_TopBoxSizer_Items(self, parent):
813         parent.AddSizer(self.LeftBoxSizer, 1, border=10, flag=wx.GROW|wx.RIGHT)
814         parent.AddSizer(self.RightGridSizer, 1, border=10, flag=wx.GROW|wx.LEFT)
815     
816     def _init_coll_LeftBoxSizer_Items(self, parent):
817         parent.AddWindow(self.staticText1, 0, border=5, flag=wx.GROW|wx.BOTTOM)
818         parent.AddWindow(self.Type, 0, border=10, flag=wx.GROW|wx.BOTTOM)
819         parent.AddWindow(self.staticText2, 0, border=5, flag=wx.GROW|wx.BOTTOM)
820         parent.AddWindow(self.NodeName, 0, border=10, flag=wx.GROW|wx.BOTTOM)
821         parent.AddWindow(self.staticText3, 0, border=5, flag=wx.GROW|wx.BOTTOM)
822         parent.AddWindow(self.NodeID, 0, border=10, flag=wx.GROW|wx.BOTTOM)
823         parent.AddWindow(self.staticText4, 0, border=5, flag=wx.GROW|wx.BOTTOM)
824         parent.AddWindow(self.Profile, 0, border=20, flag=wx.GROW|wx.BOTTOM)
825
826     def _init_coll_RightGridSizer_Items(self, parent):
827         parent.AddSizer(self.RightTopGridSizer, 0, border=0, flag=wx.GROW)
828         parent.AddWindow(self.Spacer, 0, border=0, flag=wx.GROW)
829         parent.AddSizer(self.RightBottomGridSizer, 0, border=0, flag=wx.GROW)
830
831     def _init_coll_RightGridSizer_Growables(self, parent):
832         parent.AddGrowableCol(0)
833         parent.AddGrowableRow(1)
834
835     def _init_coll_RightTopGridSizer_Items(self, parent):
836         parent.AddWindow(self.staticText5, 0, border=0, flag=wx.GROW)
837         parent.AddWindow(self.NMT_None, 0, border=0, flag=wx.GROW)
838         parent.AddWindow(self.NMT_NodeGuarding, 0, border=0, flag=wx.GROW)
839         parent.AddWindow(self.NMT_Heartbeat, 0, border=0, flag=wx.GROW)
840         
841     def _init_coll_RightTopGridSizer_Growables(self, parent):
842         parent.AddGrowableCol(0)
843         
844     def _init_coll_RightBottomGridSizer_Items(self, parent):
845         parent.AddWindow(self.staticText6, 0, border=0, flag=wx.GROW)
846         parent.AddWindow(self.DS302, 0, border=0, flag=wx.GROW)
847         parent.AddWindow(self.GenSYNC, 0, border=0, flag=wx.GROW)
848         parent.AddWindow(self.Emergency, 0, border=0, flag=wx.GROW)
849         parent.AddWindow(self.SaveConfig, 0, border=0, flag=wx.GROW)
850         parent.AddWindow(self.StoreEDS, 0, border=0, flag=wx.GROW)
851         
852     def _init_coll_RightBottomGridSizer_Growables(self, parent):
853         parent.AddGrowableCol(0)
854
855     def _init_sizers(self):
856         self.flexGridSizer1 = wx.FlexGridSizer(cols=1, hgap=0, rows=2, vgap=10)
857         self.MainSizer = wx.FlexGridSizer(cols=1, hgap=5, rows=3, vgap=0)
858         self.TopBoxSizer = wx.BoxSizer(wx.HORIZONTAL)
859         self.LeftBoxSizer = wx.BoxSizer(wx.VERTICAL)
860         self.RightGridSizer = wx.FlexGridSizer(cols=1, hgap=0, rows=3, vgap=5)
861         self.RightTopGridSizer = wx.FlexGridSizer(cols=1, hgap=0, rows=4, vgap=0)
862         self.RightBottomGridSizer = wx.FlexGridSizer(cols=1, hgap=0, rows=6, vgap=0)
863         
864         self._init_coll_flexGridSizer1_Items(self.flexGridSizer1)
865         self._init_coll_flexGridSizer1_Growables(self.flexGridSizer1)
866         self._init_coll_MainSizer_Items(self.MainSizer)
867         self._init_coll_MainSizer_Growables(self.MainSizer)
868         self._init_coll_TopBoxSizer_Items(self.TopBoxSizer)
869         self._init_coll_LeftBoxSizer_Items(self.LeftBoxSizer)
870         self._init_coll_RightGridSizer_Items(self.RightGridSizer)
871         self._init_coll_RightGridSizer_Growables(self.RightGridSizer)
872         self._init_coll_RightTopGridSizer_Items(self.RightTopGridSizer)
873         self._init_coll_RightTopGridSizer_Growables(self.RightTopGridSizer)
874         self._init_coll_RightBottomGridSizer_Items(self.RightBottomGridSizer)
875         self._init_coll_RightBottomGridSizer_Growables(self.RightBottomGridSizer)
876         
877         self.SetSizer(self.flexGridSizer1)
878
879     def _init_ctrls(self, prnt):
880         wx.Dialog.__init__(self, id=ID_CREATENODEDIALOG,
881               name='CreateNodeDialog', parent=prnt, pos=wx.Point(376, 223),
882               size=wx.Size(450, 350), style=wx.DEFAULT_DIALOG_STYLE,
883               title='Create a new Node')
884         self.SetClientSize(wx.Size(450, 350))
885
886         self.staticText1 = wx.StaticText(id=ID_CREATENODEDIALOGSTATICTEXT1,
887               label='Type:', name='staticText1', parent=self,
888               pos=wx.Point(0, 0), size=wx.Size(0, 17), style=0)
889
890         self.staticText2 = wx.StaticText(id=ID_CREATENODEDIALOGSTATICTEXT2,
891               label='Name:', name='staticText2', parent=self,
892               pos=wx.Point(0, 0), size=wx.Size(0, 17), style=0)
893
894         self.staticText3 = wx.StaticText(id=ID_CREATENODEDIALOGSTATICTEXT3,
895               label='Node ID:', name='staticText3', parent=self,
896               pos=wx.Point(0, 0), size=wx.Size(0, 17), style=0)
897
898         self.staticText4 = wx.StaticText(id=ID_CREATENODEDIALOGSTATICTEXT4,
899               label='Profile:', name='staticText4', parent=self,
900               pos=wx.Point(0, 0), size=wx.Size(0, 17), style=0)
901
902         self.Type = wx.Choice(choices=[], id=ID_CREATENODEDIALOGTYPE,
903               name='Type', parent=self, pos=wx.Point(0, 0),
904               size=wx.Size(0, 25), style=0)
905
906         self.NodeName = wx.TextCtrl(id=ID_CREATENODEDIALOGNAME, name='NodeName',
907               parent=self, pos=wx.Point(0, 0), size=wx.Size(0, 24), 
908               style=0, value='')
909
910         self.NodeID = wx.TextCtrl(id=ID_CREATENODEDIALOGNODEID, name='NodeID',
911               parent=self, pos=wx.Point(0, 0), size=wx.Size(0, 24), 
912               style=wx.TE_RIGHT, value='')
913
914         self.Profile = wx.Choice(choices=[], id=ID_CREATENODEDIALOGPROFILE,
915               name='Profile', parent=self, pos=wx.Point(0, 0),
916               size=wx.Size(0, 24), style=0)
917         self.Profile.Bind(wx.EVT_CHOICE, self.OnProfileChoice,
918               id=ID_CREATENODEDIALOGPROFILE)
919
920         self.staticText5 = wx.StaticText(id=ID_CREATENODEDIALOGSTATICTEXT5,
921               label='Network Management:', name='staticText5',
922               parent=self, pos=wx.Point(0, 0), size=wx.Size(0, 17), style=0)
923
924         self.NMT_None = wx.RadioButton(id=ID_CREATENODEDIALOGNMT_NONE,
925               label='None', name='NMT_None', parent=self,
926               pos=wx.Point(0, 0), size=wx.Size(0, 24), style=0)
927         self.NMT_None.SetValue(True)
928
929         self.NMT_NodeGuarding = wx.RadioButton(id=ID_CREATENODEDIALOGNMT_NODEGUARDING,
930               label='Node Guarding', name='NMT_NodeGuarding', parent=self, 
931               pos=wx.Point(0, 0), size=wx.Size(0, 24), style=0)
932         self.NMT_NodeGuarding.SetValue(False)
933
934         self.NMT_Heartbeat = wx.RadioButton(id=ID_CREATENODEDIALOGNMT_HEARTBEAT,
935               label='Heartbeat', name='NMT_Heartbeat', parent=self,
936               pos=wx.Point(0, 0), size=wx.Size(0, 24), style=0)
937         self.NMT_Heartbeat.SetValue(False)
938
939         self.staticText6 = wx.StaticText(id=ID_CREATENODEDIALOGSTATICTEXT6,
940               label='Options:', name='staticText6', parent=self,
941               pos=wx.Point(0, 0), size=wx.Size(0, 17), style=0)
942
943         self.DS302 = wx.CheckBox(id=ID_CREATENODEDIALOGGENSYNC,
944               label='DS-302 Profile', name='DS302', parent=self,
945               pos=wx.Point(0, 0), size=wx.Size(0, 24), style=0)
946         self.DS302.SetValue(False)
947         #self.DS302.Enable(False)
948
949         self.GenSYNC = wx.CheckBox(id=ID_CREATENODEDIALOGGENSYNC,
950               label='Generate SYNC', name='GenSYNC', parent=self,
951               pos=wx.Point(0, 0), size=wx.Size(0, 24), style=0)
952         self.GenSYNC.SetValue(False)
953
954         self.Emergency = wx.CheckBox(id=ID_CREATENODEDIALOGEMERGENCY,
955               label='Emergency support', name='Emergency',
956               parent=self, pos=wx.Point(0, 0), size=wx.Size(0, 24), style=0)
957         self.Emergency.SetValue(False)
958
959         self.SaveConfig = wx.CheckBox(id=ID_CREATENODEDIALOGSAVECONFIG,
960               label='Save Configuration', name='SaveConfig', parent=self, 
961               pos=wx.Point(0, 0), size=wx.Size(0, 24), style=0)
962         self.SaveConfig.SetValue(False)
963         self.SaveConfig.Enable(False)
964
965         self.StoreEDS = wx.CheckBox(id=ID_CREATENODEDIALOGSTOREEDS,
966               label='Store EDS', name='StoreEDS', parent=self,
967               pos=wx.Point(0, 0), size=wx.Size(0, 24), style=0)
968         self.StoreEDS.SetValue(False)
969         self.StoreEDS.Hide()
970
971         self.staticText7 = wx.StaticText(id=ID_CREATENODEDIALOGSTATICTEXT7,
972               label='Description:', name='staticText7', parent=self,
973               pos=wx.Point(0, 0), size=wx.Size(0, 17), style=0)
974
975         self.Description = wx.TextCtrl(id=ID_CREATENODEDIALOGDESCRIPTION, 
976               name='Description', parent=self, pos=wx.Point(0, 0), 
977               size=wx.Size(0, 24), style=0, value='')
978
979         self.Spacer = wx.Panel(id=ID_CREATENODEDIALOGSPACER,
980               name='Spacer', parent=self, pos=wx.Point(0, 0),
981               size=wx.Size(0, 0), style=wx.TAB_TRAVERSAL)
982
983         self.ButtonSizer = self.CreateButtonSizer(wx.OK|wx.CANCEL)
984         self.Bind(wx.EVT_BUTTON, self.OnOK, id=self.ButtonSizer.GetAffirmativeButton().GetId())
985         
986         self._init_sizers()
987
988     def __init__(self, parent):
989         self._init_ctrls(parent)
990         
991         self.staticText3.Hide()
992         self.NodeID.Hide()
993         
994         self.NodeID.SetValue("0x00")
995         self.Type.Append("master")
996         self.Type.Append("slave")
997         self.Type.SetStringSelection("slave")
998         self.Description.SetValue("")
999         self.ListProfile = {"None" : ""}
1000         self.Profile.Append("None")
1001         self.Directory = os.path.join(ScriptDirectory, "config")
1002         listfiles = os.listdir(self.Directory)
1003         listfiles.sort()
1004         for item in listfiles:
1005             name, extend = os.path.splitext(item)
1006             if os.path.isfile(os.path.join(self.Directory, item)) and extend == ".prf" and name != "DS-302":
1007                 self.ListProfile[name] = os.path.join(self.Directory, item)
1008                 self.Profile.Append(name)
1009         self.Profile.Append("Other")
1010         self.Profile.SetStringSelection("None")
1011         self.NodeName.SetFocus()
1012         
1013     def OnOK(self, event):
1014         name = self.NodeName.GetValue()
1015         message = ""
1016         if name != "":
1017             good = not name[0].isdigit()
1018             for item in name.split("_"):
1019                 good &= item.isalnum()
1020             if not good:
1021                 message = "Node name can't be undefined or start with a digit and must be composed of alphanumerical characters or underscore!"
1022         if message != "":
1023             try:
1024                 nodeid = int(self.NodeID.GetValue(), 16)
1025             except:
1026                 message = "Node ID must be an integer!"
1027         if message != "":
1028             message = wx.MessageDialog(self, message, "ERROR", wx.OK|wx.ICON_ERROR)
1029             message.ShowModal()
1030             message.Destroy()
1031             self.NodeName.SetFocus()
1032         else:
1033             self.EndModal(wx.ID_OK)
1034
1035     def GetValues(self):
1036         name = self.NodeName.GetValue()
1037         nodeid = 0
1038         if self.NodeID.GetValue() != "":
1039             nodeid = int(self.NodeID.GetValue(), 16)
1040         type = self.Type.GetStringSelection()
1041         description = self.Description.GetValue()
1042         return name, nodeid, type, description
1043
1044     def GetProfile(self):
1045         name = self.Profile.GetStringSelection()
1046         return name, self.ListProfile[name]
1047
1048     def GetNMTManagement(self):
1049         if self.NMT_None.GetValue():
1050             return "None"
1051         elif self.NMT_NodeGuarding.GetValue():
1052             return "NodeGuarding"
1053         elif self.NMT_Heartbeat.GetValue():
1054             return "Heartbeat"
1055         return None
1056     
1057     def GetOptions(self):
1058         options = []
1059         if self.DS302.GetValue():
1060             options.append("DS302")
1061         if self.GenSYNC.GetValue():
1062             options.append("GenSYNC")
1063         if self.Emergency.GetValue():
1064             options.append("Emergency")
1065         if self.SaveConfig.GetValue():
1066             options.append("SaveConfig")
1067         if self.StoreEDS.GetValue():
1068             options.append("StoreEDS")
1069         return options
1070
1071     def OnProfileChoice(self, event):
1072         if self.Profile.GetStringSelection() == "Other":
1073             dialog = wx.FileDialog(self, "Choose a file", self.Directory, "",  "OD Profile files (*.prf)|*.prf|All files|*.*", wx.OPEN|wx.CHANGE_DIR)
1074             dialog.ShowModal()
1075             filepath = dialog.GetPath()
1076             dialog.Destroy()
1077             if os.path.isfile(filepath):
1078                 name = os.path.splitext(os.path.basename(filepath))[0]
1079                 self.ListProfile[name] = filepath
1080                 length = self.Profile.GetCount()
1081                 self.Profile.Insert(name, length - 2)
1082                 self.Profile.SetStringSelection(name)
1083             else:
1084                 self.Profile.SetStringSelection("None")
1085         event.Skip()
1086
1087
1088 #-------------------------------------------------------------------------------
1089 #                            ADD Slave to NodeList Dialog
1090 #-------------------------------------------------------------------------------
1091
1092 [ID_ADDSLAVEDIALOG, ID_ADDSLAVEDIALOGSLAVENAME, 
1093  ID_ADDSLAVEDIALOGSLAVENODEID, ID_ADDSLAVEDIALOGEDSFILE, 
1094  ID_ADDSLAVEDIALOGIMPORTEDS, ID_ADDSLAVEDIALOGSTATICTEXT1, 
1095  ID_ADDSLAVEDIALOGSTATICTEXT2, ID_ADDSLAVEDIALOGSTATICTEXT3, 
1096 ] = [wx.NewId() for _init_ctrls in range(8)]
1097
1098 class AddSlaveDialog(wx.Dialog):
1099     def _init_coll_flexGridSizer1_Items(self, parent):
1100         parent.AddSizer(self.MainSizer, 0, border=20, flag=wx.GROW|wx.TOP|wx.LEFT|wx.RIGHT)
1101         parent.AddSizer(self.ButtonSizer, 0, border=20, flag=wx.ALIGN_RIGHT|wx.BOTTOM|wx.LEFT|wx.RIGHT)
1102
1103     def _init_coll_flexGridSizer1_Growables(self, parent):
1104         parent.AddGrowableCol(0)
1105         parent.AddGrowableRow(0)
1106
1107     def _init_coll_MainSizer_Items(self, parent):
1108         parent.AddWindow(self.staticText1, 0, border=5, flag=wx.GROW|wx.BOTTOM)
1109         parent.AddWindow(self.SlaveName, 0, border=10, flag=wx.GROW|wx.BOTTOM)
1110         parent.AddWindow(self.staticText2, 0, border=5, flag=wx.GROW|wx.BOTTOM)
1111         parent.AddWindow(self.SlaveNodeID, 0, border=10, flag=wx.GROW|wx.BOTTOM)
1112         parent.AddWindow(self.staticText3, 0, border=5, flag=wx.GROW|wx.BOTTOM)
1113         parent.AddSizer(self.BottomSizer, 0, border=0, flag=wx.GROW)
1114
1115     def _init_coll_BottomSizer_Items(self, parent):
1116         parent.AddWindow(self.EDSFile, 0, border=4, flag=wx.GROW|wx.TOP|wx.BOTTOM)
1117         parent.AddWindow(self.ImportEDS, 0, border=0, flag=0)
1118
1119     def _init_coll_BottomSizer_Growables(self, parent):
1120         parent.AddGrowableCol(0)
1121         parent.AddGrowableRow(0)
1122
1123     def _init_sizers(self):
1124         self.flexGridSizer1 = wx.FlexGridSizer(cols=1, hgap=0, rows=2, vgap=10)
1125         self.MainSizer = wx.BoxSizer(wx.VERTICAL)
1126         self.BottomSizer = wx.FlexGridSizer(cols=2, hgap=5, rows=1, vgap=0)
1127         
1128         self._init_coll_flexGridSizer1_Items(self.flexGridSizer1)
1129         self._init_coll_flexGridSizer1_Growables(self.flexGridSizer1)
1130         self._init_coll_MainSizer_Items(self.MainSizer)
1131         self._init_coll_BottomSizer_Items(self.BottomSizer)
1132         self._init_coll_BottomSizer_Growables(self.BottomSizer)
1133         
1134         self.SetSizer(self.flexGridSizer1)
1135
1136     def _init_ctrls(self, prnt):
1137         wx.Dialog.__init__(self, id=ID_ADDSLAVEDIALOG,
1138               name='AddSlaveDialog', parent=prnt, pos=wx.Point(376, 223),
1139               size=wx.Size(300, 250), style=wx.DEFAULT_DIALOG_STYLE|wx.RESIZE_BORDER,
1140               title='Add a slave to nodelist')
1141         self.SetClientSize(wx.Size(300, 250))
1142
1143         self.staticText1 = wx.StaticText(id=ID_ADDSLAVEDIALOGSTATICTEXT1,
1144               label='Slave Name:', name='staticText1', parent=self,
1145               pos=wx.Point(0, 0), size=wx.Size(0, 17), style=0)
1146
1147         self.SlaveName = wx.TextCtrl(id=ID_ADDSLAVEDIALOGSLAVENAME,
1148               name='SlaveName', parent=self, pos=wx.Point(0, 0), 
1149               size=wx.Size(0, 24), style=0)
1150
1151         self.staticText2 = wx.StaticText(id=ID_ADDSLAVEDIALOGSTATICTEXT2,
1152               label='Slave Node ID:', name='staticText2', parent=self,
1153               pos=wx.Point(0, 0), size=wx.Size(0, 17), style=0)
1154
1155         self.SlaveNodeID = wx.TextCtrl(id=ID_ADDSLAVEDIALOGSLAVENODEID,
1156               name='SlaveName', parent=self, pos=wx.Point(0, 0), 
1157               size=wx.Size(0, 24), style=wx.ALIGN_RIGHT)
1158
1159         self.staticText3 = wx.StaticText(id=ID_ADDSLAVEDIALOGSTATICTEXT3,
1160               label='EDS File:', name='staticText3', parent=self,
1161               pos=wx.Point(0, 0), size=wx.Size(0, 17), style=0)
1162
1163         self.EDSFile = wx.Choice(id=ID_ADDSLAVEDIALOGEDSFILE,
1164               name='EDSFile', parent=self, pos=wx.Point(0, 0),
1165               size=wx.Size(0, 24), style=0)
1166         
1167         self.ImportEDS = wx.Button(id=ID_ADDSLAVEDIALOGIMPORTEDS, label='Import EDS',
1168               name='ImportEDS', parent=self, pos=wx.Point(0, 0),
1169               size=wx.Size(100, 32), style=0)
1170         self.ImportEDS.Bind(wx.EVT_BUTTON, self.OnImportEDSButton,
1171               id=ID_ADDSLAVEDIALOGIMPORTEDS)
1172         
1173         self.ButtonSizer = self.CreateButtonSizer(wx.OK|wx.CANCEL|wx.CENTRE)
1174         self.Bind(wx.EVT_BUTTON, self.OnOK, id=self.ButtonSizer.GetAffirmativeButton().GetId())
1175     
1176         self._init_sizers()
1177
1178     def __init__(self, parent):
1179         self._init_ctrls(parent)
1180         
1181         self.SlaveNodeID.SetValue("0x00")
1182             
1183     def OnOK(self, event):
1184         error = []
1185         if self.SlaveName.GetValue() == "":
1186             error.append("Slave Name")
1187         if self.SlaveNodeID.GetValue() == "":
1188             error.append("Slave Node ID")
1189         if self.EDSFile.GetStringSelection() == "":
1190             error.append("EDS File")
1191         if len(error) > 0:
1192             text = ""
1193             for i, item in enumerate(error):
1194                 if i == 0:
1195                     text += item
1196                 elif i == len(error) - 1:
1197                     text += " and %s"%item
1198                 else:
1199                     text += ", %s"%item 
1200             message = wx.MessageDialog(self, "Form isn't complete. %s must be filled!"%text, "Error", wx.OK|wx.ICON_ERROR)
1201             message.ShowModal()
1202             message.Destroy()
1203         else:
1204             try:
1205                 nodeid = self.SlaveNodeID.GetValue()
1206                 if nodeid.find("x") != -1:
1207                     nodeid = int(nodeid, 16)
1208                 else:
1209                     nodeid = int(nodeid)
1210             except:
1211                 message = wx.MessageDialog(self, "Slave Node ID must be a value in decimal or hexadecimal!", "Error", wx.OK|wx.ICON_ERROR)
1212                 message.ShowModal()
1213                 message.Destroy()
1214                 return
1215             if not 0 <= nodeid <= 127:
1216                 message = wx.MessageDialog(self, "Slave Node ID must be between 0 and 127!", "Error", wx.OK|wx.ICON_ERROR)
1217                 message.ShowModal()
1218                 message.Destroy()
1219             elif nodeid == 0 or nodeid in self.NodeList.SlaveNodes.keys():
1220                 message = wx.MessageDialog(self, "A Node with this ID already exist in the network!", "Error", wx.OK|wx.ICON_ERROR)
1221                 message.ShowModal()
1222                 message.Destroy()
1223             else:
1224                 self.EndModal(wx.ID_OK)
1225
1226     def OnImportEDSButton(self, event):
1227         dialog = wx.FileDialog(self, "Choose an EDS file", os.getcwd(), "",  "EDS files (*.eds)|*.eds|All files|*.*", wx.OPEN|wx.CHANGE_DIR)
1228         if dialog.ShowModal() == wx.ID_OK:
1229             filepath = dialog.GetPath()
1230             if os.path.isfile(filepath):
1231                 result = self.NodeList.ImportEDSFile(filepath)
1232                 if result:
1233                     message = wx.MessageDialog(self, result, "Error", wx.OK|wx.ICON_ERROR)
1234                     message.ShowModal()
1235                     message.Destroy()
1236         dialog.Destroy()
1237         self.RefreshEDSFile()
1238         event.Skip()
1239
1240     def RefreshEDSFile(self):
1241         selection = self.EDSFile.GetStringSelection()
1242         self.EDSFile.Clear()
1243         for option in self.NodeList.EDSNodes.keys():
1244             self.EDSFile.Append(option)
1245         if self.EDSFile.FindString(selection) != wx.NOT_FOUND:
1246             self.EDSFile.SetStringSelection(selection)
1247     
1248     def SetNodeList(self, nodelist):
1249         self.NodeList = nodelist
1250         self.RefreshEDSFile()
1251     
1252     def GetValues(self):
1253         values = {}
1254         values["slaveName"] = self.SlaveName.GetValue()
1255         nodeid = self.SlaveNodeID.GetValue()
1256         if nodeid.find("x") != -1:
1257             values["slaveNodeID"] = int(nodeid, 16)
1258         else:
1259             values["slaveNodeID"] = int(nodeid)
1260         values["edsFile"] = self.EDSFile.GetStringSelection()
1261         return values
1262
1263 #-------------------------------------------------------------------------------
1264 #                            Editing DCF Entry Dialog
1265 #-------------------------------------------------------------------------------
1266
1267 class DCFEntryValuesTable(wx.grid.PyGridTableBase):
1268     
1269     """
1270     A custom wxGrid Table using user supplied data
1271     """
1272     def __init__(self, parent, data, colnames):
1273         # The base class must be initialized *first*
1274         wx.grid.PyGridTableBase.__init__(self)
1275         self.data = data
1276         self.colnames = colnames
1277         self.Parent = parent
1278         # XXX
1279         # we need to store the row length and collength to
1280         # see if the table has changed size
1281         self._rows = self.GetNumberRows()
1282         self._cols = self.GetNumberCols()
1283     
1284     def GetNumberCols(self):
1285         return len(self.colnames)
1286         
1287     def GetNumberRows(self):
1288         return len(self.data)
1289
1290     def GetColLabelValue(self, col):
1291         if col < len(self.colnames):
1292             return self.colnames[col]
1293
1294     def GetRowLabelValues(self, row):
1295         return row
1296
1297     def GetValue(self, row, col):
1298         if row < self.GetNumberRows():
1299             return str(self.data[row].get(self.GetColLabelValue(col), ""))
1300             
1301     def GetEditor(self, row, col):
1302         if row < self.GetNumberRows():
1303             return self.editors[row].get(self.GetColLabelValue(col), "")
1304     
1305     def GetValueByName(self, row, colname):
1306         return self.data[row].get(colname)
1307
1308     def SetValue(self, row, col, value):
1309         if col < len(self.colnames):
1310             self.data[row][self.GetColLabelValue(col)] = value
1311         
1312     def ResetView(self, grid):
1313         """
1314         (wx.grid.Grid) -> Reset the grid view.   Call this to
1315         update the grid if rows and columns have been added or deleted
1316         """
1317         grid.BeginBatch()
1318         for current, new, delmsg, addmsg in [
1319             (self._rows, self.GetNumberRows(), wx.grid.GRIDTABLE_NOTIFY_ROWS_DELETED, wx.grid.GRIDTABLE_NOTIFY_ROWS_APPENDED),
1320             (self._cols, self.GetNumberCols(), wx.grid.GRIDTABLE_NOTIFY_COLS_DELETED, wx.grid.GRIDTABLE_NOTIFY_COLS_APPENDED),
1321         ]:
1322             if new < current:
1323                 msg = wx.grid.GridTableMessage(self,delmsg,new,current-new)
1324                 grid.ProcessTableMessage(msg)
1325             elif new > current:
1326                 msg = wx.grid.GridTableMessage(self,addmsg,new-current)
1327                 grid.ProcessTableMessage(msg)
1328                 self.UpdateValues(grid)
1329         grid.EndBatch()
1330
1331         self._rows = self.GetNumberRows()
1332         self._cols = self.GetNumberCols()
1333         # update the column rendering scheme
1334         self._updateColAttrs(grid)
1335
1336         # update the scrollbars and the displayed part of the grid
1337         grid.AdjustScrollbars()
1338         grid.ForceRefresh()
1339
1340
1341     def UpdateValues(self, grid):
1342         """Update all displayed values"""
1343         # This sends an event to the grid table to update all of the values
1344         msg = wx.grid.GridTableMessage(self, wx.grid.GRIDTABLE_REQUEST_VIEW_GET_VALUES)
1345         grid.ProcessTableMessage(msg)
1346
1347     def _updateColAttrs(self, grid):
1348         """
1349         wx.grid.Grid -> update the column attributes to add the
1350         appropriate renderer given the column name.
1351
1352         Otherwise default to the default renderer.
1353         """
1354         
1355         for row in range(self.GetNumberRows()):
1356             for col in range(self.GetNumberCols()):
1357                 editor = wx.grid.GridCellTextEditor()
1358                 renderer = wx.grid.GridCellStringRenderer()
1359                     
1360                 grid.SetCellEditor(row, col, editor)
1361                 grid.SetCellRenderer(row, col, renderer)
1362                 
1363                 grid.SetCellBackgroundColour(row, col, wx.WHITE)
1364     
1365     def SetData(self, data):
1366         self.data = data
1367     
1368     def AppendRow(self, row_content):
1369         self.data.append(row_content)
1370
1371     def Empty(self):
1372         self.data = []
1373         self.editors = []
1374
1375 [ID_DCFENTRYVALUESDIALOG, ID_DCFENTRYVALUESDIALOGVALUESGRID, 
1376  ID_DCFENTRYVALUESDIALOGADDBUTTON, ID_DCFENTRYVALUESDIALOGDELETEBUTTON, 
1377  ID_DCFENTRYVALUESDIALOGUPBUTTON, ID_DCFENTRYVALUESDIALOGDOWNBUTTON, 
1378  ID_VARIABLEEDITORPANELSTATICTEXT1, 
1379 ] = [wx.NewId() for _init_ctrls in range(7)]
1380
1381 class DCFEntryValuesDialog(wx.Dialog):
1382     
1383     if wx.VERSION < (2, 6, 0):
1384         def Bind(self, event, function, id = None):
1385             if id is not None:
1386                 event(self, id, function)
1387             else:
1388                 event(self, function)
1389     
1390     def _init_coll_MainSizer_Items(self, parent):
1391         parent.AddWindow(self.staticText1, 0, border=20, flag=wx.GROW|wx.TOP|wx.LEFT|wx.RIGHT)
1392         parent.AddWindow(self.ValuesGrid, 0, border=20, flag=wx.GROW|wx.TOP|wx.LEFT|wx.RIGHT)
1393         parent.AddSizer(self.ButtonPanelSizer, 0, border=20, flag=wx.ALIGN_RIGHT|wx.LEFT|wx.RIGHT)
1394         parent.AddSizer(self.ButtonSizer, 0, border=20, flag=wx.ALIGN_RIGHT|wx.BOTTOM|wx.LEFT|wx.RIGHT)
1395     
1396     def _init_coll_MainSizer_Growables(self, parent):
1397         parent.AddGrowableCol(0)
1398         parent.AddGrowableRow(1)
1399     
1400     def _init_coll_ButtonPanelSizer_Items(self, parent):
1401         parent.AddWindow(self.UpButton, 0, border=5, flag=wx.ALL)
1402         parent.AddWindow(self.AddButton, 0, border=5, flag=wx.ALL)
1403         parent.AddWindow(self.DownButton, 0, border=5, flag=wx.ALL)
1404         parent.AddWindow(self.DeleteButton, 0, border=5, flag=wx.ALL)
1405         
1406     def _init_sizers(self):
1407         self.MainSizer = wx.FlexGridSizer(cols=1, hgap=0, rows=3, vgap=0)
1408         self.ButtonPanelSizer = wx.BoxSizer(wx.HORIZONTAL)
1409         
1410         self._init_coll_MainSizer_Items(self.MainSizer)
1411         self._init_coll_MainSizer_Growables(self.MainSizer)
1412         self._init_coll_ButtonPanelSizer_Items(self.ButtonPanelSizer)
1413         
1414         self.SetSizer(self.MainSizer)
1415
1416     def _init_ctrls(self, prnt):
1417         wx.Dialog.__init__(self, id=ID_DCFENTRYVALUESDIALOG,
1418               name='DCFEntryValuesDialog', parent=prnt, pos=wx.Point(376, 223),
1419               size=wx.Size(400, 300), style=wx.DEFAULT_DIALOG_STYLE|wx.RESIZE_BORDER,
1420               title='Edit DCF Entry Values')
1421         self.SetClientSize(wx.Size(400, 300))
1422
1423         self.staticText1 = wx.StaticText(id=ID_VARIABLEEDITORPANELSTATICTEXT1,
1424               label='Entry Values:', name='staticText1', parent=self,
1425               pos=wx.Point(0, 0), size=wx.Size(95, 17), style=0)
1426
1427         self.ValuesGrid = wx.grid.Grid(id=ID_DCFENTRYVALUESDIALOGVALUESGRID,
1428               name='ValuesGrid', parent=self, pos=wx.Point(0, 0), 
1429               size=wx.Size(0, 150), style=wx.VSCROLL)
1430         self.ValuesGrid.SetFont(wx.Font(12, 77, wx.NORMAL, wx.NORMAL, False,
1431               'Sans'))
1432         self.ValuesGrid.SetLabelFont(wx.Font(10, 77, wx.NORMAL, wx.NORMAL,
1433               False, 'Sans'))
1434         self.ValuesGrid.SetRowLabelSize(0)
1435         self.ValuesGrid.SetSelectionBackground(wx.WHITE)
1436         self.ValuesGrid.SetSelectionForeground(wx.BLACK)
1437         if wx.VERSION >= (2, 6, 0):
1438             self.ValuesGrid.Bind(wx.grid.EVT_GRID_CELL_CHANGE, self.OnValuesGridCellChange)
1439         else:
1440             wx.grid.EVT_GRID_CELL_CHANGE(self.ValuesGrid, self.OnValuesGridCellChange)
1441         
1442         self.AddButton = wx.Button(id=ID_DCFENTRYVALUESDIALOGADDBUTTON, label='Add',
1443               name='AddButton', parent=self, pos=wx.Point(0, 0),
1444               size=wx.Size(72, 32), style=0)
1445         self.Bind(wx.EVT_BUTTON, self.OnAddButton, id=ID_DCFENTRYVALUESDIALOGADDBUTTON)
1446
1447         self.DeleteButton = wx.Button(id=ID_DCFENTRYVALUESDIALOGDELETEBUTTON, label='Delete',
1448               name='DeleteButton', parent=self, pos=wx.Point(0, 0),
1449               size=wx.Size(72, 32), style=0)
1450         self.Bind(wx.EVT_BUTTON, self.OnDeleteButton, id=ID_DCFENTRYVALUESDIALOGDELETEBUTTON)
1451
1452         self.UpButton = wx.Button(id=ID_DCFENTRYVALUESDIALOGUPBUTTON, label='^',
1453               name='UpButton', parent=self, pos=wx.Point(0, 0),
1454               size=wx.Size(32, 32), style=0)
1455         self.Bind(wx.EVT_BUTTON, self.OnUpButton, id=ID_DCFENTRYVALUESDIALOGUPBUTTON)
1456
1457         self.DownButton = wx.Button(id=ID_DCFENTRYVALUESDIALOGDOWNBUTTON, label='v',
1458               name='DownButton', parent=self, pos=wx.Point(0, 0),
1459               size=wx.Size(32, 32), style=0)
1460         self.Bind(wx.EVT_BUTTON, self.OnDownButton, id=ID_DCFENTRYVALUESDIALOGDOWNBUTTON)
1461
1462         self.ButtonSizer = self.CreateButtonSizer(wx.OK|wx.CANCEL|wx.CENTRE)
1463         
1464         self._init_sizers()
1465
1466     def __init__(self, parent):
1467         self._init_ctrls(parent)
1468         
1469         self.Values = []
1470         self.DefaultValue = {"Index" : 0, "Subindex" : 0, "Size" : 1, "Value" : 0}
1471         
1472         self.Table = DCFEntryValuesTable(self, [], ["Index", "Subindex", "Size", "Value"])
1473         self.ValuesGrid.SetTable(self.Table)
1474         
1475     def OnValuesGridCellChange(self, event):
1476         row, col = event.GetRow(), event.GetCol()
1477         colname = self.Table.GetColLabelValue(col)
1478         value = self.Table.GetValue(row, col)
1479         try:
1480             self.Values[row][colname] = int(value, 16)
1481         except:
1482             message = wx.MessageDialog(self, "\"%s\" is not a valid value!"%value, "Error", wx.OK|wx.ICON_ERROR)
1483             message.ShowModal()
1484             message.Destroy()
1485         finally:
1486             wx.CallAfter(self.RefreshValues)
1487             event.Skip()
1488     
1489     def OnAddButton(self, event):
1490         new_row = self.DefaultValue.copy()
1491         self.Values.append(new_row)
1492         self.RefreshValues()
1493         event.Skip()
1494
1495     def OnDeleteButton(self, event):
1496         row = self.Table.GetRow(self.ValuesGrid.GetGridCursorRow())
1497         self.Values.remove(row)
1498         self.RefreshValues()
1499         event.Skip()
1500
1501     def OnUpButton(self, event):
1502         self.MoveValue(self.ValuesGrid.GetGridCursorRow(), -1)
1503         event.Skip()
1504
1505     def OnDownButton(self, event):
1506         self.MoveValue(self.ValuesGrid.GetGridCursorRow(), 1)
1507         event.Skip()
1508
1509     def MoveValue(self, value_index, move):
1510         new_index = max(0, min(value_index + move, len(self.Values) - 1))
1511         if new_index != value_index:
1512             self.Values.insert(new_index, self.Values.pop(value_index))
1513             self.RefreshValues()
1514             self.ValuesGrid.SetGridCursor(new_index, self.ValuesGrid.GetGridCursorCol())
1515         else:
1516             self.RefreshValues()
1517
1518     def SetValues(self, values):
1519         self.Values = []
1520         if values != "":
1521             data = values[4:]
1522             current = 0
1523             for i in xrange(BE_to_LE(values[:4])):
1524                 value = {}
1525                 value["Index"] = BE_to_LE(data[current:current+2])
1526                 value["Subindex"] = BE_to_LE(data[current+2:current+3])
1527                 size = BE_to_LE(data[current+3:current+7])
1528                 value["Size"] = size
1529                 value["Value"] = BE_to_LE(data[current+7:current+7+size])
1530                 current += 7 + size
1531                 self.Values.append(value)
1532         self.RefreshValues()
1533     
1534     def GetValues(self):
1535         value = LE_to_BE(len(self.Values), 4)
1536         for row in self.Values:
1537             value += LE_to_BE(row["Index"], 2)
1538             value += LE_to_BE(row["Subindex"], 1)
1539             value += LE_to_BE(row["Size"], 4)
1540             value += LE_to_BE(row["Value"], row["Size"])
1541         return value
1542     
1543     def RefreshValues(self):
1544         if len(self.Table.data) > 0:
1545             self.ValuesGrid.SetGridCursor(0, 1)
1546         data = []
1547         for value in self.Values:
1548             row = {}
1549             row["Index"] = "%04X"%value["Index"]
1550             row["Subindex"] = "%02X"%value["Subindex"]
1551             row["Size"] = "%08X"%value["Size"]
1552             row["Value"] = ("%0"+"%d"%(value["Size"] * 2)+"X")%value["Value"]
1553             data.append(row)
1554         self.Table.SetData(data)
1555         self.Table.ResetView(self.ValuesGrid)