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