]> rtime.felk.cvut.cz Git - CanFestival-3.git/blob - objdictgen/commondialogs.py
Inversion between Array and Record fixed
[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=wx.RB_SINGLE)
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=wx.RB_SINGLE)
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):
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=0)
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(wx.OK|wx.CANCEL)
998         self.Bind(wx.EVT_BUTTON, self.OnOK, id=self.ButtonSizer.GetAffirmativeButton().GetId())
999         
1000         self._init_sizers()
1001
1002     def __init__(self, parent):
1003         self._init_ctrls(parent)
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, "Choose an EDS file", os.getcwd(), "",  "EDS files (*.eds)|*.eds|All files|*.*", wx.OPEN|wx.CHANGE_DIR)
1242         if dialog.ShowModal() == wx.ID_OK:
1243             filepath = dialog.GetPath()
1244             if os.path.isfile(filepath):
1245                 result = self.NodeList.ImportEDSFile(filepath)
1246                 if result:
1247                     message = wx.MessageDialog(self, result, "Error", wx.OK|wx.ICON_ERROR)
1248                     message.ShowModal()
1249                     message.Destroy()
1250         dialog.Destroy()
1251         self.RefreshEDSFile()
1252         event.Skip()
1253
1254     def RefreshEDSFile(self):
1255         selection = self.EDSFile.GetStringSelection()
1256         self.EDSFile.Clear()
1257         for option in self.NodeList.EDSNodes.keys():
1258             self.EDSFile.Append(option)
1259         if self.EDSFile.FindString(selection) != wx.NOT_FOUND:
1260             self.EDSFile.SetStringSelection(selection)
1261     
1262     def SetNodeList(self, nodelist):
1263         self.NodeList = nodelist
1264         self.RefreshEDSFile()
1265     
1266     def GetValues(self):
1267         values = {}
1268         values["slaveName"] = self.SlaveName.GetValue()
1269         nodeid = self.SlaveNodeID.GetValue()
1270         if nodeid.find("x") != -1:
1271             values["slaveNodeID"] = int(nodeid, 16)
1272         else:
1273             values["slaveNodeID"] = int(nodeid)
1274         values["edsFile"] = self.EDSFile.GetStringSelection()
1275         return values
1276
1277 #-------------------------------------------------------------------------------
1278 #                            Editing DCF Entry Dialog
1279 #-------------------------------------------------------------------------------
1280
1281 class DCFEntryValuesTable(wx.grid.PyGridTableBase):
1282     
1283     """
1284     A custom wxGrid Table using user supplied data
1285     """
1286     def __init__(self, parent, data, colnames):
1287         # The base class must be initialized *first*
1288         wx.grid.PyGridTableBase.__init__(self)
1289         self.data = data
1290         self.colnames = colnames
1291         self.Parent = parent
1292         # XXX
1293         # we need to store the row length and collength to
1294         # see if the table has changed size
1295         self._rows = self.GetNumberRows()
1296         self._cols = self.GetNumberCols()
1297     
1298     def GetNumberCols(self):
1299         return len(self.colnames)
1300         
1301     def GetNumberRows(self):
1302         return len(self.data)
1303
1304     def GetColLabelValue(self, col):
1305         if col < len(self.colnames):
1306             return self.colnames[col]
1307
1308     def GetRowLabelValues(self, row):
1309         return row
1310
1311     def GetValue(self, row, col):
1312         if row < self.GetNumberRows():
1313             return str(self.data[row].get(self.GetColLabelValue(col), ""))
1314             
1315     def GetEditor(self, row, col):
1316         if row < self.GetNumberRows():
1317             return self.editors[row].get(self.GetColLabelValue(col), "")
1318     
1319     def GetValueByName(self, row, colname):
1320         return self.data[row].get(colname)
1321
1322     def SetValue(self, row, col, value):
1323         if col < len(self.colnames):
1324             self.data[row][self.GetColLabelValue(col)] = value
1325         
1326     def ResetView(self, grid):
1327         """
1328         (wx.grid.Grid) -> Reset the grid view.   Call this to
1329         update the grid if rows and columns have been added or deleted
1330         """
1331         grid.BeginBatch()
1332         for current, new, delmsg, addmsg in [
1333             (self._rows, self.GetNumberRows(), wx.grid.GRIDTABLE_NOTIFY_ROWS_DELETED, wx.grid.GRIDTABLE_NOTIFY_ROWS_APPENDED),
1334             (self._cols, self.GetNumberCols(), wx.grid.GRIDTABLE_NOTIFY_COLS_DELETED, wx.grid.GRIDTABLE_NOTIFY_COLS_APPENDED),
1335         ]:
1336             if new < current:
1337                 msg = wx.grid.GridTableMessage(self,delmsg,new,current-new)
1338                 grid.ProcessTableMessage(msg)
1339             elif new > current:
1340                 msg = wx.grid.GridTableMessage(self,addmsg,new-current)
1341                 grid.ProcessTableMessage(msg)
1342                 self.UpdateValues(grid)
1343         grid.EndBatch()
1344
1345         self._rows = self.GetNumberRows()
1346         self._cols = self.GetNumberCols()
1347         # update the column rendering scheme
1348         self._updateColAttrs(grid)
1349
1350         # update the scrollbars and the displayed part of the grid
1351         grid.AdjustScrollbars()
1352         grid.ForceRefresh()
1353
1354
1355     def UpdateValues(self, grid):
1356         """Update all displayed values"""
1357         # This sends an event to the grid table to update all of the values
1358         msg = wx.grid.GridTableMessage(self, wx.grid.GRIDTABLE_REQUEST_VIEW_GET_VALUES)
1359         grid.ProcessTableMessage(msg)
1360
1361     def _updateColAttrs(self, grid):
1362         """
1363         wx.grid.Grid -> update the column attributes to add the
1364         appropriate renderer given the column name.
1365
1366         Otherwise default to the default renderer.
1367         """
1368         
1369         for row in range(self.GetNumberRows()):
1370             for col in range(self.GetNumberCols()):
1371                 editor = wx.grid.GridCellTextEditor()
1372                 renderer = wx.grid.GridCellStringRenderer()
1373                     
1374                 grid.SetCellEditor(row, col, editor)
1375                 grid.SetCellRenderer(row, col, renderer)
1376                 
1377                 grid.SetCellBackgroundColour(row, col, wx.WHITE)
1378     
1379     def SetData(self, data):
1380         self.data = data
1381     
1382     def AppendRow(self, row_content):
1383         self.data.append(row_content)
1384
1385     def Empty(self):
1386         self.data = []
1387         self.editors = []
1388
1389 [ID_DCFENTRYVALUESDIALOG, ID_DCFENTRYVALUESDIALOGVALUESGRID, 
1390  ID_DCFENTRYVALUESDIALOGADDBUTTON, ID_DCFENTRYVALUESDIALOGDELETEBUTTON, 
1391  ID_DCFENTRYVALUESDIALOGUPBUTTON, ID_DCFENTRYVALUESDIALOGDOWNBUTTON, 
1392  ID_VARIABLEEDITORPANELSTATICTEXT1, 
1393 ] = [wx.NewId() for _init_ctrls in range(7)]
1394
1395 class DCFEntryValuesDialog(wx.Dialog):
1396     
1397     if wx.VERSION < (2, 6, 0):
1398         def Bind(self, event, function, id = None):
1399             if id is not None:
1400                 event(self, id, function)
1401             else:
1402                 event(self, function)
1403     
1404     def _init_coll_MainSizer_Items(self, parent):
1405         parent.AddWindow(self.staticText1, 0, border=20, flag=wx.GROW|wx.TOP|wx.LEFT|wx.RIGHT)
1406         parent.AddWindow(self.ValuesGrid, 0, border=20, flag=wx.GROW|wx.TOP|wx.LEFT|wx.RIGHT)
1407         parent.AddSizer(self.ButtonPanelSizer, 0, border=20, flag=wx.ALIGN_RIGHT|wx.LEFT|wx.RIGHT)
1408         parent.AddSizer(self.ButtonSizer, 0, border=20, flag=wx.ALIGN_RIGHT|wx.BOTTOM|wx.LEFT|wx.RIGHT)
1409     
1410     def _init_coll_MainSizer_Growables(self, parent):
1411         parent.AddGrowableCol(0)
1412         parent.AddGrowableRow(1)
1413     
1414     def _init_coll_ButtonPanelSizer_Items(self, parent):
1415         parent.AddWindow(self.UpButton, 0, border=5, flag=wx.ALL)
1416         parent.AddWindow(self.AddButton, 0, border=5, flag=wx.ALL)
1417         parent.AddWindow(self.DownButton, 0, border=5, flag=wx.ALL)
1418         parent.AddWindow(self.DeleteButton, 0, border=5, flag=wx.ALL)
1419         
1420     def _init_sizers(self):
1421         self.MainSizer = wx.FlexGridSizer(cols=1, hgap=0, rows=3, vgap=0)
1422         self.ButtonPanelSizer = wx.BoxSizer(wx.HORIZONTAL)
1423         
1424         self._init_coll_MainSizer_Items(self.MainSizer)
1425         self._init_coll_MainSizer_Growables(self.MainSizer)
1426         self._init_coll_ButtonPanelSizer_Items(self.ButtonPanelSizer)
1427         
1428         self.SetSizer(self.MainSizer)
1429
1430     def _init_ctrls(self, prnt):
1431         wx.Dialog.__init__(self, id=ID_DCFENTRYVALUESDIALOG,
1432               name='DCFEntryValuesDialog', parent=prnt, pos=wx.Point(376, 223),
1433               size=wx.Size(400, 300), style=wx.DEFAULT_DIALOG_STYLE|wx.RESIZE_BORDER,
1434               title='Edit DCF Entry Values')
1435         self.SetClientSize(wx.Size(400, 300))
1436
1437         self.staticText1 = wx.StaticText(id=ID_VARIABLEEDITORPANELSTATICTEXT1,
1438               label='Entry Values:', name='staticText1', parent=self,
1439               pos=wx.Point(0, 0), size=wx.Size(95, 17), style=0)
1440
1441         self.ValuesGrid = wx.grid.Grid(id=ID_DCFENTRYVALUESDIALOGVALUESGRID,
1442               name='ValuesGrid', parent=self, pos=wx.Point(0, 0), 
1443               size=wx.Size(0, 150), style=wx.VSCROLL)
1444         self.ValuesGrid.SetFont(wx.Font(12, 77, wx.NORMAL, wx.NORMAL, False,
1445               'Sans'))
1446         self.ValuesGrid.SetLabelFont(wx.Font(10, 77, wx.NORMAL, wx.NORMAL,
1447               False, 'Sans'))
1448         self.ValuesGrid.SetRowLabelSize(0)
1449         self.ValuesGrid.SetSelectionBackground(wx.WHITE)
1450         self.ValuesGrid.SetSelectionForeground(wx.BLACK)
1451         if wx.VERSION >= (2, 6, 0):
1452             self.ValuesGrid.Bind(wx.grid.EVT_GRID_CELL_CHANGE, self.OnValuesGridCellChange)
1453             self.ValuesGrid.Bind(wx.grid.EVT_GRID_SELECT_CELL, self.OnValuesGridSelectCell)
1454         else:
1455             wx.grid.EVT_GRID_CELL_CHANGE(self.ValuesGrid, self.OnValuesGridCellChange)
1456             wx.grid.EVT_GRID_SELECT_CELL(self.ValuesGrid, self.OnValuesGridSelectCell)
1457         
1458         self.AddButton = wx.Button(id=ID_DCFENTRYVALUESDIALOGADDBUTTON, label='Add',
1459               name='AddButton', parent=self, pos=wx.Point(0, 0),
1460               size=wx.Size(72, 32), style=0)
1461         self.Bind(wx.EVT_BUTTON, self.OnAddButton, id=ID_DCFENTRYVALUESDIALOGADDBUTTON)
1462
1463         self.DeleteButton = wx.Button(id=ID_DCFENTRYVALUESDIALOGDELETEBUTTON, label='Delete',
1464               name='DeleteButton', parent=self, pos=wx.Point(0, 0),
1465               size=wx.Size(72, 32), style=0)
1466         self.Bind(wx.EVT_BUTTON, self.OnDeleteButton, id=ID_DCFENTRYVALUESDIALOGDELETEBUTTON)
1467
1468         self.UpButton = wx.Button(id=ID_DCFENTRYVALUESDIALOGUPBUTTON, label='^',
1469               name='UpButton', parent=self, pos=wx.Point(0, 0),
1470               size=wx.Size(32, 32), style=0)
1471         self.Bind(wx.EVT_BUTTON, self.OnUpButton, id=ID_DCFENTRYVALUESDIALOGUPBUTTON)
1472
1473         self.DownButton = wx.Button(id=ID_DCFENTRYVALUESDIALOGDOWNBUTTON, label='v',
1474               name='DownButton', parent=self, pos=wx.Point(0, 0),
1475               size=wx.Size(32, 32), style=0)
1476         self.Bind(wx.EVT_BUTTON, self.OnDownButton, id=ID_DCFENTRYVALUESDIALOGDOWNBUTTON)
1477
1478         self.ButtonSizer = self.CreateButtonSizer(wx.OK|wx.CANCEL|wx.CENTRE)
1479         
1480         self._init_sizers()
1481
1482     def __init__(self, parent):
1483         self._init_ctrls(parent)
1484         
1485         self.Values = []
1486         self.DefaultValue = {"Index" : 0, "Subindex" : 0, "Size" : 1, "Value" : 0}
1487         
1488         self.Table = DCFEntryValuesTable(self, [], ["Index", "Subindex", "Size", "Value"])
1489         self.ValuesGrid.SetTable(self.Table)
1490         
1491     def OnValuesGridCellChange(self, event):
1492         row, col = event.GetRow(), event.GetCol()
1493         colname = self.Table.GetColLabelValue(col)
1494         value = self.Table.GetValue(row, col)
1495         try:
1496             self.Values[row][colname] = int(value, 16)
1497         except:
1498             message = wx.MessageDialog(self, "\"%s\" is not a valid value!"%value, "Error", wx.OK|wx.ICON_ERROR)
1499             message.ShowModal()
1500             message.Destroy()
1501         wx.CallAfter(self.RefreshValues)
1502         event.Skip()
1503     
1504     def OnValuesGridSelectCell(self, event):
1505         wx.CallAfter(self.RefreshButtons)
1506         event.Skip()
1507     
1508     def RefreshButtons(self):
1509         row = self.ValuesGrid.GetGridCursorRow()
1510         length = len(self.Table.data)
1511         self.DeleteButton.Enable(length > 0)
1512         self.UpButton.Enable(row > 0)
1513         self.DownButton.Enable(row < length - 1)
1514     
1515     def OnAddButton(self, event):
1516         new_row = self.DefaultValue.copy()
1517         self.Values.append(new_row)
1518         self.RefreshValues()
1519         event.Skip()
1520
1521     def OnDeleteButton(self, event):
1522         row = self.ValuesGrid.GetGridCursorRow()
1523         self.Values.pop(row)
1524         self.RefreshValues()
1525         event.Skip()
1526
1527     def OnUpButton(self, event):
1528         self.MoveValue(self.ValuesGrid.GetGridCursorRow(), -1)
1529         event.Skip()
1530
1531     def OnDownButton(self, event):
1532         self.MoveValue(self.ValuesGrid.GetGridCursorRow(), 1)
1533         event.Skip()
1534
1535     def MoveValue(self, value_index, move):
1536         new_index = max(0, min(value_index + move, len(self.Values) - 1))
1537         if new_index != value_index:
1538             self.Values.insert(new_index, self.Values.pop(value_index))
1539             col = self.ValuesGrid.GetGridCursorCol()
1540             self.RefreshValues()
1541             self.ValuesGrid.SetGridCursor(new_index, col)
1542             self.RefreshButtons()
1543         else:
1544             self.RefreshValues()
1545
1546     def SetValues(self, values):
1547         self.Values = []
1548         if values != "":
1549             data = values[4:]
1550             current = 0
1551             for i in xrange(BE_to_LE(values[:4])):
1552                 value = {}
1553                 value["Index"] = BE_to_LE(data[current:current+2])
1554                 value["Subindex"] = BE_to_LE(data[current+2:current+3])
1555                 size = BE_to_LE(data[current+3:current+7])
1556                 value["Size"] = size
1557                 value["Value"] = BE_to_LE(data[current+7:current+7+size])
1558                 current += 7 + size
1559                 self.Values.append(value)
1560         self.RefreshValues()
1561     
1562     def GetValues(self):
1563         value = LE_to_BE(len(self.Values), 4)
1564         for row in self.Values:
1565             value += LE_to_BE(row["Index"], 2)
1566             value += LE_to_BE(row["Subindex"], 1)
1567             value += LE_to_BE(row["Size"], 4)
1568             value += LE_to_BE(row["Value"], row["Size"])
1569         return value
1570     
1571     def RefreshValues(self):
1572         if len(self.Table.data) > 0:
1573             self.ValuesGrid.SetGridCursor(0, 0)
1574         data = []
1575         for value in self.Values:
1576             row = {}
1577             row["Index"] = "%04X"%value["Index"]
1578             row["Subindex"] = "%02X"%value["Subindex"]
1579             row["Size"] = "%08X"%value["Size"]
1580             row["Value"] = ("%0"+"%d"%(value["Size"] * 2)+"X")%value["Value"]
1581             data.append(row)
1582         self.Table.SetData(data)
1583         self.Table.ResetView(self.ValuesGrid)
1584         self.RefreshButtons()
1585