]> rtime.felk.cvut.cz Git - CanFestival-3.git/blob - objdictgen/objdictedit.py
Bug on NoteBook in Windows corrected
[CanFestival-3.git] / objdictgen / objdictedit.py
1 #Boa:Frame:objdictedit
2 #!/usr/bin/env python
3 # -*- coding: utf-8 -*-
4
5 #This file is part of CanFestival, a library implementing CanOpen Stack. 
6 #
7 #Copyright (C): Edouard TISSERANT, Francis DUPIN and Laurent BESSARD
8 #
9 #See COPYING file for copyrights details.
10 #
11 #This library is free software; you can redistribute it and/or
12 #modify it under the terms of the GNU Lesser General Public
13 #License as published by the Free Software Foundation; either
14 #version 2.1 of the License, or (at your option) any later version.
15 #
16 #This library is distributed in the hope that it will be useful,
17 #but WITHOUT ANY WARRANTY; without even the implied warranty of
18 #MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
19 #Lesser General Public License for more details.
20 #
21 #You should have received a copy of the GNU Lesser General Public
22 #License along with this library; if not, write to the Free Software
23 #Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
24
25 from wxPython.wx import *
26 from wxPython.html import *
27 from wxPython.grid import *
28 import wx
29 from wx.lib.anchors import LayoutAnchors
30 import wx.grid
31
32 from types import *
33 import os, re, platform, sys, time, traceback, getopt
34
35 __version__ = "$Revision: 1.6 $"
36
37 from nodemanager import *
38 from node import OD_Subindex,OD_MultipleSubindexes,OD_IdenticalSubindexes,OD_IdenticalIndexes
39 from doc_index.DS301_index import *
40
41 wxEVT_HTML_URL_CLICK = wxNewId()
42
43 def EVT_HTML_URL_CLICK(win, func):
44     win.Connect(-1, -1, wxEVT_HTML_URL_CLICK, func)
45
46 class wxHtmlWindowUrlClick(wxPyEvent):
47     def __init__(self, linkinfo):
48         wxPyEvent.__init__(self)
49         self.SetEventType(wxEVT_HTML_URL_CLICK)
50         self.linkinfo = (linkinfo.GetHref(), linkinfo.GetTarget())
51
52 class wxUrlClickHtmlWindow(wxHtmlWindow):
53     """ HTML window that generates and OnLinkClicked event.
54
55     Use this to avoid having to override HTMLWindow
56     """
57     def OnLinkClicked(self, linkinfo):
58         wxPostEvent(self, wxHtmlWindowUrlClick(linkinfo))
59
60 def create(parent):
61     return objdictedit(parent)
62
63 def usage():
64     print "\nUsage of objectdict.py :"
65     print "\n   %s [Filepath, ...]\n"%sys.argv[0]
66
67 try:
68     opts, args = getopt.getopt(sys.argv[1:], "h", ["help"])
69 except getopt.GetoptError:
70     # print help information and exit:
71     usage()
72     sys.exit(2)
73
74 for o, a in opts:
75     if o in ("-h", "--help"):
76         usage()
77         sys.exit()
78
79 filesOpen = args
80
81 ColSizes = [75, 250, 150, 125, 100, 60, 250]
82 ColAlignements = [wxALIGN_CENTER, wxALIGN_LEFT, wxALIGN_CENTER, wxALIGN_RIGHT, wxALIGN_CENTER, wxALIGN_CENTER, wxALIGN_LEFT]
83 AccessList = "Read Only,Write Only,Read/Write"
84 BoolList = "True,False"
85 OptionList = "Yes,No"
86
87 DictionaryOrganisation = [
88     {"minIndex" : 0x0001, "maxIndex" : 0x0FFF, "name" : "Data Type Definitions"},
89     {"minIndex" : 0x1000, "maxIndex" : 0x1029, "name" : "Communication Parameters"},
90     {"minIndex" : 0x1200, "maxIndex" : 0x12FF, "name" : "SDO Parameters"},
91     {"minIndex" : 0x1400, "maxIndex" : 0x15FF, "name" : "Receive PDO Parameters"},
92     {"minIndex" : 0x1600, "maxIndex" : 0x17FF, "name" : "Receive PDO Mapping"},
93     {"minIndex" : 0x1800, "maxIndex" : 0x19FF, "name" : "Transmit PDO Parameters"},
94     {"minIndex" : 0x1A00, "maxIndex" : 0x1BFF, "name" : "Transmit PDO Mapping"},
95     {"minIndex" : 0x1C00, "maxIndex" : 0x1FFF, "name" : "Other Communication Parameters"},
96     {"minIndex" : 0x2000, "maxIndex" : 0x5FFF, "name" : "Manufacturer Specific"},
97     {"minIndex" : 0x6000, "maxIndex" : 0x9FFF, "name" : "Standardized Device Profile"},
98     {"minIndex" : 0xA000, "maxIndex" : 0xBFFF, "name" : "Standardized Interface Profile"}]
99
100 class SubindexTable(wxPyGridTableBase):
101     
102     """
103     A custom wxGrid Table using user supplied data
104     """
105     def __init__(self, parent, data, editors, colnames):
106         # The base class must be initialized *first*
107         wxPyGridTableBase.__init__(self)
108         self.data = data
109         self.editors = editors
110         self.CurrentIndex = 0
111         self.colnames = colnames
112         self.Parent = parent
113         # XXX
114         # we need to store the row length and collength to
115         # see if the table has changed size
116         self._rows = self.GetNumberRows()
117         self._cols = self.GetNumberCols()
118     
119     def GetNumberCols(self):
120         return len(self.colnames)
121         
122     def GetNumberRows(self):
123         return len(self.data)
124
125     def GetColLabelValue(self, col):
126         if col < len(self.colnames):
127             return self.colnames[col]
128
129     def GetRowLabelValues(self, row):
130         return row
131
132     def GetValue(self, row, col):
133         if row < self.GetNumberRows():
134             name = str(self.data[row].get(self.GetColLabelValue(col), ""))
135             return name
136     
137     def GetEditor(self, row, col):
138         if row < self.GetNumberRows():
139             return self.editors[row].get(self.GetColLabelValue(col), "")
140     
141     def GetValueByName(self, row, colname):
142         return self.data[row].get(colname)
143
144     def SetValue(self, row, col, value):
145         if col < len(self.colnames):
146             self.data[row][self.GetColLabelValue(col)] = value
147         
148     def ResetView(self, grid):
149         """
150         (wxGrid) -> Reset the grid view.   Call this to
151         update the grid if rows and columns have been added or deleted
152         """
153         grid.BeginBatch()
154         for current, new, delmsg, addmsg in [
155             (self._rows, self.GetNumberRows(), wxGRIDTABLE_NOTIFY_ROWS_DELETED, wxGRIDTABLE_NOTIFY_ROWS_APPENDED),
156             (self._cols, self.GetNumberCols(), wxGRIDTABLE_NOTIFY_COLS_DELETED, wxGRIDTABLE_NOTIFY_COLS_APPENDED),
157         ]:
158             if new < current:
159                 msg = wxGridTableMessage(self,delmsg,new,current-new)
160                 grid.ProcessTableMessage(msg)
161             elif new > current:
162                 msg = wxGridTableMessage(self,addmsg,new-current)
163                 grid.ProcessTableMessage(msg)
164                 self.UpdateValues(grid)
165         grid.EndBatch()
166
167         self._rows = self.GetNumberRows()
168         self._cols = self.GetNumberCols()
169         # update the column rendering scheme
170         self._updateColAttrs(grid)
171
172         # update the scrollbars and the displayed part of the grid
173         grid.AdjustScrollbars()
174         grid.ForceRefresh()
175
176
177     def UpdateValues(self, grid):
178         """Update all displayed values"""
179         # This sends an event to the grid table to update all of the values
180         msg = wxGridTableMessage(self, wxGRIDTABLE_REQUEST_VIEW_GET_VALUES)
181         grid.ProcessTableMessage(msg)
182
183     def _updateColAttrs(self, grid):
184         """
185         wxGrid -> update the column attributes to add the
186         appropriate renderer given the column name.
187
188         Otherwise default to the default renderer.
189         """
190         
191         for col in range(self.GetNumberCols()):
192             attr = wxGridCellAttr()
193             attr.SetAlignment(ColAlignements[col], wxALIGN_CENTRE)
194             grid.SetColAttr(col, attr)
195             grid.SetColSize(col, ColSizes[col])
196         
197         typelist = None
198         accesslist = None
199         for row in range(self.GetNumberRows()):
200             editors = self.editors[row]
201             for col in range(self.GetNumberCols()):
202                 editor = None
203                 renderer = None
204                 
205                 colname = self.GetColLabelValue(col)
206                 editortype = editors[colname]
207                 if editortype:
208                     grid.SetReadOnly(row, col, False)
209                     if editortype == "string":
210                         editor = wxGridCellTextEditor()
211                         renderer = wxGridCellStringRenderer()
212                         if colname == "value" and "length" in editors:
213                             editor.SetParameters(editors["length"]) 
214                     elif editortype == "number":
215                         editor = wxGridCellNumberEditor()
216                         renderer = wxGridCellNumberRenderer()
217                         if colname == "value" and "min" in editors and "max" in editors:
218                             editor.SetParameters("%s,%s"%(editors["min"],editors["max"]))
219                     elif editortype == "real":
220                         editor = wxGridCellFloatEditor()
221                         renderer = wxGridCellFloatRenderer()
222                         if colname == "value" and "min" in editors and "max" in editors:
223                             editor.SetParameters("%s,%s"%(editors["min"],editors["max"]))
224                     elif editortype == "bool":
225                         editor = wxGridCellChoiceEditor()
226                         editor.SetParameters(BoolList)
227                     elif editortype == "access":
228                         editor = wxGridCellChoiceEditor()
229                         editor.SetParameters(AccessList)
230                     elif editortype == "option":
231                         editor = wxGridCellChoiceEditor()
232                         editor.SetParameters(OptionList)
233                     elif editortype == "type":
234                         editor = wxGridCellChoiceEditor()
235                         editor.SetParameters(self.Parent.Manager.GetCurrentTypeList())
236                     elif editortype == "map":
237                         editor = wxGridCellChoiceEditor()
238                         editor.SetParameters(self.Parent.Manager.GetCurrentMapList())
239                 else:
240                     grid.SetReadOnly(row, col, True)
241                     
242                 grid.SetCellEditor(row, col, editor)
243                 grid.SetCellRenderer(row, col, renderer)
244                 
245                 grid.SetCellBackgroundColour(row, col, wxWHITE)
246     
247     def SetData(self, data):
248         self.data = data
249         
250     def SetEditors(self, editors):
251         self.editors = editors
252     
253     def GetCurrentIndex(self):
254         return self.CurrentIndex
255     
256     def SetCurrentIndex(self, index):
257         self.CurrentIndex = index
258     
259     def AppendRow(self, row_content):
260         self.data.append(row_content)
261
262     def Empty(self):
263         self.data = []
264         self.editors = []
265
266 [wxID_EDITINGPANEL, wxID_EDITINGPANELADDBUTTON, wxID_EDITINGPANELINDEXCHOICE, 
267  wxID_EDITINGPANELINDEXLIST, wxID_EDITINGPANELINDEXLISTPANEL, wxID_EDITINGPANELPARTLIST, 
268  wxID_EDITINGPANELSECONDSPLITTER, wxID_EDITINGPANELSUBINDEXGRID,
269  wxID_EDITINGPANELSUBINDEXGRIDPANEL, wxID_EDITINGPANELCALLBACKCHECK,
270 ] = [wx.NewId() for _init_ctrls in range(10)]
271
272 [wxID_EDITINGPANELINDEXLISTMENUITEMS0, wxID_EDITINGPANELINDEXLISTMENUITEMS1, 
273  wxID_EDITINGPANELINDEXLISTMENUITEMS2, 
274 ] = [wx.NewId() for _init_coll_IndexListMenu_Items in range(3)]
275
276 [wxID_EDITINGPANELMENU1ITEMS0, wxID_EDITINGPANELMENU1ITEMS1, 
277 ] = [wx.NewId() for _init_coll_SubindexGridMenu_Items in range(2)]
278
279 class EditingPanel(wx.SplitterWindow):
280     def _init_coll_AddToListSizer_Items(self, parent):
281         # generated method, don't edit
282
283         parent.AddWindow(self.AddButton, 0, border=0, flag=0)
284         parent.AddWindow(self.IndexChoice, 0, border=0, flag=wxGROW)
285
286     def _init_coll_SubindexGridSizer_Items(self, parent):
287         # generated method, don't edit
288
289         parent.AddWindow(self.CallbackCheck, 0, border=0, flag=0)
290         parent.AddWindow(self.SubindexGrid, 0, border=0, flag=wxGROW)
291
292     def _init_coll_IndexListSizer_Items(self, parent):
293         # generated method, don't edit
294
295         parent.AddWindow(self.IndexList, 0, border=0, flag=wxGROW)
296         parent.AddSizer(self.AddToListSizer, 0, border=0, flag=wxGROW)
297
298     def _init_coll_AddToListSizer_Growables(self, parent):
299         # generated method, don't edit
300
301         parent.AddGrowableCol(1)
302
303     def _init_coll_SubindexGridSizer_Growables(self, parent):
304         # generated method, don't edit
305
306         parent.AddGrowableCol(0)
307         parent.AddGrowableRow(1)
308
309     def _init_coll_IndexListSizer_Growables(self, parent):
310         # generated method, don't edit
311
312         parent.AddGrowableCol(0)
313         parent.AddGrowableRow(0)
314
315     def _init_coll_SubindexGridMenu_Items(self, parent):
316         # generated method, don't edit
317
318         parent.Append(help='', id=wxID_EDITINGPANELMENU1ITEMS0,
319               kind=wx.ITEM_NORMAL, text='Add')
320         parent.Append(help='', id=wxID_EDITINGPANELMENU1ITEMS1,
321               kind=wx.ITEM_NORMAL, text='Delete')
322         self.Bind(wx.EVT_MENU, self.OnAddSubindexMenu,
323               id=wxID_EDITINGPANELMENU1ITEMS0)
324         self.Bind(wx.EVT_MENU, self.OnDeleteSubindexMenu,
325               id=wxID_EDITINGPANELMENU1ITEMS1)
326
327     def _init_coll_IndexListMenu_Items(self, parent):
328         # generated method, don't edit
329
330         parent.Append(help='', id=wxID_EDITINGPANELINDEXLISTMENUITEMS0,
331               kind=wx.ITEM_NORMAL, text='Rename')
332         parent.Append(help='', id=wxID_EDITINGPANELINDEXLISTMENUITEMS2,
333               kind=wx.ITEM_NORMAL, text='Modify')
334         parent.Append(help='', id=wxID_EDITINGPANELINDEXLISTMENUITEMS1,
335               kind=wx.ITEM_NORMAL, text='Delete')
336         self.Bind(wx.EVT_MENU, self.OnRenameIndexMenu,
337               id=wxID_EDITINGPANELINDEXLISTMENUITEMS0)
338         self.Bind(wx.EVT_MENU, self.OnDeleteIndexMenu,
339               id=wxID_EDITINGPANELINDEXLISTMENUITEMS1)
340         self.Bind(wx.EVT_MENU, self.OnModifyIndexMenu,
341               id=wxID_EDITINGPANELINDEXLISTMENUITEMS2)
342
343     def _init_utils(self):
344         # generated method, don't edit
345         self.IndexListMenu = wx.Menu(title='')
346
347         self.SubindexGridMenu = wx.Menu(title='')
348
349         self._init_coll_IndexListMenu_Items(self.IndexListMenu)
350         self._init_coll_SubindexGridMenu_Items(self.SubindexGridMenu)
351
352     def _init_sizers(self):
353         # generated method, don't edit
354         self.IndexListSizer = wx.FlexGridSizer(cols=1, hgap=0, rows=2, vgap=0)
355
356         self.SubindexGridSizer = wx.FlexGridSizer(cols=1, hgap=0, rows=2, vgap=0)
357
358         self.AddToListSizer = wx.FlexGridSizer(cols=2, hgap=0, rows=1, vgap=0)
359
360         self._init_coll_IndexListSizer_Growables(self.IndexListSizer)
361         self._init_coll_IndexListSizer_Items(self.IndexListSizer)
362         self._init_coll_SubindexGridSizer_Growables(self.SubindexGridSizer)
363         self._init_coll_SubindexGridSizer_Items(self.SubindexGridSizer)
364         self._init_coll_AddToListSizer_Growables(self.AddToListSizer)
365         self._init_coll_AddToListSizer_Items(self.AddToListSizer)
366
367         self.SubindexGridPanel.SetSizer(self.SubindexGridSizer)
368         self.IndexListPanel.SetSizer(self.IndexListSizer)
369         
370     def _init_ctrls(self, prnt):
371         wx.SplitterWindow.__init__(self, id=wxID_EDITINGPANEL,
372               name='MainSplitter', parent=prnt, point=wx.Point(0, 0),
373               size=wx.Size(-1, -1), style=wx.SP_3D)
374         self._init_utils()
375         self.SetNeedUpdating(True)
376         self.SetMinimumPaneSize(1)
377
378         self.PartList = wx.ListBox(choices=[], id=wxID_EDITINGPANELPARTLIST,
379               name='PartList', parent=self, pos=wx.Point(0, 0),
380               size=wx.Size(-1, -1), style=0)
381         self.PartList.Bind(wx.EVT_LISTBOX, self.OnPartListBoxClick,
382               id=wxID_EDITINGPANELPARTLIST)
383
384         self.SecondSplitter = wx.SplitterWindow(id=wxID_EDITINGPANELSECONDSPLITTER,
385               name='SecondSplitter', parent=self, point=wx.Point(0,
386               0), size=wx.Size(-1, -1), style=wx.SP_3D)
387         self.SecondSplitter.SetMinimumPaneSize(1)
388         self.SplitHorizontally(self.PartList, self.SecondSplitter,
389               110)
390
391         self.SubindexGridPanel = wx.Panel(id=wxID_EDITINGPANELSUBINDEXGRIDPANEL,
392               name='SubindexGridPanel', parent=self.SecondSplitter, pos=wx.Point(0,
393               0), size=wx.Size(-1, -1), style=wx.TAB_TRAVERSAL)
394
395         self.IndexListPanel = wx.Panel(id=wxID_EDITINGPANELINDEXLISTPANEL,
396               name='IndexListPanel', parent=self.SecondSplitter, pos=wx.Point(0,
397               0), size=wx.Size(-1, -1), style=wx.TAB_TRAVERSAL)
398         self.SecondSplitter.SplitVertically(self.IndexListPanel,
399               self.SubindexGridPanel, 280)
400
401         self.SubindexGrid = wx.grid.Grid(id=wxID_EDITINGPANELSUBINDEXGRID,
402               name='SubindexGrid', parent=self.SubindexGridPanel, pos=wx.Point(0,
403               0), size=wx.Size(-1, -1), style=0)
404         self.SubindexGrid.SetFont(wx.Font(12, 77, wx.NORMAL, wx.NORMAL, False,
405               'Sans'))
406         self.SubindexGrid.SetLabelFont(wx.Font(10, 77, wx.NORMAL, wx.NORMAL,
407               False, 'Sans'))
408         self.SubindexGrid.Bind(wx.grid.EVT_GRID_CELL_CHANGE,
409               self.OnSubindexGridCellChange)
410         self.SubindexGrid.Bind(wx.grid.EVT_GRID_CELL_RIGHT_CLICK,
411               self.OnSubindexGridRightClick)
412         self.SubindexGrid.Bind(wx.grid.EVT_GRID_SELECT_CELL,
413               self.OnSubindexGridSelectCell)
414
415         self.CallbackCheck = wx.CheckBox(id=wxID_EDITINGPANELCALLBACKCHECK,
416               label='Have Callbacks', name='CallbackCheck',
417               parent=self.SubindexGridPanel, pos=wx.Point(0, 0), size=wx.Size(152,
418               24), style=0)
419         self.CallbackCheck.Bind(wx.EVT_CHECKBOX, self.OnCallbackCheck,
420               id=wxID_EDITINGPANELCALLBACKCHECK)
421
422         self.IndexList = wx.ListBox(choices=[], id=wxID_EDITINGPANELINDEXLIST,
423               name='IndexList', parent=self.IndexListPanel, pos=wx.Point(0, 0),
424               size=wx.Size(-1, -1), style=0)
425         self.IndexList.Bind(wx.EVT_LISTBOX, self.OnIndexListClick,
426               id=wxID_EDITINGPANELINDEXLIST)
427         self.IndexList.Bind(wx.EVT_RIGHT_UP, self.OnIndexListRightUp)
428
429         self.AddButton = wx.Button(id=wxID_EDITINGPANELADDBUTTON, label='Add',
430               name='AddButton', parent=self.IndexListPanel, pos=wx.Point(0, 0),
431               size=wx.Size(50, 30), style=0)
432         self.AddButton.Bind(wx.EVT_BUTTON, self.OnAddButtonClick,
433               id=wxID_EDITINGPANELADDBUTTON)
434
435         self.IndexChoice = wx.Choice(choices=[], id=wxID_EDITINGPANELINDEXCHOICE,
436               name='IndexChoice', parent=self.IndexListPanel, pos=wx.Point(50,
437               0), size=wx.Size(-1, 30), style=0)
438
439         self._init_sizers()
440
441     def __init__(self, parent, manager):
442         self._init_ctrls(parent.GetNoteBook())
443         self.Parent = parent
444         self.Manager = manager
445         self.ListIndex = []
446         self.ChoiceIndex = []
447         self.FirstCall = False
448         
449         for values in DictionaryOrganisation:
450             text = "   0x%04X-0x%04X      %s"%(values["minIndex"],values["maxIndex"],values["name"])
451             self.PartList.Append(text)
452         self.Table = SubindexTable(self, [], [], ["subindex", "name", "type", "value", "access", "save", "comment"])
453         self.SubindexGrid.SetTable(self.Table)
454         self.SubindexGrid.SetRowLabelSize(0)
455         self.CallbackCheck.Disable()
456         self.Table.ResetView(self.SubindexGrid)
457
458     def GetSelection(self):
459         selected = self.IndexList.GetSelection()
460         if selected != wxNOT_FOUND:
461             index = self.ListIndex[selected]
462             subIndex = self.SubindexGrid.GetGridCursorRow()
463             return index, subIndex
464         return None
465
466     def OnAddButtonClick(self, event):
467         selected = self.IndexChoice.GetStringSelection()
468         if selected != "":
469             if selected == "User Type":
470                 self.Parent.AddUserType()
471             elif selected == "SDO Server":
472                 self.Manager.AddSDOServerToCurrent()
473             elif selected == "SDO Client":
474                 self.Manager.AddSDOClientToCurrent()
475             elif selected == "PDO Receive":
476                 self.Manager.AddPDOReceiveToCurrent()
477             elif selected == "PDO Transmit":
478                 self.Manager.AddPDOTransmitToCurrent()
479             elif selected == "Map Variable":
480                 self.Parent.AddMapVariable()
481             elif selected in [menu for menu, indexes in self.Manager.GetCurrentSpecificMenu()]:
482                 self.Manager.AddSpecificEntryToCurrent(selected)
483             else:
484                 index = self.ChoiceIndex[self.IndexChoice.GetSelection()]
485                 self.Manager.ManageEntriesOfCurrent([index], [])
486             self.Parent.RefreshBufferState()
487             self.RefreshIndexList()
488         event.Skip()
489
490     def OnPartListBoxClick(self, event):
491         self.SubindexGrid.SetGridCursor(0, 0)
492         self.RefreshIndexList()
493         event.Skip()
494
495     def OnIndexListClick(self, event):
496         self.SubindexGrid.SetGridCursor(0, 0)
497         self.RefreshTable()
498         event.Skip()
499
500     def OnSubindexGridSelectCell(self, event):
501         wxCallAfter(self.Parent.RefreshStatusBar)
502         event.Skip()
503
504 #-------------------------------------------------------------------------------
505 #                             Refresh Functions
506 #-------------------------------------------------------------------------------
507
508     def RefreshIndexList(self):
509         selected = self.IndexList.GetSelection()
510         choice = self.IndexChoice.GetStringSelection()
511         choiceindex = self.IndexChoice.GetSelection()
512         if selected != wxNOT_FOUND:
513             selectedindex = self.ListIndex[selected]
514         self.IndexList.Clear()
515         self.IndexChoice.Clear()
516         i = self.PartList.GetSelection()
517         if i < len(DictionaryOrganisation):
518             values = DictionaryOrganisation[i]
519             self.ListIndex = []
520             for name, index in self.Manager.GetCurrentValidIndexes(values["minIndex"], values["maxIndex"]):
521                 self.IndexList.Append("0x%04X   %s"%(index, name))
522                 self.ListIndex.append(index)
523             self.ChoiceIndex = []
524             if i == 0:
525                 self.IndexChoice.Append("User Type")
526                 self.IndexChoice.SetStringSelection("User Type")
527             elif i == 2:
528                 self.IndexChoice.Append("SDO Server")
529                 self.IndexChoice.Append("SDO Client")
530                 if choiceindex != wxNOT_FOUND and choice == self.IndexChoice.GetString(choiceindex):
531                      self.IndexChoice.SetStringSelection(choice)
532             elif i in (3, 4):
533                 self.IndexChoice.Append("PDO Receive")
534                 self.IndexChoice.SetStringSelection("PDO Receive")
535             elif i in (5, 6):
536                 self.IndexChoice.Append("PDO Transmit")
537                 self.IndexChoice.SetStringSelection("PDO Transmit")
538             elif i == 8:
539                 self.IndexChoice.Append("Map Variable")
540                 self.IndexChoice.SetStringSelection("Map Variable")
541             else:
542                 for name, index in self.Manager.GetCurrentValidChoices(values["minIndex"], values["maxIndex"]):
543                     if index:
544                         self.IndexChoice.Append("0x%04X   %s"%(index, name))
545                     else:
546                         self.IndexChoice.Append(name)
547                     self.ChoiceIndex.append(index)
548             if choiceindex != wxNOT_FOUND and choice == self.IndexChoice.GetString(choiceindex):
549                 self.IndexChoice.SetStringSelection(choice)
550         self.IndexChoice.Enable(self.IndexChoice.GetCount() != 0)
551         self.AddButton.Enable(self.IndexChoice.GetCount() != 0)
552         if selected == wxNOT_FOUND or selected >= len(self.ListIndex) or selectedindex != self.ListIndex[selected]:
553             self.Table.Empty()
554             self.CallbackCheck.SetValue(False)
555             self.CallbackCheck.Disable()
556             self.Table.ResetView(self.SubindexGrid)
557             self.Parent.RefreshStatusBar()
558         else:
559             self.IndexList.SetSelection(selected)
560             self.RefreshTable()
561
562     def RefreshTable(self):
563         selected = self.IndexList.GetSelection()
564         if selected != wxNOT_FOUND:
565             index = self.ListIndex[selected]
566             if index > 0x260:
567                 self.CallbackCheck.Enable()
568                 self.CallbackCheck.SetValue(self.Manager.HasCurrentEntryCallbacks(index))
569             result = self.Manager.GetCurrentEntryValues(index)
570             if result != None:
571                 self.Table.SetCurrentIndex(index)
572                 data, editors = result
573                 self.Table.SetData(data)
574                 self.Table.SetEditors(editors)
575                 self.Table.ResetView(self.SubindexGrid)
576         self.Parent.RefreshStatusBar()
577
578 #-------------------------------------------------------------------------------
579 #                        Editing Table value function
580 #-------------------------------------------------------------------------------
581
582     def OnSubindexGridCellChange(self, event):
583         index = self.Table.GetCurrentIndex()
584         subIndex = event.GetRow()
585         col = event.GetCol()
586         name = self.Table.GetColLabelValue(col)
587         value = self.Table.GetValue(subIndex, col)
588         editor = self.Table.GetEditor(subIndex, col)
589         self.Manager.SetCurrentEntry(index, subIndex, value, name, editor)
590         self.Parent.RefreshBufferState()
591         wxCallAfter(self.RefreshTable)
592         event.Skip()
593
594     def OnCallbackCheck(self, event):
595         index = self.Table.GetCurrentIndex()
596         self.Manager.SetCurrentEntryCallbacks(index, self.CallbackCheck.GetValue())
597         self.Parent.RefreshBufferState()
598         wxCallAfter(self.RefreshTable)
599         event.Skip()
600
601 #-------------------------------------------------------------------------------
602 #                          Contextual Menu functions
603 #-------------------------------------------------------------------------------
604
605     def OnIndexListRightUp(self, event):
606         if not self.FirstCall:
607             self.FirstCall = True
608             selected = self.IndexList.GetSelection()
609             if selected != wxNOT_FOUND:
610                 index = self.ListIndex[selected]
611                 if index < 0x260:
612                     self.IndexListMenu.FindItemByPosition(0).Enable(False)
613                     self.IndexListMenu.FindItemByPosition(1).Enable(True)
614                     self.PopupMenu(self.IndexListMenu)
615                 elif 0x1000 <= index <= 0x1BFF:
616                     self.IndexListMenu.FindItemByPosition(0).Enable(False)
617                     self.IndexListMenu.FindItemByPosition(1).Enable(False)
618                     self.PopupMenu(self.IndexListMenu)
619                 elif 0x2000 <= index <= 0x5FFF:
620                     self.IndexListMenu.FindItemByPosition(0).Enable(True)
621                     self.IndexListMenu.FindItemByPosition(1).Enable(False)
622                     self.PopupMenu(self.IndexListMenu)
623                 elif index >= 0x6000:
624                     self.IndexListMenu.FindItemByPosition(0).Enable(False)
625                     self.IndexListMenu.FindItemByPosition(1).Enable(False)
626                     self.PopupMenu(self.IndexListMenu)
627         else:
628             self.FirstCall = False
629         event.Skip()
630
631     def OnSubindexGridRightClick(self, event):
632         selected = self.IndexList.GetSelection()
633         if selected != wxNOT_FOUND:
634             index = self.ListIndex[selected]
635             if self.Manager.IsCurrentEntry(index):
636                 infos = self.Manager.GetEntryInfos(index)
637                 if index >= 0x2000 and infos["struct"] & OD_MultipleSubindexes or infos["struct"] & OD_IdenticalSubindexes:
638                     self.PopupMenu(self.SubindexGridMenu)
639         event.Skip()
640
641     def OnRenameIndexMenu(self, event):
642         selected = self.IndexList.GetSelection()
643         if selected != wxNOT_FOUND:
644             index = self.ListIndex[selected]
645             if self.Manager.IsCurrentEntry(index):
646                 infos = self.Manager.GetEntryInfos(index)
647                 dialog = wxTextEntryDialog(self, "Give a new name for index 0x%04X"%index,
648                              "Rename an index", infos["name"], wxOK|wxCANCEL)
649                 if dialog.ShowModal() == wxID_OK:
650                     self.Manager.SetCurrentEntryName(index, dialog.GetValue())
651                     self.Parent.RefreshBufferState()
652                     self.RefreshIndexList()
653                 dialog.Destroy()
654         event.Skip()
655
656     def OnModifyIndexMenu(self, event):
657         selected = self.IndexList.GetSelection()
658         if selected != wxNOT_FOUND:
659             index = self.ListIndex[selected]
660             if self.Manager.IsCurrentEntry(index) and index < 0x260:
661                 values, valuetype = self.Manager.GetCustomisedTypeValues(index)
662                 dialog = UserTypeDialog(self)
663                 dialog.SetTypeList(self.Manager.GetCustomisableTypes(), values[1])
664                 if valuetype == 0:
665                     dialog.SetValues(min = values[2], max = values[3])
666                 elif valuetype == 1:
667                     dialog.SetValues(length = values[2])
668                 if dialog.ShowModal() == wxID_OK:
669                     type, min, max, length = dialog.GetValues()
670                     self.Manager.SetCurrentUserType(index, type, min, max, length)
671                     self.Parent.RefreshBufferState()
672                     self.RefreshIndexList()
673         event.Skip()
674         
675     def OnDeleteIndexMenu(self, event):
676         selected = self.IndexList.GetSelection()
677         if selected != wxNOT_FOUND:
678             index = self.ListIndex[selected]
679             if self.Manager.IsCurrentEntry(index):
680                 self.Manager.ManageEntriesOfCurrent([],[index])
681                 self.Parent.RefreshBufferState()
682                 self.RefreshIndexList()
683         event.Skip()
684
685     def OnAddSubindexMenu(self, event):
686         selected = self.IndexList.GetSelection()
687         if selected != wxNOT_FOUND:
688             index = self.ListIndex[selected]
689             if self.Manager.IsCurrentEntry(index):
690                 dialog = wxTextEntryDialog(self, "Number of subindexes to add:",
691                              "Add subindexes", "1", wxOK|wxCANCEL)
692                 if dialog.ShowModal() == wxID_OK:
693                     number = eval(dialog.GetValue())
694                     if type(number) == IntType:
695                         self.Manager.AddSubentriesToCurrent(index, number)
696                         self.Parent.RefreshBufferState()
697                         self.RefreshIndexList()
698                     else:
699                         message = wxMessageDialog(self, "An integer is required!", "ERROR", wxOK|wxICON_ERROR)
700                         message.ShowModal()
701                         message.Destroy()
702                 dialog.Destroy()
703         event.Skip()
704
705     def OnDeleteSubindexMenu(self, event):
706         selected = self.IndexList.GetSelection()
707         if selected != wxNOT_FOUND:
708             index = self.ListIndex[selected]
709             if self.Manager.IsCurrentEntry(index):
710                 dialog = wxTextEntryDialog(self, "Number of subindexes to delete:",
711                              "Delete subindexes", "1", wxOK|wxCANCEL)
712                 if dialog.ShowModal() == wxID_OK:
713                     number = eval(dialog.GetValue())
714                     if type(number) == IntType:
715                         self.Manager.RemoveSubentriesFromCurrent(index, number)
716                         self.Parent.RefreshBufferState()
717                         self.RefreshIndexList()
718                     else:
719                         message = wxMessageDialog(self, "An integer is required!", "ERROR", wxOK|wxICON_ERROR)
720                         message.ShowModal()
721                         message.Destroy()
722                 dialog.Destroy()
723         event.Skip()
724
725 [wxID_OBJDICTEDIT, wxID_OBJDICTEDITFILEOPENED, 
726  wxID_OBJDICTEDITHELPBAR,
727 ] = [wx.NewId() for _init_ctrls in range(3)]
728
729 [wxID_OBJDICTEDITADDMENUITEMS0, wxID_OBJDICTEDITADDMENUITEMS1, 
730  wxID_OBJDICTEDITADDMENUITEMS2, wxID_OBJDICTEDITADDMENUITEMS3, 
731  wxID_OBJDICTEDITADDMENUITEMS4, wxID_OBJDICTEDITADDMENUITEMS5, 
732 ] = [wx.NewId() for _init_coll_AddMenu_Items in range(6)]
733
734 [wxID_OBJDICTEDITFILEMENUITEMS0, wxID_OBJDICTEDITFILEMENUITEMS1, 
735  wxID_OBJDICTEDITFILEMENUITEMS2, wxID_OBJDICTEDITFILEMENUITEMS4, 
736  wxID_OBJDICTEDITFILEMENUITEMS5, wxID_OBJDICTEDITFILEMENUITEMS6, 
737  wxID_OBJDICTEDITFILEMENUITEMS7, wxID_OBJDICTEDITFILEMENUITEMS8,
738 ] = [wx.NewId() for _init_coll_FileMenu_Items in range(8)]
739
740 [wxID_OBJDICTEDITEDITMENUITEMS0, wxID_OBJDICTEDITEDITMENUITEMS1, 
741  wxID_OBJDICTEDITEDITMENUITEMS2, wxID_OBJDICTEDITEDITMENUITEMS4, 
742  wxID_OBJDICTEDITEDITMENUITEMS6, wxID_OBJDICTEDITEDITMENUITEMS7, 
743  wxID_OBJDICTEDITEDITMENUITEMS8, 
744 ] = [wx.NewId() for _init_coll_EditMenu_Items in range(7)]
745
746 [wxID_OBJDICTEDITHELPMENUITEMS0, wxID_OBJDICTEDITHELPMENUITEMS1,
747  wxID_OBJDICTEDITHELPMENUITEMS2,
748 ] = [wx.NewId() for _init_coll_HelpMenu_Items in range(3)]
749
750 class objdictedit(wx.Frame):
751     def _init_coll_menuBar1_Menus(self, parent):
752         # generated method, don't edit
753
754         parent.Append(menu=self.FileMenu, title='File')
755         parent.Append(menu=self.EditMenu, title='Edit')
756         parent.Append(menu=self.AddMenu, title='Add')
757         parent.Append(menu=self.HelpMenu, title='Help')
758
759     def _init_coll_EditMenu_Items(self, parent):
760         # generated method, don't edit
761
762         parent.Append(help='', id=wxID_OBJDICTEDITEDITMENUITEMS4,
763               kind=wx.ITEM_NORMAL, text='Refresh\tCTRL+R')
764         parent.AppendSeparator()
765         parent.Append(help='', id=wxID_OBJDICTEDITEDITMENUITEMS1,
766               kind=wx.ITEM_NORMAL, text='Undo\tCTRL+Z')
767         parent.Append(help='', id=wxID_OBJDICTEDITEDITMENUITEMS0,
768               kind=wx.ITEM_NORMAL, text='Redo\tCTRL+Y')
769         parent.AppendSeparator()
770         parent.Append(help='', id=wxID_OBJDICTEDITEDITMENUITEMS6,
771               kind=wx.ITEM_NORMAL, text='Node infos')
772         parent.Append(help='', id=wxID_OBJDICTEDITEDITMENUITEMS2,
773               kind=wx.ITEM_NORMAL, text='DS-301 Profile')
774         parent.Append(help='', id=wxID_OBJDICTEDITEDITMENUITEMS8,
775               kind=wx.ITEM_NORMAL, text='DS-302 Profile')
776         parent.Append(help='', id=wxID_OBJDICTEDITEDITMENUITEMS7,
777               kind=wx.ITEM_NORMAL, text='Other Profile')
778         self.Bind(wx.EVT_MENU, self.OnUndoMenu,
779               id=wxID_OBJDICTEDITEDITMENUITEMS1)
780         self.Bind(wx.EVT_MENU, self.OnRedoMenu,
781               id=wxID_OBJDICTEDITEDITMENUITEMS0)
782         self.Bind(wx.EVT_MENU, self.OnCommunicationMenu,
783               id=wxID_OBJDICTEDITEDITMENUITEMS2)
784         self.Bind(wx.EVT_MENU, self.OnRefreshMenu,
785               id=wxID_OBJDICTEDITEDITMENUITEMS4)
786         self.Bind(wx.EVT_MENU, self.OnNodeInfosMenu,
787               id=wxID_OBJDICTEDITEDITMENUITEMS6)
788         self.Bind(wx.EVT_MENU, self.OnEditProfileMenu,
789               id=wxID_OBJDICTEDITEDITMENUITEMS7)
790         self.Bind(wx.EVT_MENU, self.OnOtherCommunicationMenu,
791               id=wxID_OBJDICTEDITEDITMENUITEMS8)
792
793     def _init_coll_HelpMenu_Items(self, parent):
794         # generated method, don't edit
795
796         parent.Append(help='', id=wxID_OBJDICTEDITHELPMENUITEMS0,
797               kind=wx.ITEM_NORMAL, text='DS-301 Standard\tF1')
798         parent.Append(help='', id=wxID_OBJDICTEDITHELPMENUITEMS1,
799               kind=wx.ITEM_NORMAL, text='CAN Festival Docs\tF2')
800         parent.Append(help='', id=wxID_OBJDICTEDITHELPMENUITEMS2,
801               kind=wx.ITEM_NORMAL, text='About')
802         self.Bind(wx.EVT_MENU, self.OnHelpDS301Menu,
803               id=wxID_OBJDICTEDITHELPMENUITEMS0)
804         self.Bind(wx.EVT_MENU, self.OnHelpCANFestivalMenu,
805               id=wxID_OBJDICTEDITHELPMENUITEMS1)
806         self.Bind(wx.EVT_MENU, self.OnAboutMenu,
807               id=wxID_OBJDICTEDITHELPMENUITEMS2)
808
809     def _init_coll_FileMenu_Items(self, parent):
810         # generated method, don't edit
811
812         parent.Append(help='', id=wxID_OBJDICTEDITFILEMENUITEMS5,
813               kind=wx.ITEM_NORMAL, text='New\tCTRL+N')
814         parent.Append(help='', id=wxID_OBJDICTEDITFILEMENUITEMS0,
815               kind=wx.ITEM_NORMAL, text='Open\tCTRL+O')
816         parent.Append(help='', id=wxID_OBJDICTEDITFILEMENUITEMS1,
817               kind=wx.ITEM_NORMAL, text='Save\tCTRL+S')
818         parent.Append(help='', id=wxID_OBJDICTEDITFILEMENUITEMS6,
819               kind=wx.ITEM_NORMAL, text='Save As...\tALT+S')
820         parent.Append(help='', id=wxID_OBJDICTEDITFILEMENUITEMS2,
821               kind=wx.ITEM_NORMAL, text='Close\tCTRL+W')
822         parent.AppendSeparator()
823         parent.Append(help='', id=wxID_OBJDICTEDITFILEMENUITEMS7,
824               kind=wx.ITEM_NORMAL, text='Import XML file')
825         parent.Append(help='', id=wxID_OBJDICTEDITFILEMENUITEMS8,
826               kind=wx.ITEM_NORMAL, text='Build Dictionary\tCTRL+B')
827         parent.AppendSeparator()
828         parent.Append(help='', id=wxID_OBJDICTEDITFILEMENUITEMS4,
829               kind=wx.ITEM_NORMAL, text='Exit')
830         self.Bind(wx.EVT_MENU, self.OnOpenMenu,
831               id=wxID_OBJDICTEDITFILEMENUITEMS0)
832         self.Bind(wx.EVT_MENU, self.OnSaveMenu,
833               id=wxID_OBJDICTEDITFILEMENUITEMS1)
834         self.Bind(wx.EVT_MENU, self.OnCloseMenu,
835               id=wxID_OBJDICTEDITFILEMENUITEMS2)
836         self.Bind(wx.EVT_MENU, self.OnQuitMenu,
837               id=wxID_OBJDICTEDITFILEMENUITEMS4)
838         self.Bind(wx.EVT_MENU, self.OnNewMenu,
839               id=wxID_OBJDICTEDITFILEMENUITEMS5)
840         self.Bind(wx.EVT_MENU, self.OnSaveAsMenu,
841               id=wxID_OBJDICTEDITFILEMENUITEMS6)
842         self.Bind(wx.EVT_MENU, self.OnImportMenu,
843               id=wxID_OBJDICTEDITFILEMENUITEMS7)
844         self.Bind(wx.EVT_MENU, self.OnExportMenu,
845               id=wxID_OBJDICTEDITFILEMENUITEMS8)
846
847     def _init_coll_AddMenu_Items(self, parent):
848         # generated method, don't edit
849
850         parent.Append(help='', id=wxID_OBJDICTEDITADDMENUITEMS0,
851               kind=wx.ITEM_NORMAL, text='SDO Server')
852         parent.Append(help='', id=wxID_OBJDICTEDITADDMENUITEMS1,
853               kind=wx.ITEM_NORMAL, text='SDO Client')
854         parent.Append(help='', id=wxID_OBJDICTEDITADDMENUITEMS2,
855               kind=wx.ITEM_NORMAL, text='PDO Transmit')
856         parent.Append(help='', id=wxID_OBJDICTEDITADDMENUITEMS3,
857               kind=wx.ITEM_NORMAL, text='PDO Receive')
858         parent.Append(help='', id=wxID_OBJDICTEDITADDMENUITEMS4,
859               kind=wx.ITEM_NORMAL, text='Map Variable')
860         parent.Append(help='', id=wxID_OBJDICTEDITADDMENUITEMS5,
861               kind=wx.ITEM_NORMAL, text='User Type')
862         self.Bind(wx.EVT_MENU, self.OnAddSDOServerMenu,
863               id=wxID_OBJDICTEDITADDMENUITEMS0)
864         self.Bind(wx.EVT_MENU, self.OnAddSDOClientMenu,
865               id=wxID_OBJDICTEDITADDMENUITEMS1)
866         self.Bind(wx.EVT_MENU, self.OnAddPDOTransmitMenu,
867               id=wxID_OBJDICTEDITADDMENUITEMS2)
868         self.Bind(wx.EVT_MENU, self.OnAddPDOReceiveMenu,
869               id=wxID_OBJDICTEDITADDMENUITEMS3)
870         self.Bind(wx.EVT_MENU, self.OnAddMapVariableMenu,
871               id=wxID_OBJDICTEDITADDMENUITEMS4)
872         self.Bind(wx.EVT_MENU, self.OnAddUserTypeMenu,
873               id=wxID_OBJDICTEDITADDMENUITEMS5)
874
875     def _init_coll_HelpBar_Fields(self, parent):
876         # generated method, don't edit
877         parent.SetFieldsCount(3)
878
879         parent.SetStatusText(number=0, text='')
880         parent.SetStatusText(number=1, text='')
881         parent.SetStatusText(number=2, text='')
882
883         parent.SetStatusWidths([100, 110, -1])
884
885     def _init_utils(self):
886         # generated method, don't edit
887         self.menuBar1 = wx.MenuBar()
888         self.menuBar1.SetEvtHandlerEnabled(True)
889
890         self.FileMenu = wx.Menu(title='')
891
892         self.EditMenu = wx.Menu(title='')
893
894         self.AddMenu = wx.Menu(title='')
895
896         self.HelpMenu = wx.Menu(title='')
897
898         self._init_coll_menuBar1_Menus(self.menuBar1)
899         self._init_coll_FileMenu_Items(self.FileMenu)
900         self._init_coll_EditMenu_Items(self.EditMenu)
901         self._init_coll_AddMenu_Items(self.AddMenu)
902         self._init_coll_HelpMenu_Items(self.HelpMenu)
903
904     def _init_ctrls(self, prnt):
905         # generated method, don't edit
906         wx.Frame.__init__(self, id=wxID_OBJDICTEDIT, name='objdictedit',
907               parent=prnt, pos=wx.Point(149, 178), size=wx.Size(1000, 700),
908               style=wx.DEFAULT_FRAME_STYLE, title='Objdictedit')
909         self._init_utils()
910         self.SetClientSize(wx.Size(1000, 700))
911         self.SetMenuBar(self.menuBar1)
912         self.Bind(wx.EVT_CLOSE, self.OnCloseFrame, id=wxID_OBJDICTEDIT)
913
914         self.FileOpened = wx.Notebook(id=wxID_OBJDICTEDITFILEOPENED,
915               name='FileOpened', parent=self, pos=wx.Point(0, 0),
916               size=wx.Size(0, 0), style=0)
917         self.FileOpened.Bind(wx.EVT_NOTEBOOK_PAGE_CHANGED,
918               self.OnFileSelectedChanged, id=wxID_OBJDICTEDITFILEOPENED)
919
920         self.HelpBar = wx.StatusBar(id=wxID_OBJDICTEDITHELPBAR, name='HelpBar',
921               parent=self, style=wxST_SIZEGRIP)
922         self._init_coll_HelpBar_Fields(self.HelpBar)
923         self.SetStatusBar(self.HelpBar)
924
925     def __init__(self, parent):
926         self._init_ctrls(parent)
927         self.HtmlFrameOpened = []
928         
929         self.Manager = NodeManager()
930         for filepath in filesOpen:
931             self.Manager.OpenFileInCurrent(filepath)
932             new_editingpanel = EditingPanel(self, self.Manager)
933             self.FileOpened.AddPage(new_editingpanel, "")
934             self.FileOpened.SetSelection(self.Manager.GetCurrentNodeIndex())
935         if self.Manager.CurrentDS302Defined(): 
936             self.EditMenu.Enable(wxID_OBJDICTEDITEDITMENUITEMS8, True)
937         else:
938             self.EditMenu.Enable(wxID_OBJDICTEDITEDITMENUITEMS8, False)
939         self.RefreshEditMenu()
940         self.RefreshBufferState()
941         self.RefreshProfileMenu()
942         self.RefreshMainMenu()
943
944         self.RefreshBufferState()
945         self.RefreshTitle()
946         self.RefreshMainMenu()
947
948     def GetNoteBook(self):
949         return self.FileOpened
950
951     def OnAddSDOServerMenu(self, event):
952         self.Manager.AddSDOServerToCurrent()
953         self.RefreshBufferState()
954         self.RefreshCurrentIndexList()
955         event.Skip()
956     
957     def OnAddSDOClientMenu(self, event):
958         self.Manager.AddSDOClientToCurrent()
959         self.RefreshBufferState()
960         self.RefreshCurrentIndexList()
961         event.Skip()
962
963     def OnAddPDOTransmitMenu(self, event):
964         self.Manager.AddPDOTransmitToCurrent()
965         self.RefreshBufferState()
966         self.RefreshCurrentIndexList()
967         event.Skip()
968
969     def OnAddPDOReceiveMenu(self, event):
970         self.Manager.AddPDOReceiveToCurrent()
971         self.RefreshBufferState()
972         self.RefreshCurrentIndexList()
973         event.Skip()
974
975     def OnAddMapVariableMenu(self, event):
976         self.AddMapVariable()
977         event.Skip()
978
979     def OnAddUserTypeMenu(self, event):
980         self.AddUserType()
981         event.Skip()
982
983     def OnFileSelectedChanged(self, event):
984         selected = event.GetSelection()
985         # At init selected = -1
986         if selected >= 0:
987                 self.Manager.ChangeCurrentNode(selected)
988                 self.RefreshBufferState()
989                 self.RefreshProfileMenu()
990         event.Skip()
991
992     def OnHelpDS301Menu(self, event):
993         selected = self.FileOpened.GetSelection()
994         if selected >= 0:
995             window = self.FileOpened.GetPage(selected)
996             result = window.GetSelection()
997             if result:
998                 index, subIndex = result
999                 result = OpenPDFDocIndex(index)
1000                 if type(result) == StringType:
1001                     message = wxMessageDialog(self, result, "ERROR", wxOK|wxICON_ERROR)
1002                     message.ShowModal()
1003                     message.Destroy()
1004         event.Skip()
1005         
1006     def OnHelpCANFestivalMenu(self, event):
1007         self.OpenHtmlFrame("CAN Festival Reference", "../doc/canfestival.html", wx.Size(1000, 600))
1008         event.Skip()
1009
1010     def OnAboutMenu(self, event):
1011         self.OpenHtmlFrame("About CAN Festival", "../doc/about.html", wx.Size(500, 450))
1012         event.Skip()
1013
1014     def OpenHtmlFrame(self, title, file, size):
1015         if title not in self.HtmlFrameOpened:
1016             self.HtmlFrameOpened.append(title)
1017             window = HtmlFrame(self, self.HtmlFrameOpened)
1018             window.SetTitle(title)
1019             window.SetHtmlPage(file)
1020             window.SetClientSize(size)
1021             window.Show()
1022
1023     def OnQuitMenu(self, event):
1024         self.Close()
1025         event.Skip()
1026     
1027     def OnCloseFrame(self, event):
1028         if self.Manager.OneFileHasChanged():
1029             dialog = wxMessageDialog(self, "There are changes, do you want to save?",  "Close Application", wxYES_NO|wxCANCEL|wxICON_QUESTION)
1030             answer = dialog.ShowModal()
1031             dialog.Destroy()
1032             if answer == wxID_YES:
1033                 self.Manager.ChangeCurrentNode(0)
1034                 for i in xrange(self.FileOpened.GetPageCount()):
1035                     if self.Manager.CurrentIsSaved():
1036                         self.Manager.CloseCurrent()
1037                     else:
1038                         self.Save()
1039                         self.Manager.CloseCurrent(True)
1040                 event.Skip()
1041             elif answer == wxID_NO:
1042                 for i in xrange(self.FileOpened.GetPageCount()):
1043                     self.Manager.CloseCurrent(True)
1044                 wxCallAfter(self.Close)
1045                 event.Skip()
1046         else:
1047             event.Skip()
1048
1049 #-------------------------------------------------------------------------------
1050 #                             Refresh Functions
1051 #-------------------------------------------------------------------------------
1052
1053     def RefreshTitle(self):
1054         if self.FileOpened.GetPageCount() > 0:
1055             self.SetTitle("Objdictedit - %s"%self.Manager.GetCurrentFilename())
1056         else:
1057             self.SetTitle("Objdictedit")
1058
1059     def OnRefreshMenu(self, event):
1060         self.RefreshCurrentIndexList()
1061         event.Skip()
1062
1063     def RefreshCurrentIndexList(self):
1064         selected = self.FileOpened.GetSelection()
1065         window = self.FileOpened.GetPage(selected)
1066         window.RefreshIndexList()
1067
1068     def RefreshStatusBar(self):
1069         window = self.FileOpened.GetPage(self.FileOpened.GetSelection())
1070         selection = window.GetSelection()
1071         if selection:
1072             index, subIndex = selection
1073             if self.Manager.IsCurrentEntry(index):
1074                 self.HelpBar.SetStatusText("Index: 0x%04X"%index, 0)
1075                 self.HelpBar.SetStatusText("Subindex: 0x%02X"%subIndex, 1)
1076                 entryinfos = self.Manager.GetEntryInfos(index)
1077                 name = entryinfos["name"]
1078                 category = "Optional"
1079                 if entryinfos["need"]:
1080                     category = "Mandatory"
1081                 struct = "VAR"
1082                 number = ""
1083                 if entryinfos["struct"] & OD_IdenticalIndexes:
1084                     number = " possibly defined %d times"%entryinfos["nbmax"]
1085                 if entryinfos["struct"] & OD_IdenticalSubindexes:
1086                     struct = "REC"
1087                 elif entryinfos["struct"] & OD_MultipleSubindexes:
1088                     struct = "ARRAY"
1089                 text = "%s: %s entry of struct %s%s."%(name,category,struct,number)
1090                 self.HelpBar.SetStatusText(text, 2)
1091             else:
1092                 for i in xrange(3):
1093                     self.HelpBar.SetStatusText("", i)
1094         else:
1095             for i in xrange(3):
1096                 self.HelpBar.SetStatusText("", i)
1097
1098     def RefreshMainMenu(self):
1099         if self.FileOpened.GetPageCount() > 0:
1100             self.menuBar1.EnableTop(1, True)
1101             self.menuBar1.EnableTop(2, True)
1102             self.FileMenu.Enable(wxID_OBJDICTEDITFILEMENUITEMS1, True)
1103             self.FileMenu.Enable(wxID_OBJDICTEDITFILEMENUITEMS2, True)
1104             self.FileMenu.Enable(wxID_OBJDICTEDITFILEMENUITEMS6, True)
1105             self.FileMenu.Enable(wxID_OBJDICTEDITFILEMENUITEMS8, True)
1106         else:
1107             self.menuBar1.EnableTop(1, False)      
1108             self.menuBar1.EnableTop(2, False)
1109             self.FileMenu.Enable(wxID_OBJDICTEDITFILEMENUITEMS1, False)
1110             self.FileMenu.Enable(wxID_OBJDICTEDITFILEMENUITEMS2, False)
1111             self.FileMenu.Enable(wxID_OBJDICTEDITFILEMENUITEMS6, False)
1112             self.FileMenu.Enable(wxID_OBJDICTEDITFILEMENUITEMS8, False)
1113
1114     def RefreshEditMenu(self):
1115         if self.FileOpened.GetPageCount() > 0:
1116             undo, redo = self.Manager.GetCurrentBufferState()
1117             self.EditMenu.FindItemByPosition(2).Enable(undo)
1118             self.EditMenu.FindItemByPosition(3).Enable(redo)
1119         else:
1120             self.EditMenu.FindItemByPosition(2).Enable(False)
1121             self.EditMenu.FindItemByPosition(3).Enable(False)
1122
1123     def RefreshProfileMenu(self):
1124         profile = self.Manager.GetCurrentProfileName()
1125         edititem = self.EditMenu.FindItemByPosition(8)
1126         length = self.AddMenu.GetMenuItemCount()
1127         for i in xrange(length-6):
1128             additem = self.AddMenu.FindItemByPosition(6)
1129             self.AddMenu.Delete(additem.GetId())
1130         if profile not in ("None", "DS-301"):
1131             edititem.SetText("%s Profile"%profile)
1132             edititem.Enable(True)
1133             self.AddMenu.AppendSeparator()
1134             for text, indexes in self.Manager.GetCurrentSpecificMenu():
1135                 new_id = wx.NewId()
1136                 self.AddMenu.Append(help='', id=new_id, kind=wx.ITEM_NORMAL, text=text)
1137                 self.Bind(wx.EVT_MENU, self.GetProfileCallBack(text), id=new_id)
1138         else:
1139             edititem.SetText("Other Profile")
1140             edititem.Enable(False)
1141         
1142
1143 #-------------------------------------------------------------------------------
1144 #                            Buffer Functions
1145 #-------------------------------------------------------------------------------
1146
1147     def RefreshBufferState(self):
1148         fileopened = self.Manager.GetAllFilenames()
1149         for idx, filename in enumerate(fileopened):
1150             self.FileOpened.SetPageText(idx, filename)
1151         self.RefreshEditMenu()
1152         self.RefreshTitle()
1153
1154     def OnUndoMenu(self, event):
1155         self.Manager.LoadCurrentPrevious()
1156         self.RefreshCurrentIndexList()
1157         self.RefreshBufferState()
1158         event.Skip()
1159
1160     def OnRedoMenu(self, event):
1161         self.Manager.LoadCurrentNext()
1162         self.RefreshCurrentIndexList()
1163         self.RefreshBufferState()
1164         event.Skip()
1165
1166
1167 #-------------------------------------------------------------------------------
1168 #                         Load and Save Funtions
1169 #-------------------------------------------------------------------------------
1170
1171     def OnNewMenu(self, event):
1172         self.FilePath = ""
1173         dialog = CreateNodeDialog(self)
1174         if dialog.ShowModal() == wxID_OK:
1175             name, id, type = dialog.GetValues()
1176             if name != "":
1177                 good = not name[0].isdigit()
1178                 for item in name.split("_"):
1179                     good &= item.isalnum()
1180             else:
1181                 good = False
1182             if good:
1183                 profile,filepath = dialog.GetProfile()
1184                 NMT = dialog.GetNMTManagement()
1185                 options = dialog.GetOptions()
1186                 result = self.Manager.CreateNewNode(name, id, type, profile, filepath, NMT, options)
1187                 if not IsOfType(result, StringType):
1188                     new_editingpanel = EditingPanel(self, self.Manager)
1189                     self.FileOpened.AddPage(new_editingpanel, "")
1190                     self.FileOpened.SetSelection(self.Manager.GetCurrentNodeIndex())
1191                     self.EditMenu.Enable(wxID_OBJDICTEDITEDITMENUITEMS8, False)
1192                     if "DS302" in options:
1193                         self.EditMenu.Enable(wxID_OBJDICTEDITEDITMENUITEMS8, True)
1194                     self.RefreshBufferState()
1195                     self.RefreshProfileMenu()
1196                     self.RefreshMainMenu()
1197                 else:
1198                     message = wxMessageDialog(self, result, "ERROR", wxOK|wxICON_ERROR)
1199                     message.ShowModal()
1200                     message.Destroy()
1201             else:
1202                 message = wxMessageDialog(self, "Node name can't be undefined or start with a digit and must be composed of alphanumerical characters or underscore!", "ERROR", wxOK|wxICON_ERROR)
1203                 message.ShowModal()
1204                 message.Destroy()
1205         event.Skip()
1206
1207     def OnOpenMenu(self, event):
1208         filepath = self.Manager.GetCurrentFilePath()
1209         if filepath != "":
1210             directory = os.path.dirname(filepath)
1211         else:
1212             directory = os.getcwd()
1213         dialog = wxFileDialog(self, "Choose a file", directory, "",  "OD files (*.od)|*.od|All files|*.*", wxOPEN)
1214         if dialog.ShowModal() == wxID_OK:
1215             filepath = dialog.GetPath()
1216             if os.path.isfile(filepath):
1217                 result = self.Manager.OpenFileInCurrent(filepath)
1218                 if type(result) != StringType:
1219                     new_editingpanel = EditingPanel(self, self.Manager)
1220                     self.FileOpened.AddPage(new_editingpanel, "")
1221                     self.FileOpened.SetSelection(self.Manager.GetCurrentNodeIndex())
1222                     if self.Manager.CurrentDS302Defined(): 
1223                         self.EditMenu.Enable(wxID_OBJDICTEDITEDITMENUITEMS8, True)
1224                     else:
1225                         self.EditMenu.Enable(wxID_OBJDICTEDITEDITMENUITEMS8, False)
1226                     self.RefreshEditMenu()
1227                     self.RefreshBufferState()
1228                     self.RefreshProfileMenu()
1229                     self.RefreshMainMenu()
1230                 else:
1231                     message = wxMessageDialog(self, e.args[0], "Error", wxOK|wxICON_ERROR)
1232                     message.ShowModal()
1233                     message.Destroy()
1234         dialog.Destroy()
1235         event.Skip()
1236
1237     def OnSaveMenu(self, event):
1238         self.Save()
1239         event.Skip()
1240     
1241     def OnSaveAsMenu(self, event):
1242         self.SaveAs()
1243         event.Skip()
1244         
1245     def Save(self):
1246         result = self.Manager.SaveCurrentInFile()
1247         if not result:
1248             self.SaveAs()
1249         elif type(result) != StringType:
1250             self.RefreshBufferState()
1251         else:
1252             message = wxMessageDialog(self, result, "Error", wxOK|wxICON_ERROR)
1253             message.ShowModal()
1254             message.Destroy()
1255
1256     def SaveAs(self):
1257         filepath = self.Manager.GetCurrentFilePath()
1258         if filepath != "":
1259             directory, filename = os.path.split(filepath)
1260         else:
1261             directory, filename = os.getcwd(), "%s.od"%self.Manager.GetCurrentNodeInfos()[0]
1262         dialog = wxFileDialog(self, "Choose a file", directory, filename,  "OD files (*.od)|*.od|All files|*.*", wxSAVE|wxOVERWRITE_PROMPT)
1263         if dialog.ShowModal() == wxID_OK:
1264             filepath = dialog.GetPath()
1265             if os.path.isdir(os.path.dirname(filepath)):
1266                 result = self.Manager.SaveCurrentInFile(filepath)
1267                 if type(result) != StringType:
1268                     self.RefreshBufferState()
1269                 else:
1270                     message = wxMessageDialog(self, result, "Error", wxOK|wxICON_ERROR)
1271                     message.ShowModal()
1272                     message.Destroy()
1273             else:
1274                 message = wxMessageDialog(self, "%s is not a valid folder!"%os.path.dirname(filepath), "Error", wxOK|wxICON_ERROR)
1275                 message.ShowModal()
1276                 message.Destroy()
1277         dialog.Destroy()
1278
1279     def OnCloseMenu(self, event):
1280         answer = wxID_YES
1281         result = self.Manager.CloseCurrent()
1282         if not result:
1283             dialog = wxMessageDialog(self, "There are changes, do you want to save?",  "Close File", wxYES_NO|wxCANCEL|wxICON_QUESTION)
1284             answer = dialog.ShowModal()
1285             dialog.Destroy()
1286             if answer == wxID_YES:
1287                 self.OnSaveMenu(event)
1288                 if self.Manager.CurrentIsSaved():
1289                     self.Manager.CloseCurrent()
1290             elif answer == wxID_NO:
1291                 self.Manager.CloseCurrent(True)
1292         if self.FileOpened.GetPageCount() > self.Manager.GetBufferNumber():
1293             current = self.FileOpened.GetSelection()
1294             self.FileOpened.DeletePage(current)
1295             if self.FileOpened.GetPageCount() > 0:
1296                 self.FileOpened.SetSelection(min(current, self.FileOpened.GetPageCount() - 1))
1297             self.RefreshBufferState()
1298             self.RefreshMainMenu()
1299         event.Skip()
1300         
1301
1302 #-------------------------------------------------------------------------------
1303 #                         Import and Export Functions
1304 #-------------------------------------------------------------------------------
1305
1306     def OnImportMenu(self, event):
1307         dialog = wxFileDialog(self, "Choose a file", os.getcwd(), "",  "XML OD files (*.xml)|*.xml|All files|*.*", wxOPEN)
1308         if dialog.ShowModal() == wxID_OK:
1309             filepath = dialog.GetPath()
1310             if os.path.isfile(filepath):
1311                 result = self.Manager.ImportCurrentFromFile(filepath)
1312                 if result:
1313                     if self.FileOpened.GetPageCount() == 0:
1314                         new_editingpanel = EditingPanel(self, self.Manager)
1315                         self.FileOpened.AddPage(new_editingpanel, "")
1316                         self.FileOpened.SetSelection(self.Manager.GetCurrentNodeIndex())
1317                     self.RefreshBufferState()
1318                     self.RefreshCurrentIndexList()
1319                     self.RefreshProfileMenu()
1320                     self.RefreshMainMenu()
1321                     message = wxMessageDialog(self, "Import successful", "Information", wxOK|wxICON_INFORMATION)
1322                     message.ShowModal()
1323                     message.Destroy()
1324         dialog.Destroy()
1325         event.Skip()
1326
1327     def OnExportMenu(self, event):
1328         dialog = wxFileDialog(self, "Choose a file", os.getcwd(), self.Manager.GetCurrentNodeInfos()[0],  "CANFestival OD files (*.c)|*.c|All files|*.*", wxSAVE|wxOVERWRITE_PROMPT)
1329         if dialog.ShowModal() == wxID_OK:
1330             filepath = dialog.GetPath()
1331             if os.path.isdir(os.path.dirname(filepath)):
1332                 path, extend = os.path.splitext(filepath)
1333                 if extend in ("", "."):
1334                     filepath = path + ".c"
1335                 result = self.Manager.ExportCurrentToFile(filepath)
1336                 if result:
1337                     message = wxMessageDialog(self, "Export successful", "Information", wxOK|wxICON_INFORMATION)
1338                     message.ShowModal()
1339                     message.Destroy()
1340             else:
1341                 message = wxMessageDialog(self, "%s is not a valid folder!"%os.path.dirname(filepath), "Error", wxOK|wxICON_ERROR)
1342                 message.ShowModal()
1343                 message.Destroy()
1344         dialog.Destroy()
1345         event.Skip()
1346
1347 #-------------------------------------------------------------------------------
1348 #                          Editing Profiles functions
1349 #-------------------------------------------------------------------------------
1350
1351     def OnCommunicationMenu(self, event):
1352         dictionary,current = self.Manager.GetCurrentCommunicationLists()
1353         self.EditProfile("Edit DS-301 Profile", dictionary, current)
1354         event.Skip()
1355     
1356     def OnOtherCommunicationMenu(self, event):
1357         dictionary,current = self.Manager.GetCurrentDS302Lists()
1358         self.EditProfile("Edit DS-301 Profile", dictionary, current)
1359         event.Skip()
1360     
1361     def OnEditProfileMenu(self, event):
1362         title = "Edit %s Profile"%self.Manager.GetCurrentProfileName()
1363         dictionary,current = self.Manager.GetCurrentProfileLists()
1364         self.EditProfile(title, dictionary, current)
1365         event.Skip()
1366     
1367     def EditProfile(self, title, dictionary, current):
1368         dialog = CommunicationDialog(self)
1369         dialog.SetTitle(title)
1370         dialog.SetIndexDictionary(dictionary)
1371         dialog.SetCurrentList(current)
1372         dialog.RefreshLists()
1373         if dialog.ShowModal() == wxID_OK:
1374             new_profile = dialog.GetCurrentList()
1375             addinglist = []
1376             removinglist = []
1377             for index in new_profile:
1378                 if index not in current:
1379                     addinglist.append(index)
1380             for index in current:
1381                 if index not in new_profile:
1382                     removinglist.append(index)
1383             self.Manager.ManageEntriesOfCurrent(addinglist, removinglist)
1384             self.Manager.GenerateMapList()
1385             self.Manager.BufferCurrentNode()
1386             self.RefreshBufferState()
1387             self.RefreshCurrentIndexList()
1388         dialog.Destroy()
1389
1390     def GetProfileCallBack(self, text):
1391         def ProfileCallBack(event):
1392             self.Manager.AddSpecificEntryToCurrent(text)
1393             self.RefreshBufferState()
1394             self.RefreshCurrentIndexList()
1395             event.Skip()
1396         return ProfileCallBack
1397
1398 #-------------------------------------------------------------------------------
1399 #                         Edit Node informations function
1400 #-------------------------------------------------------------------------------
1401
1402     def OnNodeInfosMenu(self, event):
1403         dialog = NodeInfosDialog(self)
1404         name,id,type = self.Manager.GetCurrentNodeInfos()
1405         profile = self.Manager.GetCurrentProfileName()
1406         dialog.SetProfiles([profile])
1407         dialog.SetValues(name, id, type, profile)
1408         if dialog.ShowModal() == wxID_OK:
1409             name,id,type,profile = dialog.GetValues()
1410             self.Manager.SetCurrentNodeInfos(name, id, type)
1411             self.RefreshBufferState()
1412             self.RefreshProfileMenu()
1413         event.Skip()
1414
1415
1416 #-------------------------------------------------------------------------------
1417 #                           Add User Types and Variables
1418 #-------------------------------------------------------------------------------
1419         
1420     def AddMapVariable(self):
1421         index = self.Manager.GetCurrentNextMapIndex()
1422         if index:
1423             dialog = MapVariableDialog(self)
1424             dialog.SetIndex(index)
1425             if dialog.ShowModal() == wxID_OK:
1426                 index, name, struct, number = dialog.GetValues()
1427                 result = self.Manager.AddMapVariableToCurrent(index, name, struct, number)
1428                 if type(result) != StringType:
1429                     self.RefreshBufferState()
1430                     self.RefreshCurrentIndexList()
1431                 else:
1432                     message = wxMessageDialog(self, result, "Error", wxOK|wxICON_ERROR)
1433                     message.ShowModal()
1434                     message.Destroy()
1435             dialog.Destroy()
1436         else:
1437             message = wxMessageDialog(self, result, "No map variable index left!", wxOK|wxICON_ERROR)
1438             message.ShowModal()
1439             message.Destroy()
1440         
1441     def AddUserType(self):
1442         dialog = UserTypeDialog(self)
1443         dialog.SetTypeList(self.Manager.GetCustomisableTypes())
1444         if dialog.ShowModal() == wxID_OK:
1445             type, min, max, length = dialog.GetValues()
1446             result = self.Manager.AddUserTypeToCurrent(type, min, max, length)
1447             if not IsOfType(result, StringType):
1448                 self.RefreshBufferState()
1449                 self.RefreshCurrentIndexList()
1450             else:
1451                 message = wxMessageDialog(self, result, "Error", wxOK|wxICON_ERROR)
1452                 message.ShowModal()
1453                 message.Destroy()
1454         dialog.Destroy()
1455
1456
1457
1458 #-------------------------------------------------------------------------------
1459 #                          Editing Communication Dialog
1460 #-------------------------------------------------------------------------------
1461
1462
1463 [wxID_COMMUNICATIONDIALOG, wxID_COMMUNICATIONDIALOGMAINPANEL,
1464  wxID_COMMUNICATIONDIALOGPOSSIBLEINDEXES, wxID_COMMUNICATIONDIALOGCURRENTINDEXES,
1465  wxID_COMMUNICATIONDIALOGSELECT, wxID_COMMUNICATIONDIALOGUNSELECT, 
1466  wxID_COMMUNICATIONDIALOGSTATICTEXT1, wxID_COMMUNICATIONDIALOGSTATICTEXT2
1467 ] = [wx.NewId() for _init_ctrls in range(8)]
1468
1469 class CommunicationDialog(wx.Dialog):
1470     def _init_coll_flexGridSizer1_Items(self, parent):
1471         # generated method, don't edit
1472
1473         parent.AddWindow(self.MainPanel, 0, border=0, flag=0)
1474
1475     def _init_sizers(self):
1476         # generated method, don't edit
1477         self.flexGridSizer1 = wx.FlexGridSizer(cols=1, hgap=0, rows=2, vgap=0)
1478
1479         self._init_coll_flexGridSizer1_Items(self.flexGridSizer1)
1480
1481         self.SetSizer(self.flexGridSizer1)
1482
1483     def _init_ctrls(self, prnt):
1484         # generated method, don't edit
1485         wx.Dialog.__init__(self, id=wxID_COMMUNICATIONDIALOG,
1486               name='CommunicationDialog', parent=prnt, pos=wx.Point(234, 216),
1487               size=wx.Size(726, 437), style=wx.DEFAULT_DIALOG_STYLE,
1488               title='Edit Communication Profile')
1489         self.SetClientSize(wx.Size(726, 437))
1490
1491         self.MainPanel = wx.Panel(id=wxID_COMMUNICATIONDIALOGMAINPANEL,
1492               name='MainPanel', parent=self, pos=wx.Point(0, 0),
1493               size=wx.Size(688, 382), style=wx.TAB_TRAVERSAL)
1494         self.MainPanel.SetAutoLayout(True)
1495
1496         self.PossibleIndexes = wx.ListBox(choices=[],
1497               id=wxID_COMMUNICATIONDIALOGPOSSIBLEINDEXES,
1498               name='PossibleIndexes', parent=self.MainPanel, pos=wx.Point(40,
1499               48), size=wx.Size(280, 320), style=wxLB_EXTENDED)
1500         self.PossibleIndexes.Bind(wx.EVT_LEFT_DCLICK, self.OnPossibleIndexesDClick,
1501               id=wxID_COMMUNICATIONDIALOGPOSSIBLEINDEXES)
1502
1503         self.CurrentIndexes = wx.ListBox(choices=[],
1504               id=wxID_COMMUNICATIONDIALOGCURRENTINDEXES, name='CurrentIndexes',
1505               parent=self.MainPanel, pos=wx.Point(400, 48), size=wx.Size(280,
1506               320), style=wxLB_EXTENDED)
1507         self.CurrentIndexes.Bind(wx.EVT_LEFT_DCLICK, self.OnCurrentIndexesDClick,
1508               id=wxID_COMMUNICATIONDIALOGCURRENTINDEXES)
1509
1510         self.Select = wx.Button(id=wxID_COMMUNICATIONDIALOGSELECT, label='>>',
1511               name='Select', parent=self.MainPanel, pos=wx.Point(345, 136),
1512               size=wx.Size(32, 32), style=0)
1513         self.Select.Bind(wx.EVT_BUTTON, self.OnSelectButton,
1514               id=wxID_COMMUNICATIONDIALOGSELECT)
1515
1516         self.Unselect = wx.Button(id=wxID_COMMUNICATIONDIALOGUNSELECT,
1517               label='<<', name='Unselect', parent=self.MainPanel,
1518               pos=wx.Point(345, 216), size=wx.Size(32, 30), style=0)
1519         self.Unselect.Bind(wx.EVT_BUTTON, self.OnUnselectButton,
1520               id=wxID_COMMUNICATIONDIALOGUNSELECT)
1521
1522         self.staticText1 = wx.StaticText(id=wxID_COMMUNICATIONDIALOGSTATICTEXT1,
1523               label='Possible Profile Indexes :', name='staticText1',
1524               parent=self.MainPanel, pos=wx.Point(40, 24), size=wx.Size(156,
1525               17), style=0)
1526
1527         self.staticText2 = wx.StaticText(id=wxID_COMMUNICATIONDIALOGSTATICTEXT2,
1528               label='Current Profile Indexes :', name='staticText2',
1529               parent=self.MainPanel, pos=wx.Point(400, 24), size=wx.Size(152,
1530               17), style=0)
1531
1532         self._init_sizers()
1533
1534     def __init__(self, parent):
1535         self._init_ctrls(parent)
1536         self.ButtonSizer = self.CreateButtonSizer(wxOK|wxCANCEL)
1537         self.flexGridSizer1.Add(self.ButtonSizer, 1, wxALIGN_CENTER)
1538         self.AllList = []
1539         self.CurrentList = []
1540         self.IndexDictionary = {}
1541
1542     def SetIndexDictionary(self, dictionary):
1543         self.IndexDictionary = dictionary
1544         
1545     def SetCurrentList(self, list):
1546         self.CurrentList = []
1547         self.CurrentList.extend(list)
1548         self.CurrentList.sort()
1549         
1550     def GetCurrentList(self):
1551         return self.CurrentList
1552         
1553     def RefreshLists(self):
1554         self.PossibleIndexes.Clear()
1555         self.CurrentIndexes.Clear()
1556         self.AllList = []
1557         for index in self.IndexDictionary.iterkeys():
1558             if index not in self.CurrentList:
1559                 self.AllList.append(index)
1560         self.AllList.sort()
1561         for index in self.AllList:
1562             self.PossibleIndexes.Append("0x%04X   %s"%(index, self.IndexDictionary[index][0]))
1563         for index in self.CurrentList:
1564             if index in self.IndexDictionary:
1565                 self.CurrentIndexes.Append("0x%04X   %s"%(index, self.IndexDictionary[index][0]))
1566
1567     def OnPossibleIndexesDClick(self, event):
1568         self.SelectPossible()
1569         event.Skip()
1570
1571     def OnCurrentIndexesDClick(self, event):
1572         self.UnselectCurrent()
1573         event.Skip()
1574
1575     def OnSelectButton(self, event):
1576         self.SelectPossible()
1577         event.Skip()
1578
1579     def OnUnselectButton(self, event):
1580         self.UnselectCurrent()
1581         event.Skip()
1582
1583     def SelectPossible(self):
1584         selected = self.PossibleIndexes.GetSelections()
1585         for i in selected:
1586             self.CurrentList.append(self.AllList[i])
1587         self.CurrentList.sort()
1588         self.RefreshLists()
1589
1590     def UnselectCurrent(self):
1591         selected = self.CurrentIndexes.GetSelections()
1592         for i in selected:
1593             if not self.IndexDictionary[self.CurrentList[i]][1]:
1594                 self.CurrentList.pop(i)
1595         self.CurrentList.sort()
1596         self.RefreshLists()
1597
1598
1599
1600 #-------------------------------------------------------------------------------
1601 #                          Create Map Variable Dialog
1602 #-------------------------------------------------------------------------------
1603
1604
1605 [wxID_MAPVARIABLEDIALOG, wxID_MAPVARIABLEDIALOGINDEX, 
1606  wxID_MAPVARIABLEDIALOGINDEXNAME, wxID_MAPVARIABLEDIALOGMAINPANEL, 
1607  wxID_MAPVARIABLEDIALOGNUMBER, wxID_MAPVARIABLEDIALOGRADIOBUTTON1, 
1608  wxID_MAPVARIABLEDIALOGRADIOBUTTON2, wxID_MAPVARIABLEDIALOGRADIOBUTTON3, 
1609  wxID_MAPVARIABLEDIALOGSTATICTEXT1, wxID_MAPVARIABLEDIALOGSTATICTEXT2, 
1610  wxID_MAPVARIABLEDIALOGSTATICTEXT3, wxID_MAPVARIABLEDIALOGSTATICTEXT4, 
1611 ] = [wx.NewId() for _init_ctrls in range(12)]
1612
1613 class MapVariableDialog(wx.Dialog):
1614     def _init_coll_flexGridSizer1_Items(self, parent):
1615         # generated method, don't edit
1616
1617         parent.AddWindow(self.MainPanel, 0, border=0, flag=0)
1618
1619     def _init_sizers(self):
1620         # generated method, don't edit
1621         self.flexGridSizer1 = wx.FlexGridSizer(cols=1, hgap=0, rows=2, vgap=0)
1622
1623         self._init_coll_flexGridSizer1_Items(self.flexGridSizer1)
1624
1625         self.SetSizer(self.flexGridSizer1)
1626
1627     def _init_ctrls(self, prnt):
1628         # generated method, don't edit
1629         wx.Dialog.__init__(self, id=wxID_MAPVARIABLEDIALOG,
1630               name='CommunicationDialog', parent=prnt, pos=wx.Point(376, 223),
1631               size=wx.Size(444, 186), style=wx.DEFAULT_DIALOG_STYLE,
1632               title='Add Map Variable')
1633         self.SetClientSize(wx.Size(444, 186))
1634
1635         self.MainPanel = wx.Panel(id=wxID_MAPVARIABLEDIALOGMAINPANEL,
1636               name='MainPanel', parent=self, pos=wx.Point(0, 0),
1637               size=wx.Size(431, 142), style=wx.TAB_TRAVERSAL)
1638         self.MainPanel.SetAutoLayout(True)
1639
1640         self.staticText1 = wx.StaticText(id=wxID_MAPVARIABLEDIALOGSTATICTEXT1,
1641               label='Index :', name='staticText1', parent=self.MainPanel,
1642               pos=wx.Point(24, 24), size=wx.Size(156, 17), style=0)
1643
1644         self.Index = wx.TextCtrl(id=wxID_MAPVARIABLEDIALOGINDEX, name='Index',
1645               parent=self.MainPanel, pos=wx.Point(24, 48), size=wx.Size(152,
1646               25), style=0, value='0x2000')
1647
1648         self.staticText3 = wx.StaticText(id=wxID_MAPVARIABLEDIALOGSTATICTEXT3,
1649               label='Name :', name='staticText3', parent=self.MainPanel,
1650               pos=wx.Point(24, 80), size=wx.Size(47, 17), style=0)
1651
1652         self.IndexName = wx.TextCtrl(id=wxID_MAPVARIABLEDIALOGINDEXNAME,
1653               name='IndexName', parent=self.MainPanel, pos=wx.Point(24, 104),
1654               size=wx.Size(152, 24), style=0, value='Undefined')
1655
1656         self.staticText2 = wx.StaticText(id=wxID_MAPVARIABLEDIALOGSTATICTEXT2,
1657               label='Type :', name='staticText2', parent=self.MainPanel,
1658               pos=wx.Point(208, 24), size=wx.Size(38, 17), style=0)
1659
1660         self.radioButton1 = wx.RadioButton(id=wxID_MAPVARIABLEDIALOGRADIOBUTTON1,
1661               label='VAR', name='radioButton1', parent=self.MainPanel,
1662               pos=wx.Point(208, 48), size=wx.Size(72, 24), style=wxRB_GROUP)
1663         self.radioButton1.SetValue(True)
1664         self.radioButton1.Bind(wx.EVT_RADIOBUTTON, self.OnRadioButton1Click,
1665               id=wxID_MAPVARIABLEDIALOGRADIOBUTTON1)
1666
1667         self.radioButton2 = wx.RadioButton(id=wxID_MAPVARIABLEDIALOGRADIOBUTTON2,
1668               label='ARRAY', name='radioButton2', parent=self.MainPanel,
1669               pos=wx.Point(208, 72), size=wx.Size(80, 24), style=wxRB_SINGLE)
1670         self.radioButton2.SetValue(False)
1671         self.radioButton2.Bind(wx.EVT_RADIOBUTTON, self.OnRadioButton2Click,
1672               id=wxID_MAPVARIABLEDIALOGRADIOBUTTON2)
1673
1674         self.radioButton3 = wx.RadioButton(id=wxID_MAPVARIABLEDIALOGRADIOBUTTON3,
1675               label='REC', name='radioButton3', parent=self.MainPanel,
1676               pos=wx.Point(208, 96), size=wx.Size(96, 24), style=wxRB_SINGLE)
1677         self.radioButton3.SetValue(False)
1678         self.radioButton3.Bind(wx.EVT_RADIOBUTTON, self.OnRadioButton3Click,
1679               id=wxID_MAPVARIABLEDIALOGRADIOBUTTON3)
1680
1681         self.staticText4 = wx.StaticText(id=wxID_MAPVARIABLEDIALOGSTATICTEXT4,
1682               label='Number :', name='staticText4', parent=self.MainPanel,
1683               pos=wx.Point(312, 80), size=wx.Size(88, 16), style=0)
1684
1685         self.Number = wx.TextCtrl(id=wxID_MAPVARIABLEDIALOGNUMBER,
1686               name='Number', parent=self.MainPanel, pos=wx.Point(312, 104),
1687               size=wx.Size(112, 24), style=wx.TE_RIGHT, value='0')
1688
1689         self._init_sizers()
1690
1691     def __init__(self, parent):
1692         self._init_ctrls(parent)
1693         self.ButtonSizer = self.CreateButtonSizer(wxOK|wxCANCEL)
1694         self.flexGridSizer1.Add(self.ButtonSizer, 1, wxALIGN_CENTER)
1695         self.staticText4.Enable(False)
1696         self.Number.Enable(False)
1697
1698     def SetIndex(self, index):
1699         self.Index.SetValue("0x%04X"%index)
1700
1701     def GetValues(self):
1702         if self.radioButton1.GetValue():
1703             struct = 1
1704         elif self.radioButton2.GetValue():
1705             struct = 3
1706         elif self.radioButton3.GetValue():
1707             struct = 7
1708         name = self.IndexName.GetValue()
1709         index = eval(self.Index.GetValue())
1710         number = eval(self.Number.GetValue())
1711         return index, name, struct, number
1712
1713     def OnRadioButton1Click(self, event):
1714         self.EnableNumberTyping(False)
1715         event.Skip()
1716
1717     def OnRadioButton2Click(self, event):
1718         self.EnableNumberTyping(True)
1719         event.Skip()
1720
1721     def OnRadioButton3Click(self, event):
1722         self.EnableNumberTyping(True)
1723         event.Skip()
1724
1725     def EnableNumberTyping(self, enable):
1726         self.staticText4.Enable(enable)
1727         self.Number.Enable(enable)
1728
1729
1730 #-------------------------------------------------------------------------------
1731 #                          Create User Type Dialog
1732 #-------------------------------------------------------------------------------
1733
1734
1735 [wxID_USERTYPEDIALOG, wxID_USERTYPEDIALOGLENGTH, wxID_USERTYPEDIALOGMAINPANEL, 
1736  wxID_USERTYPEDIALOGMAX, wxID_USERTYPEDIALOGMIN, 
1737  wxID_USERTYPEDIALOGSTATICBOX1, wxID_USERTYPEDIALOGSTATICTEXT1, 
1738  wxID_USERTYPEDIALOGSTATICTEXT2, wxID_USERTYPEDIALOGSTATICTEXT3, 
1739  wxID_USERTYPEDIALOGSTATICTEXT4, wxID_USERTYPEDIALOGTYPE, 
1740 ] = [wx.NewId() for _init_ctrls in range(11)]
1741
1742 class UserTypeDialog(wx.Dialog):
1743     def _init_coll_flexGridSizer1_Items(self, parent):
1744         # generated method, don't edit
1745
1746         parent.AddWindow(self.MainPanel, 0, border=0, flag=0)
1747
1748     def _init_sizers(self):
1749         # generated method, don't edit
1750         self.flexGridSizer1 = wx.FlexGridSizer(cols=1, hgap=0, rows=2, vgap=0)
1751
1752         self._init_coll_flexGridSizer1_Items(self.flexGridSizer1)
1753
1754         self.SetSizer(self.flexGridSizer1)
1755
1756     def _init_ctrls(self, prnt):
1757         # generated method, don't edit
1758         wx.Dialog.__init__(self, id=wxID_USERTYPEDIALOG, name='UserTypeDialog',
1759               parent=prnt, pos=wx.Point(376, 223), size=wx.Size(444, 228),
1760               style=wx.DEFAULT_DIALOG_STYLE, title='Add User Type')
1761         self.SetClientSize(wx.Size(444, 228))
1762
1763         self.MainPanel = wx.Panel(id=wxID_USERTYPEDIALOGMAINPANEL,
1764               name='MainPanel', parent=self, pos=wx.Point(0, 0),
1765               size=wx.Size(431, 182), style=wx.TAB_TRAVERSAL)
1766         self.MainPanel.SetAutoLayout(True)
1767
1768         self.staticText1 = wx.StaticText(id=wxID_USERTYPEDIALOGSTATICTEXT1,
1769               label='Type :', name='staticText1', parent=self.MainPanel,
1770               pos=wx.Point(24, 24), size=wx.Size(156, 17), style=0)
1771
1772         self.Type = wx.Choice(choices=[], id=wxID_USERTYPEDIALOGTYPE,
1773               name='Type', parent=self.MainPanel, pos=wx.Point(24, 48),
1774               size=wx.Size(160, 24), style=0)
1775         self.Type.Bind(wx.EVT_CHOICE, self.OnTypeChoice,
1776               id=wxID_USERTYPEDIALOGTYPE)
1777
1778         self.staticBox1 = wx.StaticBox(id=wxID_USERTYPEDIALOGSTATICBOX1,
1779               label='Values', name='staticBox1', parent=self.MainPanel,
1780               pos=wx.Point(200, 24), size=wx.Size(224, 144), style=0)
1781
1782         self.staticText2 = wx.StaticText(id=wxID_USERTYPEDIALOGSTATICTEXT2,
1783               label='Minimum :', name='staticText2', parent=self.MainPanel,
1784               pos=wx.Point(216, 48), size=wx.Size(67, 17), style=0)
1785
1786         self.Min = wx.TextCtrl(id=wxID_USERTYPEDIALOGMIN, name='Min',
1787               parent=self.MainPanel, pos=wx.Point(296, 48), size=wx.Size(112,
1788               24), style=wx.TE_RIGHT, value='0')
1789
1790         self.staticText3 = wx.StaticText(id=wxID_USERTYPEDIALOGSTATICTEXT3,
1791               label='Maximum :', name='staticText3', parent=self.MainPanel,
1792               pos=wx.Point(216, 88), size=wx.Size(71, 17), style=0)
1793
1794         self.Max = wx.TextCtrl(id=wxID_USERTYPEDIALOGMAX, name='Max',
1795               parent=self.MainPanel, pos=wx.Point(296, 88), size=wx.Size(112,
1796               25), style=wx.TE_RIGHT, value='0')
1797
1798         self.staticText4 = wx.StaticText(id=wxID_USERTYPEDIALOGSTATICTEXT4,
1799               label='Length :', name='staticText4', parent=self.MainPanel,
1800               pos=wx.Point(216, 128), size=wx.Size(52, 17), style=0)
1801
1802         self.Length = wx.TextCtrl(id=wxID_USERTYPEDIALOGLENGTH, name='Length',
1803               parent=self.MainPanel, pos=wx.Point(296, 128), size=wx.Size(112,
1804               25), style=wx.TE_RIGHT, value='0')
1805
1806         self._init_sizers()
1807
1808     def __init__(self, parent):
1809         self._init_ctrls(parent)
1810         self.ButtonSizer = self.CreateButtonSizer(wxOK|wxCANCEL)
1811         self.flexGridSizer1.Add(self.ButtonSizer, 1, wxALIGN_CENTER)
1812         self.TypeDictionary = {}
1813         
1814     def SetValues(self, min = None, max = None, length = None):
1815         if min != None:
1816             self.Min.SetValue(str(min))
1817         if max != None:
1818             self.Max.SetValue(str(max))
1819         if length != None:
1820             self.Length.SetValue(str(length))
1821
1822     def SetTypeList(self, typedic, type = None):
1823         self.Type.Clear()
1824         list = []
1825         for index, (name, valuetype) in typedic.iteritems():
1826             self.TypeDictionary[name] = (index, valuetype)
1827             list.append((index, name))
1828         list.sort()
1829         for index, name in list:
1830             self.Type.Append(name)
1831         if type != None:
1832             self.Type.SetStringSelection(typedic[type][0])
1833         self.RefreshValues()
1834
1835     def OnTypeChoice(self, event):
1836         self.RefreshValues()
1837         event.Skip()
1838     
1839     def RefreshValues(self):
1840         name = self.Type.GetStringSelection()
1841         if name != "":
1842             valuetype = self.TypeDictionary[name][1]
1843             if valuetype == 0:
1844                 self.staticText2.Enable(True)
1845                 self.staticText3.Enable(True)
1846                 self.staticText4.Enable(False)
1847                 self.Min.Enable(True)
1848                 self.Max.Enable(True)
1849                 self.Length.Enable(False)
1850             elif valuetype == 1:
1851                 self.staticText2.Enable(False)
1852                 self.staticText3.Enable(False)
1853                 self.staticText4.Enable(True)
1854                 self.Min.Enable(False)
1855                 self.Max.Enable(False)
1856                 self.Length.Enable(True)
1857         else:
1858             self.staticText2.Enable(False)
1859             self.staticText3.Enable(False)
1860             self.staticText4.Enable(False)
1861             self.Min.Enable(False)
1862             self.Max.Enable(False)
1863             self.Length.Enable(False)
1864
1865     def GetValues(self):
1866         name = self.Type.GetStringSelection()
1867         type = self.TypeDictionary[name][0]
1868         min = eval(self.Min.GetValue())
1869         max = eval(self.Max.GetValue())
1870         length = eval(self.Length.GetValue())
1871         return type, min, max, length
1872
1873
1874
1875 #-------------------------------------------------------------------------------
1876 #                          Editing Node Infos Dialog
1877 #-------------------------------------------------------------------------------
1878
1879
1880 [wxID_NODEINFOSDIALOG, wxID_NODEINFOSDIALOGMAINPANEL, 
1881  wxID_NODEINFOSDIALOGNAME, wxID_NODEINFOSDIALOGNODEID, 
1882  wxID_NODEINFOSDIALOGPROFILE, wxID_NODEINFOSDIALOGSTATICTEXT1, 
1883  wxID_NODEINFOSDIALOGSTATICTEXT2, wxID_NODEINFOSDIALOGSTATICTEXT3, 
1884  wxID_NODEINFOSDIALOGSTATICTEXT4, wxID_NODEINFOSDIALOGTYPE, 
1885 ] = [wx.NewId() for _init_ctrls in range(10)]
1886
1887 class NodeInfosDialog(wx.Dialog):
1888     def _init_coll_flexGridSizer1_Items(self, parent):
1889         # generated method, don't edit
1890
1891         parent.AddWindow(self.MainPanel, 0, border=0, flag=0)
1892
1893     def _init_sizers(self):
1894         # generated method, don't edit
1895         self.flexGridSizer1 = wx.FlexGridSizer(cols=1, hgap=0, rows=2, vgap=0)
1896
1897         self._init_coll_flexGridSizer1_Items(self.flexGridSizer1)
1898
1899         self.SetSizer(self.flexGridSizer1)
1900
1901     def _init_ctrls(self, prnt):
1902         # generated method, don't edit
1903         wx.Dialog.__init__(self, id=wxID_NODEINFOSDIALOG,
1904               name='NodeInfosDialog', parent=prnt, pos=wx.Point(376, 223),
1905               size=wx.Size(249, 250), style=wx.DEFAULT_DIALOG_STYLE,
1906               title='Node Infos')
1907         self.SetClientSize(wx.Size(249, 250))
1908
1909         self.MainPanel = wx.Panel(id=wxID_NODEINFOSDIALOGMAINPANEL,
1910               name='MainPanel', parent=self, pos=wx.Point(0, 0),
1911               size=wx.Size(231, 264), style=wx.TAB_TRAVERSAL)
1912         self.MainPanel.SetAutoLayout(True)
1913
1914         self.staticText1 = wx.StaticText(id=wxID_NODEINFOSDIALOGSTATICTEXT1,
1915               label='Name :', name='staticText1', parent=self.MainPanel,
1916               pos=wx.Point(24, 24), size=wx.Size(156, 17), style=0)
1917
1918         self.Name = wx.TextCtrl(id=wxID_NODEINFOSDIALOGNAME, name='Name',
1919               parent=self.MainPanel, pos=wx.Point(24, 48), size=wx.Size(200,
1920               25), style=0, value='')
1921
1922         self.staticText2 = wx.StaticText(id=wxID_NODEINFOSDIALOGSTATICTEXT2,
1923               label='Node ID :', name='staticText2', parent=self.MainPanel,
1924               pos=wx.Point(24, 80), size=wx.Size(67, 17), style=0)
1925
1926         self.NodeID = wx.TextCtrl(id=wxID_NODEINFOSDIALOGNODEID, name='NodeID',
1927               parent=self.MainPanel, pos=wx.Point(24, 104), size=wx.Size(200,
1928               25), style=wx.TE_RIGHT, value='')
1929
1930         self.staticText3 = wx.StaticText(id=wxID_NODEINFOSDIALOGSTATICTEXT3,
1931               label='Type :', name='staticText3', parent=self.MainPanel,
1932               pos=wx.Point(24, 136), size=wx.Size(71, 17), style=0)
1933
1934         self.Type = wx.Choice(choices=[], id=wxID_NODEINFOSDIALOGTYPE,
1935               name='Type', parent=self.MainPanel, pos=wx.Point(24, 160),
1936               size=wx.Size(200, 25), style=0)
1937
1938         self.staticText4 = wx.StaticText(id=wxID_NODEINFOSDIALOGSTATICTEXT4,
1939               label='Profile :', name='staticText4', parent=self.MainPanel,
1940               pos=wx.Point(24, 192), size=wx.Size(47, 17), style=0)
1941
1942         self.Profile = wx.Choice(choices=[], id=wxID_NODEINFOSDIALOGPROFILE,
1943               name='Profile', parent=self.MainPanel, pos=wx.Point(24, 216),
1944               size=wx.Size(200, 25), style=0)
1945
1946         self._init_sizers()
1947
1948     def __init__(self, parent):
1949         self._init_ctrls(parent)
1950         self.ButtonSizer = self.CreateButtonSizer(wxOK|wxCANCEL)
1951         self.flexGridSizer1.Add(self.ButtonSizer, 1, wxALIGN_CENTER)
1952         self.Type.Append("master")
1953         self.Type.Append("slave")
1954         self.staticText4.Hide()
1955         self.Profile.Hide()
1956     
1957     def SetProfiles(self, profiles):
1958         for profile in profiles:
1959             self.Profile.Append(profile)
1960     
1961     def SetValues(self, name, id, type, profile):
1962         self.Name.SetValue(name)
1963         self.NodeID.SetValue("0x%02X"%id)
1964         self.Type.SetStringSelection(type)
1965         self.Profile.SetStringSelection(profile)
1966
1967     def GetValues(self):
1968         name = self.Name.GetValue()
1969         nodeid = eval(self.NodeID.GetValue())
1970         type = self.Type.GetStringSelection()
1971         profile = self.Profile.GetStringSelection()
1972         return name, nodeid, type, profile
1973
1974
1975
1976 #-------------------------------------------------------------------------------
1977 #                          Create New Node Dialog
1978 #-------------------------------------------------------------------------------
1979
1980
1981 [wxID_CREATENODEDIALOG, wxID_CREATENODEDIALOGEMERGENCY, 
1982  wxID_CREATENODEDIALOGGENSYNC, wxID_CREATENODEDIALOGMAINPANEL, 
1983  wxID_CREATENODEDIALOGNAME, wxID_CREATENODEDIALOGNMT_HEARTBEAT, 
1984  wxID_CREATENODEDIALOGNMT_NODEGUARDING, wxID_CREATENODEDIALOGNMT_NONE, 
1985  wxID_CREATENODEDIALOGNODEID, wxID_CREATENODEDIALOGPROFILE, 
1986  wxID_CREATENODEDIALOGSAVECONFIG, wxID_CREATENODEDIALOGSTATICTEXT1, 
1987  wxID_CREATENODEDIALOGSTATICTEXT2, wxID_CREATENODEDIALOGSTATICTEXT3, 
1988  wxID_CREATENODEDIALOGSTATICTEXT4, wxID_CREATENODEDIALOGSTATICTEXT5, 
1989  wxID_CREATENODEDIALOGSTATICTEXT6, wxID_CREATENODEDIALOGSTOREEDS, 
1990  wxID_CREATENODEDIALOGTYPE, 
1991 ] = [wx.NewId() for _init_ctrls in range(19)]
1992
1993 class CreateNodeDialog(wx.Dialog):
1994     def _init_coll_flexGridSizer1_Items(self, parent):
1995         # generated method, don't edit
1996
1997         parent.AddWindow(self.MainPanel, 0, border=0, flag=0)
1998
1999     def _init_sizers(self):
2000         # generated method, don't edit
2001         self.flexGridSizer1 = wx.FlexGridSizer(cols=1, hgap=0, rows=2, vgap=0)
2002
2003         self._init_coll_flexGridSizer1_Items(self.flexGridSizer1)
2004
2005         self.SetSizer(self.flexGridSizer1)
2006
2007     def _init_ctrls(self, prnt):
2008         # generated method, don't edit
2009         wx.Dialog.__init__(self, id=wxID_CREATENODEDIALOG,
2010               name='CreateNodeDialog', parent=prnt, pos=wx.Point(376, 223),
2011               size=wx.Size(451, 316), style=wx.DEFAULT_DIALOG_STYLE,
2012               title='Create a new Node')
2013         self.SetClientSize(wx.Size(451, 316))
2014
2015         self.MainPanel = wx.Panel(id=wxID_CREATENODEDIALOGMAINPANEL,
2016               name='MainPanel', parent=self, pos=wx.Point(0, 0),
2017               size=wx.Size(440, 278), style=wx.TAB_TRAVERSAL)
2018         self.MainPanel.SetAutoLayout(True)
2019
2020         self.staticText1 = wx.StaticText(id=wxID_CREATENODEDIALOGSTATICTEXT1,
2021               label='Name :', name='staticText1', parent=self.MainPanel,
2022               pos=wx.Point(24, 24), size=wx.Size(156, 17), style=0)
2023
2024         self.staticText2 = wx.StaticText(id=wxID_CREATENODEDIALOGSTATICTEXT2,
2025               label='Node ID :', name='staticText2', parent=self.MainPanel,
2026               pos=wx.Point(24, 80), size=wx.Size(67, 17), style=0)
2027
2028         self.staticText3 = wx.StaticText(id=wxID_CREATENODEDIALOGSTATICTEXT3,
2029               label='Type :', name='staticText3', parent=self.MainPanel,
2030               pos=wx.Point(24, 136), size=wx.Size(71, 17), style=0)
2031
2032         self.Type = wx.Choice(choices=[], id=wxID_CREATENODEDIALOGTYPE,
2033               name='Type', parent=self.MainPanel, pos=wx.Point(24, 160),
2034               size=wx.Size(200, 24), style=0)
2035
2036         self.Name = wx.TextCtrl(id=wxID_CREATENODEDIALOGNAME, name='Name',
2037               parent=self.MainPanel, pos=wx.Point(24, 48), size=wx.Size(200,
2038               25), style=0, value='')
2039
2040         self.NodeID = wx.TextCtrl(id=wxID_CREATENODEDIALOGNODEID, name='NodeID',
2041               parent=self.MainPanel, pos=wx.Point(24, 104), size=wx.Size(200,
2042               25), style=wx.TE_RIGHT, value='')
2043
2044         self.staticText4 = wx.StaticText(id=wxID_CREATENODEDIALOGSTATICTEXT4,
2045               label='Profile :', name='staticText4', parent=self.MainPanel,
2046               pos=wx.Point(24, 192), size=wx.Size(47, 17), style=0)
2047
2048         self.Profile = wx.Choice(choices=[], id=wxID_CREATENODEDIALOGPROFILE,
2049               name='Profile', parent=self.MainPanel, pos=wx.Point(24, 216),
2050               size=wx.Size(200, 24), style=0)
2051         self.Profile.Bind(wx.EVT_CHOICE, self.OnProfileChoice,
2052               id=wxID_CREATENODEDIALOGPROFILE)
2053
2054         self.staticText5 = wx.StaticText(id=wxID_CREATENODEDIALOGSTATICTEXT5,
2055               label='Network Management :', name='staticText5',
2056               parent=self.MainPanel, pos=wx.Point(256, 24), size=wx.Size(152,
2057               16), style=0)
2058
2059         self.NMT_None = wx.RadioButton(id=wxID_CREATENODEDIALOGNMT_NONE,
2060               label='None', name='NMT_None', parent=self.MainPanel,
2061               pos=wx.Point(256, 40), size=wx.Size(114, 24), style=0)
2062         self.NMT_None.SetValue(True)
2063
2064         self.NMT_NodeGuarding = wx.RadioButton(id=wxID_CREATENODEDIALOGNMT_NODEGUARDING,
2065               label='Node Guarding', name='NMT_NodeGuarding',
2066               parent=self.MainPanel, pos=wx.Point(256, 64), size=wx.Size(128,
2067               24), style=0)
2068         self.NMT_NodeGuarding.SetValue(False)
2069
2070         self.NMT_Heartbeat = wx.RadioButton(id=wxID_CREATENODEDIALOGNMT_HEARTBEAT,
2071               label='Heartbeat', name='NMT_Heartbeat', parent=self.MainPanel,
2072               pos=wx.Point(256, 88), size=wx.Size(114, 24), style=0)
2073         self.NMT_Heartbeat.SetValue(False)
2074
2075         self.staticText6 = wx.StaticText(id=wxID_CREATENODEDIALOGSTATICTEXT6,
2076               label='Options :', name='staticText6', parent=self.MainPanel,
2077               pos=wx.Point(256, 128), size=wx.Size(72, 17), style=0)
2078
2079         self.DS302 = wx.CheckBox(id=wxID_CREATENODEDIALOGGENSYNC,
2080               label='DS-302 Profile', name='DS302', parent=self.MainPanel,
2081               pos=wx.Point(256, 144), size=wx.Size(128, 24), style=0)
2082         self.DS302.SetValue(False)
2083
2084         self.GenSYNC = wx.CheckBox(id=wxID_CREATENODEDIALOGGENSYNC,
2085               label='Generate SYNC', name='GenSYNC', parent=self.MainPanel,
2086               pos=wx.Point(256, 168), size=wx.Size(128, 24), style=0)
2087         self.GenSYNC.SetValue(False)
2088
2089         self.Emergency = wx.CheckBox(id=wxID_CREATENODEDIALOGEMERGENCY,
2090               label='Emergency support', name='Emergency',
2091               parent=self.MainPanel, pos=wx.Point(256, 192), size=wx.Size(152,
2092               24), style=0)
2093         self.Emergency.SetValue(False)
2094
2095         self.SaveConfig = wx.CheckBox(id=wxID_CREATENODEDIALOGSAVECONFIG,
2096               label='Save Configuration', name='SaveConfig',
2097               parent=self.MainPanel, pos=wx.Point(256, 216), size=wx.Size(152,
2098               24), style=0)
2099         self.SaveConfig.SetValue(False)
2100
2101         self.StoreEDS = wx.CheckBox(id=wxID_CREATENODEDIALOGSTOREEDS,
2102               label='Store EDS', name='StoreEDS', parent=self.MainPanel,
2103               pos=wx.Point(256, 240), size=wx.Size(144, 24), style=0)
2104         self.StoreEDS.SetValue(False)
2105
2106         self._init_sizers()
2107
2108     def __init__(self, parent):
2109         self._init_ctrls(parent)
2110         self.ButtonSizer = self.CreateButtonSizer(wxOK|wxCANCEL)
2111         self.flexGridSizer1.Add(self.ButtonSizer, 1, wxALIGN_CENTER)
2112         self.Type.Append("master")
2113         self.Type.Append("slave")
2114         self.Type.SetStringSelection("slave")
2115         self.ListProfile = {"None" : ""}
2116         self.Profile.Append("None")
2117         self.Directory = os.path.join(os.getcwd(), "config")
2118         listfiles = os.listdir(self.Directory)
2119         listfiles.sort()
2120         for item in listfiles:
2121             name, extend = os.path.splitext(item)
2122             if os.path.isfile(os.path.join(self.Directory, item)) and extend == ".prf" and name != "DS-302":
2123                 self.ListProfile[name] = os.path.join(self.Directory, item)
2124                 self.Profile.Append(name)
2125         self.Profile.Append("Other")
2126         self.Profile.SetStringSelection("None")
2127
2128     def GetValues(self):
2129         name = self.Name.GetValue()
2130         nodeid = 0
2131         if self.NodeID.GetValue() != "":
2132             nodeid = eval(self.NodeID.GetValue())
2133         type = self.Type.GetStringSelection()
2134         return name, nodeid, type
2135
2136     def GetProfile(self):
2137         name = self.Profile.GetStringSelection()
2138         return name, self.ListProfile[name]
2139
2140     def GetNMTManagement(self):
2141         if self.NMT_None.GetValue():
2142             return "None"
2143         elif self.NMT_NodeGuarding.GetValue():
2144             return "NodeGuarding"
2145         elif self.NMT_Heartbeat.GetValue():
2146             return "Heartbeat"
2147         return None
2148     
2149     def GetOptions(self):
2150         options = []
2151         if self.DS302.GetValue():
2152             options.append("DS302")
2153         if self.GenSYNC.GetValue():
2154             options.append("GenSYNC")
2155         if self.Emergency.GetValue():
2156             options.append("Emergency")
2157         if self.SaveConfig.GetValue():
2158             options.append("SaveConfig")
2159         if self.StoreEDS.GetValue():
2160             options.append("StoreEDS")
2161         return options
2162
2163     def OnProfileChoice(self, event):
2164         if self.Profile.GetStringSelection() == "Other":
2165             dialog = wxFileDialog(self, "Choose a file", self.Directory, "",  "OD Profile files (*.prf)|*.prf|All files|*.*", wxOPEN)
2166             dialog.ShowModal()
2167             filepath = dialog.GetPath()
2168             dialog.Destroy()
2169             if os.path.isfile(filepath):
2170                 name = os.path.splitext(os.path.basename(filepath))[0]
2171                 self.ListProfile[name] = filepath
2172                 length = self.Profile.GetCount()
2173                 self.Profile.Insert(name, length - 2)
2174                 self.Profile.SetStringSelection(name)
2175             else:
2176                 self.Profile.SetStringSelection("None")
2177         event.Skip()
2178
2179
2180
2181 #-------------------------------------------------------------------------------
2182 #                                Html Frame
2183 #-------------------------------------------------------------------------------
2184
2185
2186 [wxID_HTMLFRAME, wxID_HTMLFRAMEHTMLCONTENT, 
2187 ] = [wx.NewId() for _init_ctrls in range(2)]
2188
2189 class HtmlFrame(wx.Frame):
2190     def _init_ctrls(self, prnt):
2191         # generated method, don't edit
2192         wx.Frame.__init__(self, id=wxID_HTMLFRAME, name='HtmlFrame',
2193               parent=prnt, pos=wx.Point(320, 231), size=wx.Size(853, 616),
2194               style=wx.DEFAULT_FRAME_STYLE, title='')
2195         self.Bind(wx.EVT_CLOSE, self.OnCloseFrame, id=wxID_HTMLFRAME)
2196         
2197         self.HtmlContent = wxUrlClickHtmlWindow(id=wxID_HTMLFRAMEHTMLCONTENT,
2198               name='HtmlContent', parent=self, pos=wx.Point(0, 0),
2199               size=wx.Size(-1, -1), style=wxHW_SCROLLBAR_AUTO|wxHW_NO_SELECTION)
2200         EVT_HTML_URL_CLICK(self.HtmlContent, self.OnLinkClick)
2201
2202     def __init__(self, parent, opened):
2203         self._init_ctrls(parent)
2204         self.HtmlFrameOpened = opened
2205     
2206     def SetHtmlCode(self, htmlcode):
2207         self.HtmlContent.SetPage(htmlcode)
2208         
2209     def SetHtmlPage(self, htmlpage):
2210         self.HtmlContent.LoadPage(htmlpage)
2211         
2212     def OnCloseFrame(self, event):
2213         self.HtmlFrameOpened.remove(self.GetTitle())
2214         event.Skip()
2215     
2216     def OnLinkClick(self, event):
2217         url = event.linkinfo[0]
2218         try:
2219             import webbrowser
2220         except ImportError:
2221             wxMessageBox('Please point your browser at: %s' % url)
2222         else:
2223             webbrowser.open(url)
2224     
2225
2226 #-------------------------------------------------------------------------------
2227 #                               Exception Handler
2228 #-------------------------------------------------------------------------------
2229
2230 Max_Traceback_List_Size = 20
2231
2232 def Display_Exception_Dialog(e_type,e_value,e_tb):
2233     trcbck_lst = []
2234     for i,line in enumerate(traceback.extract_tb(e_tb)):
2235         trcbck = " " + str(i+1) + ". "
2236         if line[0].find(os.getcwd()) == -1:
2237             trcbck += "file : " + str(line[0]) + ",   "
2238         else:
2239             trcbck += "file : " + str(line[0][len(os.getcwd()):]) + ",   "
2240         trcbck += "line : " + str(line[1]) + ",   " + "function : " + str(line[2])
2241         trcbck_lst.append(trcbck)
2242         
2243     # Allow clicking....
2244     cap = wx.Window_GetCapture()
2245     if cap:
2246         cap.ReleaseMouse()
2247
2248     dlg = wx.SingleChoiceDialog(None, 
2249         """
2250 An error happens.
2251
2252 Click on OK for saving an error report.
2253
2254 Please contact LOLITech at:
2255 +33 (0)3 29 52 95 67
2256 bugs_objdictedit@lolitech.fr
2257
2258
2259 Error:
2260 """ +
2261         str(e_type) + " : " + str(e_value), 
2262         "Error",
2263         trcbck_lst)
2264     try:
2265         res = (dlg.ShowModal() == wx.ID_OK)
2266     finally:
2267         dlg.Destroy()
2268
2269     return res
2270
2271 def Display_Error_Dialog(e_value):
2272     message = wxMessageDialog(None, str(e_value), "Error", wxOK|wxICON_ERROR)
2273     message.ShowModal()
2274     message.Destroy()
2275
2276 def get_last_traceback(tb):
2277     while tb.tb_next:
2278         tb = tb.tb_next
2279     return tb
2280
2281
2282 def format_namespace(d, indent='    '):
2283     return '\n'.join(['%s%s: %s' % (indent, k, repr(v)[:10000]) for k, v in d.iteritems()])
2284
2285
2286 ignored_exceptions = [] # a problem with a line in a module is only reported once per session
2287
2288 def wxAddExceptHook(path, app_version='[No version]'):#, ignored_exceptions=[]):
2289     
2290     def handle_exception(e_type, e_value, e_traceback):
2291         traceback.print_exception(e_type, e_value, e_traceback) # this is very helpful when there's an exception in the rest of this func
2292         last_tb = get_last_traceback(e_traceback)
2293         ex = (last_tb.tb_frame.f_code.co_filename, last_tb.tb_frame.f_lineno)
2294         if str(e_value).startswith("!!!"):
2295             Display_Error_Dialog(e_value)
2296         elif ex not in ignored_exceptions:
2297             ignored_exceptions.append(ex)
2298             result = Display_Exception_Dialog(e_type,e_value,e_traceback)
2299             if result:
2300                 info = {
2301                     'app-title' : wx.GetApp().GetAppName(), # app_title
2302                     'app-version' : app_version,
2303                     'wx-version' : wx.VERSION_STRING,
2304                     'wx-platform' : wx.Platform,
2305                     'python-version' : platform.python_version(), #sys.version.split()[0],
2306                     'platform' : platform.platform(),
2307                     'e-type' : e_type,
2308                     'e-value' : e_value,
2309                     'date' : time.ctime(),
2310                     'cwd' : os.getcwd(),
2311                     }
2312                 if e_traceback:
2313                     info['traceback'] = ''.join(traceback.format_tb(e_traceback)) + '%s: %s' % (e_type, e_value)
2314                     last_tb = get_last_traceback(e_traceback)
2315                     exception_locals = last_tb.tb_frame.f_locals # the locals at the level of the stack trace where the exception actually occurred
2316                     info['locals'] = format_namespace(exception_locals)
2317                     if 'self' in exception_locals:
2318                         info['self'] = format_namespace(exception_locals['self'].__dict__)
2319                 
2320                 output = open(path+os.sep+"bug_report_"+info['date'].replace(':','-').replace(' ','_')+".txt",'w')
2321                 lst = info.keys()
2322                 lst.sort()
2323                 for a in lst:
2324                     output.write(a+":\n"+str(info[a])+"\n\n")
2325
2326     #sys.excepthook = lambda *args: wx.CallAfter(handle_exception, *args)
2327     sys.excepthook = handle_exception
2328
2329 if __name__ == '__main__':
2330     app = wxPySimpleApp()
2331     wxInitAllImageHandlers()
2332     
2333     # Install a exception handle for bug reports
2334     wxAddExceptHook(os.getcwd(),__version__)
2335     
2336     frame = objdictedit(None)
2337
2338     frame.Show()
2339     app.MainLoop()