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