]> rtime.felk.cvut.cz Git - CanFestival-3.git/blob - objdictgen/objdictedit.py
Bug on CanOpen help popup corrected
[CanFestival-3.git] / objdictgen / objdictedit.py
1 #Boa:Frame:objdictedit
2 #!/usr/bin/env python
3 # -*- coding: utf-8 -*-
4
5 #This file is part of CanFestival, a library implementing CanOpen Stack. 
6 #
7 #Copyright (C): Edouard TISSERANT, Francis DUPIN and Laurent BESSARD
8 #
9 #See COPYING file for copyrights details.
10 #
11 #This library is free software; you can redistribute it and/or
12 #modify it under the terms of the GNU Lesser General Public
13 #License as published by the Free Software Foundation; either
14 #version 2.1 of the License, or (at your option) any later version.
15 #
16 #This library is distributed in the hope that it will be useful,
17 #but WITHOUT ANY WARRANTY; without even the implied warranty of
18 #MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
19 #Lesser General Public License for more details.
20 #
21 #You should have received a copy of the GNU Lesser General Public
22 #License along with this library; if not, write to the Free Software
23 #Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
24
25 from wxPython.wx import *
26 from wxPython.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.12 $"
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         event.Skip()
1078
1079     def OnAboutMenu(self, event):
1080         self.OpenHtmlFrame("About CAN Festival", os.path.join(WorkingDirectory, "../doc/about.html"), wx.Size(500, 450))
1081         event.Skip()
1082
1083     def OpenHtmlFrame(self, title, file, size):
1084         if title not in self.HtmlFrameOpened:
1085             self.HtmlFrameOpened.append(title)
1086             window = HtmlFrame(self, self.HtmlFrameOpened)
1087             window.SetTitle(title)
1088             window.SetHtmlPage(file)
1089             window.SetClientSize(size)
1090             window.Show()
1091
1092     def OnQuitMenu(self, event):
1093         self.Close()
1094         event.Skip()
1095     
1096     def OnCloseFrame(self, event):
1097         if self.Manager.OneFileHasChanged():
1098             dialog = wxMessageDialog(self, "There are changes, do you want to save?",  "Close Application", wxYES_NO|wxCANCEL|wxICON_QUESTION)
1099             answer = dialog.ShowModal()
1100             dialog.Destroy()
1101             if answer == wxID_YES:
1102                 self.Manager.ChangeCurrentNode(0)
1103                 for i in xrange(self.FileOpened.GetPageCount()):
1104                     if self.Manager.CurrentIsSaved():
1105                         self.Manager.CloseCurrent()
1106                     else:
1107                         self.Save()
1108                         self.Manager.CloseCurrent(True)
1109                 event.Skip()
1110             elif answer == wxID_NO:
1111                 for i in xrange(self.FileOpened.GetPageCount()):
1112                     self.Manager.CloseCurrent(True)
1113                 wxCallAfter(self.Close)
1114                 event.Skip()
1115         else:
1116             event.Skip()
1117
1118 #-------------------------------------------------------------------------------
1119 #                             Refresh Functions
1120 #-------------------------------------------------------------------------------
1121
1122     def RefreshTitle(self):
1123         if self.FileOpened.GetPageCount() > 0:
1124             self.SetTitle("Objdictedit - %s"%self.Manager.GetCurrentFilename())
1125         else:
1126             self.SetTitle("Objdictedit")
1127
1128     def OnRefreshMenu(self, event):
1129         self.RefreshCurrentIndexList()
1130         event.Skip()
1131
1132     def RefreshCurrentIndexList(self):
1133         selected = self.FileOpened.GetSelection()
1134         window = self.FileOpened.GetPage(selected)
1135         window.RefreshIndexList()
1136
1137     def RefreshStatusBar(self):
1138         window = self.FileOpened.GetPage(self.FileOpened.GetSelection())
1139         selection = window.GetSelection()
1140         if selection:
1141             index, subIndex = selection
1142             if self.Manager.IsCurrentEntry(index):
1143                 self.HelpBar.SetStatusText("Index: 0x%04X"%index, 0)
1144                 self.HelpBar.SetStatusText("Subindex: 0x%02X"%subIndex, 1)
1145                 entryinfos = self.Manager.GetEntryInfos(index)
1146                 name = entryinfos["name"]
1147                 category = "Optional"
1148                 if entryinfos["need"]:
1149                     category = "Mandatory"
1150                 struct = "VAR"
1151                 number = ""
1152                 if entryinfos["struct"] & OD_IdenticalIndexes:
1153                     number = " possibly defined %d times"%entryinfos["nbmax"]
1154                 if entryinfos["struct"] & OD_IdenticalSubindexes:
1155                     struct = "REC"
1156                 elif entryinfos["struct"] & OD_MultipleSubindexes:
1157                     struct = "ARRAY"
1158                 text = "%s: %s entry of struct %s%s."%(name,category,struct,number)
1159                 self.HelpBar.SetStatusText(text, 2)
1160             else:
1161                 for i in xrange(3):
1162                     self.HelpBar.SetStatusText("", i)
1163         else:
1164             for i in xrange(3):
1165                 self.HelpBar.SetStatusText("", i)
1166
1167     def RefreshMainMenu(self):
1168         if self.FileOpened.GetPageCount() > 0:
1169             self.menuBar1.EnableTop(1, True)
1170             self.menuBar1.EnableTop(2, True)
1171             self.FileMenu.Enable(wxID_OBJDICTEDITFILEMENUITEMS1, True)
1172             self.FileMenu.Enable(wxID_OBJDICTEDITFILEMENUITEMS2, True)
1173             self.FileMenu.Enable(wxID_OBJDICTEDITFILEMENUITEMS6, True)
1174             self.FileMenu.Enable(wxID_OBJDICTEDITFILEMENUITEMS8, True)
1175         else:
1176             self.menuBar1.EnableTop(1, False)      
1177             self.menuBar1.EnableTop(2, False)
1178             self.FileMenu.Enable(wxID_OBJDICTEDITFILEMENUITEMS1, False)
1179             self.FileMenu.Enable(wxID_OBJDICTEDITFILEMENUITEMS2, False)
1180             self.FileMenu.Enable(wxID_OBJDICTEDITFILEMENUITEMS6, False)
1181             self.FileMenu.Enable(wxID_OBJDICTEDITFILEMENUITEMS8, False)
1182
1183     def RefreshEditMenu(self):
1184         if self.FileOpened.GetPageCount() > 0:
1185             undo, redo = self.Manager.GetCurrentBufferState()
1186             self.EditMenu.FindItemByPosition(2).Enable(undo)
1187             self.EditMenu.FindItemByPosition(3).Enable(redo)
1188         else:
1189             self.EditMenu.FindItemByPosition(2).Enable(False)
1190             self.EditMenu.FindItemByPosition(3).Enable(False)
1191
1192     def RefreshProfileMenu(self):
1193         profile = self.Manager.GetCurrentProfileName()
1194         edititem = self.EditMenu.FindItemByPosition(8)
1195         length = self.AddMenu.GetMenuItemCount()
1196         for i in xrange(length-6):
1197             additem = self.AddMenu.FindItemByPosition(6)
1198             self.AddMenu.Delete(additem.GetId())
1199         if profile not in ("None", "DS-301"):
1200             edititem.SetText("%s Profile"%profile)
1201             edititem.Enable(True)
1202             self.AddMenu.AppendSeparator()
1203             for text, indexes in self.Manager.GetCurrentSpecificMenu():
1204                 new_id = wx.NewId()
1205                 self.AddMenu.Append(help='', id=new_id, kind=wx.ITEM_NORMAL, text=text)
1206                 self.Bind(wx.EVT_MENU, self.GetProfileCallBack(text), id=new_id)
1207         else:
1208             edititem.SetText("Other Profile")
1209             edititem.Enable(False)
1210         
1211
1212 #-------------------------------------------------------------------------------
1213 #                            Buffer Functions
1214 #-------------------------------------------------------------------------------
1215
1216     def RefreshBufferState(self):
1217         fileopened = self.Manager.GetAllFilenames()
1218         for idx, filename in enumerate(fileopened):
1219             self.FileOpened.SetPageText(idx, filename)
1220         self.RefreshEditMenu()
1221         self.RefreshTitle()
1222
1223     def OnUndoMenu(self, event):
1224         self.Manager.LoadCurrentPrevious()
1225         self.RefreshCurrentIndexList()
1226         self.RefreshBufferState()
1227         event.Skip()
1228
1229     def OnRedoMenu(self, event):
1230         self.Manager.LoadCurrentNext()
1231         self.RefreshCurrentIndexList()
1232         self.RefreshBufferState()
1233         event.Skip()
1234
1235
1236 #-------------------------------------------------------------------------------
1237 #                         Load and Save Funtions
1238 #-------------------------------------------------------------------------------
1239
1240     def OnNewMenu(self, event):
1241         self.FilePath = ""
1242         dialog = CreateNodeDialog(self)
1243         if dialog.ShowModal() == wxID_OK:
1244             name, id, type = dialog.GetValues()
1245             profile, filepath = dialog.GetProfile()
1246             NMT = dialog.GetNMTManagement()
1247             options = dialog.GetOptions()
1248             result = self.Manager.CreateNewNode(name, id, type, profile, filepath, NMT, options)
1249             if not IsOfType(result, StringType):
1250                 new_editingpanel = EditingPanel(self, self.Manager)
1251                 self.FileOpened.AddPage(new_editingpanel, "")
1252                 self.FileOpened.SetSelection(self.Manager.GetCurrentNodeIndex())
1253                 self.EditMenu.Enable(wxID_OBJDICTEDITEDITMENUITEMS8, False)
1254                 if "DS302" in options:
1255                     self.EditMenu.Enable(wxID_OBJDICTEDITEDITMENUITEMS8, True)
1256                 self.RefreshBufferState()
1257                 self.RefreshProfileMenu()
1258                 self.RefreshMainMenu()
1259             else:
1260                 message = wxMessageDialog(self, result, "ERROR", wxOK|wxICON_ERROR)
1261                 message.ShowModal()
1262                 message.Destroy()
1263         event.Skip()
1264
1265     def OnOpenMenu(self, event):
1266         filepath = self.Manager.GetCurrentFilePath()
1267         if filepath != "":
1268             directory = os.path.dirname(filepath)
1269         else:
1270             directory = os.getcwd()
1271         dialog = wxFileDialog(self, "Choose a file", directory, "",  "OD files (*.od)|*.od|All files|*.*", wxOPEN|wxCHANGE_DIR)
1272         if dialog.ShowModal() == wxID_OK:
1273             filepath = dialog.GetPath()
1274             if os.path.isfile(filepath):
1275                 result = self.Manager.OpenFileInCurrent(filepath)
1276                 if type(result) != StringType:
1277                     new_editingpanel = EditingPanel(self, self.Manager)
1278                     self.FileOpened.AddPage(new_editingpanel, "")
1279                     self.FileOpened.SetSelection(self.Manager.GetCurrentNodeIndex())
1280                     if self.Manager.CurrentDS302Defined(): 
1281                         self.EditMenu.Enable(wxID_OBJDICTEDITEDITMENUITEMS8, True)
1282                     else:
1283                         self.EditMenu.Enable(wxID_OBJDICTEDITEDITMENUITEMS8, False)
1284                     self.RefreshEditMenu()
1285                     self.RefreshBufferState()
1286                     self.RefreshProfileMenu()
1287                     self.RefreshMainMenu()
1288                 else:
1289                     message = wxMessageDialog(self, e.args[0], "Error", wxOK|wxICON_ERROR)
1290                     message.ShowModal()
1291                     message.Destroy()
1292         dialog.Destroy()
1293         event.Skip()
1294
1295     def OnSaveMenu(self, event):
1296         self.Save()
1297         event.Skip()
1298     
1299     def OnSaveAsMenu(self, event):
1300         self.SaveAs()
1301         event.Skip()
1302         
1303     def Save(self):
1304         result = self.Manager.SaveCurrentInFile()
1305         if not result:
1306             self.SaveAs()
1307         elif type(result) != StringType:
1308             self.RefreshBufferState()
1309         else:
1310             message = wxMessageDialog(self, result, "Error", wxOK|wxICON_ERROR)
1311             message.ShowModal()
1312             message.Destroy()
1313
1314     def SaveAs(self):
1315         filepath = self.Manager.GetCurrentFilePath()
1316         if filepath != "":
1317             directory, filename = os.path.split(filepath)
1318         else:
1319             directory, filename = os.getcwd(), "%s.od"%self.Manager.GetCurrentNodeInfos()[0]
1320         dialog = wxFileDialog(self, "Choose a file", directory, filename,  "OD files (*.od)|*.od|All files|*.*", wxSAVE|wxOVERWRITE_PROMPT|wxCHANGE_DIR)
1321         if dialog.ShowModal() == wxID_OK:
1322             filepath = dialog.GetPath()
1323             if os.path.isdir(os.path.dirname(filepath)):
1324                 result = self.Manager.SaveCurrentInFile(filepath)
1325                 if type(result) != StringType:
1326                     self.RefreshBufferState()
1327                 else:
1328                     message = wxMessageDialog(self, result, "Error", wxOK|wxICON_ERROR)
1329                     message.ShowModal()
1330                     message.Destroy()
1331             else:
1332                 message = wxMessageDialog(self, "%s is not a valid folder!"%os.path.dirname(filepath), "Error", wxOK|wxICON_ERROR)
1333                 message.ShowModal()
1334                 message.Destroy()
1335         dialog.Destroy()
1336
1337     def OnCloseMenu(self, event):
1338         answer = wxID_YES
1339         result = self.Manager.CloseCurrent()
1340         if not result:
1341             dialog = wxMessageDialog(self, "There are changes, do you want to save?",  "Close File", wxYES_NO|wxCANCEL|wxICON_QUESTION)
1342             answer = dialog.ShowModal()
1343             dialog.Destroy()
1344             if answer == wxID_YES:
1345                 self.OnSaveMenu(event)
1346                 if self.Manager.CurrentIsSaved():
1347                     self.Manager.CloseCurrent()
1348             elif answer == wxID_NO:
1349                 self.Manager.CloseCurrent(True)
1350         if self.FileOpened.GetPageCount() > self.Manager.GetBufferNumber():
1351             current = self.FileOpened.GetSelection()
1352             self.FileOpened.DeletePage(current)
1353             if self.FileOpened.GetPageCount() > 0:
1354                 self.FileOpened.SetSelection(min(current, self.FileOpened.GetPageCount() - 1))
1355             self.RefreshBufferState()
1356             self.RefreshMainMenu()
1357         event.Skip()
1358         
1359
1360 #-------------------------------------------------------------------------------
1361 #                         Import and Export Functions
1362 #-------------------------------------------------------------------------------
1363
1364     def OnImportMenu(self, event):
1365         dialog = wxFileDialog(self, "Choose a file", os.getcwd(), "",  "XML OD files (*.xml)|*.xml|All files|*.*", wxOPEN|wxCHANGE_DIR)
1366         if dialog.ShowModal() == wxID_OK:
1367             filepath = dialog.GetPath()
1368             if os.path.isfile(filepath):
1369                 result = self.Manager.ImportCurrentFromFile(filepath)
1370                 if result:
1371                     if self.FileOpened.GetPageCount() == 0:
1372                         new_editingpanel = EditingPanel(self, self.Manager)
1373                         self.FileOpened.AddPage(new_editingpanel, "")
1374                         self.FileOpened.SetSelection(self.Manager.GetCurrentNodeIndex())
1375                     self.RefreshBufferState()
1376                     self.RefreshCurrentIndexList()
1377                     self.RefreshProfileMenu()
1378                     self.RefreshMainMenu()
1379                     message = wxMessageDialog(self, "Import successful", "Information", wxOK|wxICON_INFORMATION)
1380                     message.ShowModal()
1381                     message.Destroy()
1382         dialog.Destroy()
1383         event.Skip()
1384
1385     def OnExportMenu(self, event):
1386         dialog = wxFileDialog(self, "Choose a file", os.getcwd(), self.Manager.GetCurrentNodeInfos()[0],  "CANFestival OD files (*.c)|*.c|All files|*.*", wxSAVE|wxOVERWRITE_PROMPT|wxCHANGE_DIR)
1387         if dialog.ShowModal() == wxID_OK:
1388             filepath = dialog.GetPath()
1389             if os.path.isdir(os.path.dirname(filepath)):
1390                 path, extend = os.path.splitext(filepath)
1391                 if extend in ("", "."):
1392                     filepath = path + ".c"
1393                 result = self.Manager.ExportCurrentToFile(filepath)
1394                 if result:
1395                     message = wxMessageDialog(self, "Export successful", "Information", wxOK|wxICON_INFORMATION)
1396                     message.ShowModal()
1397                     message.Destroy()
1398             else:
1399                 message = wxMessageDialog(self, "%s is not a valid folder!"%os.path.dirname(filepath), "Error", wxOK|wxICON_ERROR)
1400                 message.ShowModal()
1401                 message.Destroy()
1402         dialog.Destroy()
1403         event.Skip()
1404
1405 #-------------------------------------------------------------------------------
1406 #                          Editing Profiles functions
1407 #-------------------------------------------------------------------------------
1408
1409     def OnCommunicationMenu(self, event):
1410         dictionary,current = self.Manager.GetCurrentCommunicationLists()
1411         self.EditProfile("Edit DS-301 Profile", dictionary, current)
1412         event.Skip()
1413     
1414     def OnOtherCommunicationMenu(self, event):
1415         dictionary,current = self.Manager.GetCurrentDS302Lists()
1416         self.EditProfile("Edit DS-301 Profile", dictionary, current)
1417         event.Skip()
1418     
1419     def OnEditProfileMenu(self, event):
1420         title = "Edit %s Profile"%self.Manager.GetCurrentProfileName()
1421         dictionary,current = self.Manager.GetCurrentProfileLists()
1422         self.EditProfile(title, dictionary, current)
1423         event.Skip()
1424     
1425     def EditProfile(self, title, dictionary, current):
1426         dialog = CommunicationDialog(self)
1427         dialog.SetTitle(title)
1428         dialog.SetIndexDictionary(dictionary)
1429         dialog.SetCurrentList(current)
1430         dialog.RefreshLists()
1431         if dialog.ShowModal() == wxID_OK:
1432             new_profile = dialog.GetCurrentList()
1433             addinglist = []
1434             removinglist = []
1435             for index in new_profile:
1436                 if index not in current:
1437                     addinglist.append(index)
1438             for index in current:
1439                 if index not in new_profile:
1440                     removinglist.append(index)
1441             self.Manager.ManageEntriesOfCurrent(addinglist, removinglist)
1442             self.Manager.GenerateMapList()
1443             self.Manager.BufferCurrentNode()
1444             self.RefreshBufferState()
1445             self.RefreshCurrentIndexList()
1446         dialog.Destroy()
1447
1448     def GetProfileCallBack(self, text):
1449         def ProfileCallBack(event):
1450             self.Manager.AddSpecificEntryToCurrent(text)
1451             self.RefreshBufferState()
1452             self.RefreshCurrentIndexList()
1453             event.Skip()
1454         return ProfileCallBack
1455
1456 #-------------------------------------------------------------------------------
1457 #                         Edit Node informations function
1458 #-------------------------------------------------------------------------------
1459
1460     def OnNodeInfosMenu(self, event):
1461         dialog = NodeInfosDialog(self)
1462         name,id,type = self.Manager.GetCurrentNodeInfos()
1463         profile = self.Manager.GetCurrentProfileName()
1464         dialog.SetProfiles([profile])
1465         dialog.SetValues(name, id, type, profile)
1466         if dialog.ShowModal() == wxID_OK:
1467             name,id,type,profile = dialog.GetValues()
1468             self.Manager.SetCurrentNodeInfos(name, id, type)
1469             self.RefreshBufferState()
1470             self.RefreshProfileMenu()
1471         event.Skip()
1472
1473
1474 #-------------------------------------------------------------------------------
1475 #                           Add User Types and Variables
1476 #-------------------------------------------------------------------------------
1477         
1478     def AddMapVariable(self):
1479         index = self.Manager.GetCurrentNextMapIndex()
1480         if index:
1481             dialog = MapVariableDialog(self)
1482             dialog.SetIndex(index)
1483             if dialog.ShowModal() == wxID_OK:
1484                 index, name, struct, number = dialog.GetValues()
1485                 result = self.Manager.AddMapVariableToCurrent(index, name, struct, number)
1486                 if type(result) != StringType:
1487                     self.RefreshBufferState()
1488                     self.RefreshCurrentIndexList()
1489                 else:
1490                     message = wxMessageDialog(self, result, "Error", wxOK|wxICON_ERROR)
1491                     message.ShowModal()
1492                     message.Destroy()
1493             dialog.Destroy()
1494         else:
1495             message = wxMessageDialog(self, result, "No map variable index left!", wxOK|wxICON_ERROR)
1496             message.ShowModal()
1497             message.Destroy()
1498         
1499     def AddUserType(self):
1500         dialog = UserTypeDialog(self)
1501         dialog.SetTypeList(self.Manager.GetCustomisableTypes())
1502         if dialog.ShowModal() == wxID_OK:
1503             type, min, max, length = dialog.GetValues()
1504             result = self.Manager.AddUserTypeToCurrent(type, min, max, length)
1505             if not IsOfType(result, StringType):
1506                 self.RefreshBufferState()
1507                 self.RefreshCurrentIndexList()
1508             else:
1509                 message = wxMessageDialog(self, result, "Error", wxOK|wxICON_ERROR)
1510                 message.ShowModal()
1511                 message.Destroy()
1512         dialog.Destroy()
1513
1514
1515
1516 #-------------------------------------------------------------------------------
1517 #                          Editing Communication Dialog
1518 #-------------------------------------------------------------------------------
1519
1520
1521 [wxID_COMMUNICATIONDIALOG, wxID_COMMUNICATIONDIALOGMAINPANEL,
1522  wxID_COMMUNICATIONDIALOGPOSSIBLEINDEXES, wxID_COMMUNICATIONDIALOGCURRENTINDEXES,
1523  wxID_COMMUNICATIONDIALOGSELECT, wxID_COMMUNICATIONDIALOGUNSELECT, 
1524  wxID_COMMUNICATIONDIALOGSTATICTEXT1, wxID_COMMUNICATIONDIALOGSTATICTEXT2
1525 ] = [wx.NewId() for _init_ctrls in range(8)]
1526
1527 class CommunicationDialog(wx.Dialog):
1528     def _init_coll_flexGridSizer1_Items(self, parent):
1529         # generated method, don't edit
1530
1531         parent.AddWindow(self.MainPanel, 0, border=0, flag=0)
1532
1533     def _init_sizers(self):
1534         # generated method, don't edit
1535         self.flexGridSizer1 = wx.FlexGridSizer(cols=1, hgap=0, rows=2, vgap=0)
1536
1537         self._init_coll_flexGridSizer1_Items(self.flexGridSizer1)
1538
1539         self.SetSizer(self.flexGridSizer1)
1540
1541     def _init_ctrls(self, prnt):
1542         # generated method, don't edit
1543         wx.Dialog.__init__(self, id=wxID_COMMUNICATIONDIALOG,
1544               name='CommunicationDialog', parent=prnt, pos=wx.Point(234, 216),
1545               size=wx.Size(726, 437), style=wx.DEFAULT_DIALOG_STYLE,
1546               title='Edit Communication Profile')
1547         self.SetClientSize(wx.Size(726, 437))
1548
1549         self.MainPanel = wx.Panel(id=wxID_COMMUNICATIONDIALOGMAINPANEL,
1550               name='MainPanel', parent=self, pos=wx.Point(0, 0),
1551               size=wx.Size(688, 382), style=wx.TAB_TRAVERSAL)
1552         self.MainPanel.SetAutoLayout(True)
1553
1554         self.PossibleIndexes = wx.ListBox(choices=[],
1555               id=wxID_COMMUNICATIONDIALOGPOSSIBLEINDEXES,
1556               name='PossibleIndexes', parent=self.MainPanel, pos=wx.Point(40,
1557               48), size=wx.Size(280, 320), style=wxLB_EXTENDED)
1558         self.PossibleIndexes.Bind(wx.EVT_LEFT_DCLICK, self.OnPossibleIndexesDClick,
1559               id=wxID_COMMUNICATIONDIALOGPOSSIBLEINDEXES)
1560
1561         self.CurrentIndexes = wx.ListBox(choices=[],
1562               id=wxID_COMMUNICATIONDIALOGCURRENTINDEXES, name='CurrentIndexes',
1563               parent=self.MainPanel, pos=wx.Point(400, 48), size=wx.Size(280,
1564               320), style=wxLB_EXTENDED)
1565         self.CurrentIndexes.Bind(wx.EVT_LEFT_DCLICK, self.OnCurrentIndexesDClick,
1566               id=wxID_COMMUNICATIONDIALOGCURRENTINDEXES)
1567
1568         self.Select = wx.Button(id=wxID_COMMUNICATIONDIALOGSELECT, label='>>',
1569               name='Select', parent=self.MainPanel, pos=wx.Point(345, 136),
1570               size=wx.Size(32, 32), style=0)
1571         self.Select.Bind(wx.EVT_BUTTON, self.OnSelectButton,
1572               id=wxID_COMMUNICATIONDIALOGSELECT)
1573
1574         self.Unselect = wx.Button(id=wxID_COMMUNICATIONDIALOGUNSELECT,
1575               label='<<', name='Unselect', parent=self.MainPanel,
1576               pos=wx.Point(345, 216), size=wx.Size(32, 30), style=0)
1577         self.Unselect.Bind(wx.EVT_BUTTON, self.OnUnselectButton,
1578               id=wxID_COMMUNICATIONDIALOGUNSELECT)
1579
1580         self.staticText1 = wx.StaticText(id=wxID_COMMUNICATIONDIALOGSTATICTEXT1,
1581               label='Possible Profile Indexes:', name='staticText1',
1582               parent=self.MainPanel, pos=wx.Point(40, 24), size=wx.Size(156,
1583               17), style=0)
1584
1585         self.staticText2 = wx.StaticText(id=wxID_COMMUNICATIONDIALOGSTATICTEXT2,
1586               label='Current Profile Indexes:', name='staticText2',
1587               parent=self.MainPanel, pos=wx.Point(400, 24), size=wx.Size(152,
1588               17), style=0)
1589
1590         self._init_sizers()
1591
1592     def __init__(self, parent):
1593         self._init_ctrls(parent)
1594         self.ButtonSizer = self.CreateButtonSizer(wxOK|wxCANCEL)
1595         self.flexGridSizer1.Add(self.ButtonSizer, 1, wxALIGN_CENTER)
1596         self.AllList = []
1597         self.CurrentList = []
1598         self.IndexDictionary = {}
1599
1600     def SetIndexDictionary(self, dictionary):
1601         self.IndexDictionary = dictionary
1602         
1603     def SetCurrentList(self, list):
1604         self.CurrentList = []
1605         self.CurrentList.extend(list)
1606         self.CurrentList.sort()
1607         
1608     def GetCurrentList(self):
1609         return self.CurrentList
1610         
1611     def RefreshLists(self):
1612         self.PossibleIndexes.Clear()
1613         self.CurrentIndexes.Clear()
1614         self.AllList = []
1615         for index in self.IndexDictionary.iterkeys():
1616             if index not in self.CurrentList:
1617                 self.AllList.append(index)
1618         self.AllList.sort()
1619         for index in self.AllList:
1620             self.PossibleIndexes.Append("0x%04X   %s"%(index, self.IndexDictionary[index][0]))
1621         for index in self.CurrentList:
1622             if index in self.IndexDictionary:
1623                 self.CurrentIndexes.Append("0x%04X   %s"%(index, self.IndexDictionary[index][0]))
1624
1625     def OnPossibleIndexesDClick(self, event):
1626         self.SelectPossible()
1627         event.Skip()
1628
1629     def OnCurrentIndexesDClick(self, event):
1630         self.UnselectCurrent()
1631         event.Skip()
1632
1633     def OnSelectButton(self, event):
1634         self.SelectPossible()
1635         event.Skip()
1636
1637     def OnUnselectButton(self, event):
1638         self.UnselectCurrent()
1639         event.Skip()
1640
1641     def SelectPossible(self):
1642         selected = self.PossibleIndexes.GetSelections()
1643         for i in selected:
1644             self.CurrentList.append(self.AllList[i])
1645         self.CurrentList.sort()
1646         self.RefreshLists()
1647
1648     def UnselectCurrent(self):
1649         selected = self.CurrentIndexes.GetSelections()
1650         for i in selected:
1651             if not self.IndexDictionary[self.CurrentList[i]][1]:
1652                 self.CurrentList.pop(i)
1653         self.CurrentList.sort()
1654         self.RefreshLists()
1655
1656
1657
1658 #-------------------------------------------------------------------------------
1659 #                          Create Map Variable Dialog
1660 #-------------------------------------------------------------------------------
1661
1662
1663 [wxID_MAPVARIABLEDIALOG, wxID_MAPVARIABLEDIALOGINDEX, 
1664  wxID_MAPVARIABLEDIALOGINDEXNAME, wxID_MAPVARIABLEDIALOGMAINPANEL, 
1665  wxID_MAPVARIABLEDIALOGNUMBER, wxID_MAPVARIABLEDIALOGRADIOBUTTON1, 
1666  wxID_MAPVARIABLEDIALOGRADIOBUTTON2, wxID_MAPVARIABLEDIALOGRADIOBUTTON3, 
1667  wxID_MAPVARIABLEDIALOGSTATICTEXT1, wxID_MAPVARIABLEDIALOGSTATICTEXT2, 
1668  wxID_MAPVARIABLEDIALOGSTATICTEXT3, wxID_MAPVARIABLEDIALOGSTATICTEXT4, 
1669 ] = [wx.NewId() for _init_ctrls in range(12)]
1670
1671 class MapVariableDialog(wx.Dialog):
1672     def _init_coll_flexGridSizer1_Items(self, parent):
1673         # generated method, don't edit
1674
1675         parent.AddWindow(self.MainPanel, 0, border=0, flag=0)
1676
1677     def _init_sizers(self):
1678         # generated method, don't edit
1679         self.flexGridSizer1 = wx.FlexGridSizer(cols=1, hgap=0, rows=2, vgap=0)
1680
1681         self._init_coll_flexGridSizer1_Items(self.flexGridSizer1)
1682
1683         self.SetSizer(self.flexGridSizer1)
1684
1685     def _init_ctrls(self, prnt):
1686         # generated method, don't edit
1687         wx.Dialog.__init__(self, id=wxID_MAPVARIABLEDIALOG,
1688               name='CommunicationDialog', parent=prnt, pos=wx.Point(376, 223),
1689               size=wx.Size(444, 186), style=wx.DEFAULT_DIALOG_STYLE,
1690               title='Add Map Variable')
1691         self.SetClientSize(wx.Size(444, 186))
1692
1693         self.MainPanel = wx.Panel(id=wxID_MAPVARIABLEDIALOGMAINPANEL,
1694               name='MainPanel', parent=self, pos=wx.Point(0, 0),
1695               size=wx.Size(431, 142), style=wx.TAB_TRAVERSAL)
1696         self.MainPanel.SetAutoLayout(True)
1697
1698         self.staticText1 = wx.StaticText(id=wxID_MAPVARIABLEDIALOGSTATICTEXT1,
1699               label='Index:', name='staticText1', parent=self.MainPanel,
1700               pos=wx.Point(24, 24), size=wx.Size(156, 17), style=0)
1701
1702         self.Index = wx.TextCtrl(id=wxID_MAPVARIABLEDIALOGINDEX, name='Index',
1703               parent=self.MainPanel, pos=wx.Point(24, 48), size=wx.Size(152,
1704               25), style=0, value='0x2000')
1705
1706         self.staticText3 = wx.StaticText(id=wxID_MAPVARIABLEDIALOGSTATICTEXT3,
1707               label='Name:', name='staticText3', parent=self.MainPanel,
1708               pos=wx.Point(24, 80), size=wx.Size(47, 17), style=0)
1709
1710         self.IndexName = wx.TextCtrl(id=wxID_MAPVARIABLEDIALOGINDEXNAME,
1711               name='IndexName', parent=self.MainPanel, pos=wx.Point(24, 104),
1712               size=wx.Size(152, 24), style=0, value='Undefined')
1713
1714         self.staticText2 = wx.StaticText(id=wxID_MAPVARIABLEDIALOGSTATICTEXT2,
1715               label='Type:', name='staticText2', parent=self.MainPanel,
1716               pos=wx.Point(208, 24), size=wx.Size(38, 17), style=0)
1717
1718         self.radioButton1 = wx.RadioButton(id=wxID_MAPVARIABLEDIALOGRADIOBUTTON1,
1719               label='VAR', name='radioButton1', parent=self.MainPanel,
1720               pos=wx.Point(208, 48), size=wx.Size(72, 24), style=wxRB_GROUP)
1721         self.radioButton1.SetValue(True)
1722         self.radioButton1.Bind(wx.EVT_RADIOBUTTON, self.OnRadioButton1Click,
1723               id=wxID_MAPVARIABLEDIALOGRADIOBUTTON1)
1724
1725         self.radioButton2 = wx.RadioButton(id=wxID_MAPVARIABLEDIALOGRADIOBUTTON2,
1726               label='ARRAY', name='radioButton2', parent=self.MainPanel,
1727               pos=wx.Point(208, 72), size=wx.Size(80, 24), style=wxRB_SINGLE)
1728         self.radioButton2.SetValue(False)
1729         self.radioButton2.Bind(wx.EVT_RADIOBUTTON, self.OnRadioButton2Click,
1730               id=wxID_MAPVARIABLEDIALOGRADIOBUTTON2)
1731
1732         self.radioButton3 = wx.RadioButton(id=wxID_MAPVARIABLEDIALOGRADIOBUTTON3,
1733               label='REC', name='radioButton3', parent=self.MainPanel,
1734               pos=wx.Point(208, 96), size=wx.Size(96, 24), style=wxRB_SINGLE)
1735         self.radioButton3.SetValue(False)
1736         self.radioButton3.Bind(wx.EVT_RADIOBUTTON, self.OnRadioButton3Click,
1737               id=wxID_MAPVARIABLEDIALOGRADIOBUTTON3)
1738
1739         self.staticText4 = wx.StaticText(id=wxID_MAPVARIABLEDIALOGSTATICTEXT4,
1740               label='Number:', name='staticText4', parent=self.MainPanel,
1741               pos=wx.Point(312, 80), size=wx.Size(88, 16), style=0)
1742
1743         self.Number = wx.TextCtrl(id=wxID_MAPVARIABLEDIALOGNUMBER,
1744               name='Number', parent=self.MainPanel, pos=wx.Point(312, 104),
1745               size=wx.Size(112, 24), style=wx.TE_RIGHT, value='0')
1746
1747         self._init_sizers()
1748
1749     def __init__(self, parent):
1750         self._init_ctrls(parent)
1751         self.ButtonSizer = self.CreateButtonSizer(wxOK|wxCANCEL)
1752         self.flexGridSizer1.Add(self.ButtonSizer, 1, wxALIGN_CENTER)
1753         self.staticText4.Enable(False)
1754         self.Number.Enable(False)
1755
1756     def SetIndex(self, index):
1757         self.Index.SetValue("0x%04X"%index)
1758
1759     def GetValues(self):
1760         if self.radioButton1.GetValue():
1761             struct = 1
1762         elif self.radioButton2.GetValue():
1763             struct = 3
1764         elif self.radioButton3.GetValue():
1765             struct = 7
1766         name = self.IndexName.GetValue()
1767         index = eval(self.Index.GetValue())
1768         number = eval(self.Number.GetValue())
1769         return index, name, struct, number
1770
1771     def OnRadioButton1Click(self, event):
1772         self.EnableNumberTyping(False)
1773         event.Skip()
1774
1775     def OnRadioButton2Click(self, event):
1776         self.EnableNumberTyping(True)
1777         event.Skip()
1778
1779     def OnRadioButton3Click(self, event):
1780         self.EnableNumberTyping(True)
1781         event.Skip()
1782
1783     def EnableNumberTyping(self, enable):
1784         self.staticText4.Enable(enable)
1785         self.Number.Enable(enable)
1786
1787
1788 #-------------------------------------------------------------------------------
1789 #                          Create User Type Dialog
1790 #-------------------------------------------------------------------------------
1791
1792
1793 [wxID_USERTYPEDIALOG, wxID_USERTYPEDIALOGLENGTH, wxID_USERTYPEDIALOGMAINPANEL, 
1794  wxID_USERTYPEDIALOGMAX, wxID_USERTYPEDIALOGMIN, 
1795  wxID_USERTYPEDIALOGSTATICBOX1, wxID_USERTYPEDIALOGSTATICTEXT1, 
1796  wxID_USERTYPEDIALOGSTATICTEXT2, wxID_USERTYPEDIALOGSTATICTEXT3, 
1797  wxID_USERTYPEDIALOGSTATICTEXT4, wxID_USERTYPEDIALOGTYPE, 
1798 ] = [wx.NewId() for _init_ctrls in range(11)]
1799
1800 class UserTypeDialog(wx.Dialog):
1801     def _init_coll_flexGridSizer1_Items(self, parent):
1802         # generated method, don't edit
1803
1804         parent.AddWindow(self.MainPanel, 0, border=0, flag=0)
1805
1806     def _init_sizers(self):
1807         # generated method, don't edit
1808         self.flexGridSizer1 = wx.FlexGridSizer(cols=1, hgap=0, rows=2, vgap=0)
1809
1810         self._init_coll_flexGridSizer1_Items(self.flexGridSizer1)
1811
1812         self.SetSizer(self.flexGridSizer1)
1813
1814     def _init_ctrls(self, prnt):
1815         # generated method, don't edit
1816         wx.Dialog.__init__(self, id=wxID_USERTYPEDIALOG, name='UserTypeDialog',
1817               parent=prnt, pos=wx.Point(376, 223), size=wx.Size(444, 228),
1818               style=wx.DEFAULT_DIALOG_STYLE, title='Add User Type')
1819         self.SetClientSize(wx.Size(444, 228))
1820
1821         self.MainPanel = wx.Panel(id=wxID_USERTYPEDIALOGMAINPANEL,
1822               name='MainPanel', parent=self, pos=wx.Point(0, 0),
1823               size=wx.Size(431, 182), style=wx.TAB_TRAVERSAL)
1824         self.MainPanel.SetAutoLayout(True)
1825
1826         self.staticText1 = wx.StaticText(id=wxID_USERTYPEDIALOGSTATICTEXT1,
1827               label='Type:', name='staticText1', parent=self.MainPanel,
1828               pos=wx.Point(24, 24), size=wx.Size(156, 17), style=0)
1829
1830         self.Type = wx.Choice(choices=[], id=wxID_USERTYPEDIALOGTYPE,
1831               name='Type', parent=self.MainPanel, pos=wx.Point(24, 48),
1832               size=wx.Size(160, 24), style=0)
1833         self.Type.Bind(wx.EVT_CHOICE, self.OnTypeChoice,
1834               id=wxID_USERTYPEDIALOGTYPE)
1835
1836         self.staticBox1 = wx.StaticBox(id=wxID_USERTYPEDIALOGSTATICBOX1,
1837               label='Values', name='staticBox1', parent=self.MainPanel,
1838               pos=wx.Point(200, 24), size=wx.Size(224, 144), style=0)
1839
1840         self.staticText2 = wx.StaticText(id=wxID_USERTYPEDIALOGSTATICTEXT2,
1841               label='Minimum:', name='staticText2', parent=self.MainPanel,
1842               pos=wx.Point(216, 48), size=wx.Size(67, 17), style=0)
1843
1844         self.Min = wx.TextCtrl(id=wxID_USERTYPEDIALOGMIN, name='Min',
1845               parent=self.MainPanel, pos=wx.Point(296, 48), size=wx.Size(112,
1846               24), style=wx.TE_RIGHT, value='0')
1847
1848         self.staticText3 = wx.StaticText(id=wxID_USERTYPEDIALOGSTATICTEXT3,
1849               label='Maximum:', name='staticText3', parent=self.MainPanel,
1850               pos=wx.Point(216, 88), size=wx.Size(71, 17), style=0)
1851
1852         self.Max = wx.TextCtrl(id=wxID_USERTYPEDIALOGMAX, name='Max',
1853               parent=self.MainPanel, pos=wx.Point(296, 88), size=wx.Size(112,
1854               25), style=wx.TE_RIGHT, value='0')
1855
1856         self.staticText4 = wx.StaticText(id=wxID_USERTYPEDIALOGSTATICTEXT4,
1857               label='Length:', name='staticText4', parent=self.MainPanel,
1858               pos=wx.Point(216, 128), size=wx.Size(52, 17), style=0)
1859
1860         self.Length = wx.TextCtrl(id=wxID_USERTYPEDIALOGLENGTH, name='Length',
1861               parent=self.MainPanel, pos=wx.Point(296, 128), size=wx.Size(112,
1862               25), style=wx.TE_RIGHT, value='0')
1863
1864         self._init_sizers()
1865
1866     def __init__(self, parent):
1867         self._init_ctrls(parent)
1868         self.ButtonSizer = self.CreateButtonSizer(wxOK|wxCANCEL)
1869         self.flexGridSizer1.Add(self.ButtonSizer, 1, wxALIGN_CENTER)
1870         self.TypeDictionary = {}
1871         
1872     def SetValues(self, min = None, max = None, length = None):
1873         if min != None:
1874             self.Min.SetValue(str(min))
1875         if max != None:
1876             self.Max.SetValue(str(max))
1877         if length != None:
1878             self.Length.SetValue(str(length))
1879
1880     def SetTypeList(self, typedic, type = None):
1881         self.Type.Clear()
1882         list = []
1883         for index, (name, valuetype) in typedic.iteritems():
1884             self.TypeDictionary[name] = (index, valuetype)
1885             list.append((index, name))
1886         list.sort()
1887         for index, name in list:
1888             self.Type.Append(name)
1889         if type != None:
1890             self.Type.SetStringSelection(typedic[type][0])
1891         self.RefreshValues()
1892
1893     def OnTypeChoice(self, event):
1894         self.RefreshValues()
1895         event.Skip()
1896     
1897     def RefreshValues(self):
1898         name = self.Type.GetStringSelection()
1899         if name != "":
1900             valuetype = self.TypeDictionary[name][1]
1901             if valuetype == 0:
1902                 self.staticText2.Enable(True)
1903                 self.staticText3.Enable(True)
1904                 self.staticText4.Enable(False)
1905                 self.Min.Enable(True)
1906                 self.Max.Enable(True)
1907                 self.Length.Enable(False)
1908             elif valuetype == 1:
1909                 self.staticText2.Enable(False)
1910                 self.staticText3.Enable(False)
1911                 self.staticText4.Enable(True)
1912                 self.Min.Enable(False)
1913                 self.Max.Enable(False)
1914                 self.Length.Enable(True)
1915         else:
1916             self.staticText2.Enable(False)
1917             self.staticText3.Enable(False)
1918             self.staticText4.Enable(False)
1919             self.Min.Enable(False)
1920             self.Max.Enable(False)
1921             self.Length.Enable(False)
1922
1923     def GetValues(self):
1924         name = self.Type.GetStringSelection()
1925         type = self.TypeDictionary[name][0]
1926         min = eval(self.Min.GetValue())
1927         max = eval(self.Max.GetValue())
1928         length = eval(self.Length.GetValue())
1929         return type, min, max, length
1930
1931
1932
1933 #-------------------------------------------------------------------------------
1934 #                          Editing Node Infos Dialog
1935 #-------------------------------------------------------------------------------
1936
1937
1938 [wxID_NODEINFOSDIALOG, wxID_NODEINFOSDIALOGMAINPANEL, 
1939  wxID_NODEINFOSDIALOGNAME, wxID_NODEINFOSDIALOGNODEID, 
1940  wxID_NODEINFOSDIALOGPROFILE, wxID_NODEINFOSDIALOGSTATICTEXT1, 
1941  wxID_NODEINFOSDIALOGSTATICTEXT2, wxID_NODEINFOSDIALOGSTATICTEXT3, 
1942  wxID_NODEINFOSDIALOGSTATICTEXT4, wxID_NODEINFOSDIALOGTYPE, 
1943 ] = [wx.NewId() for _init_ctrls in range(10)]
1944
1945 class NodeInfosDialog(wx.Dialog):
1946     def _init_coll_flexGridSizer1_Items(self, parent):
1947         # generated method, don't edit
1948
1949         parent.AddWindow(self.MainPanel, 0, border=0, flag=0)
1950
1951     def _init_sizers(self):
1952         # generated method, don't edit
1953         self.flexGridSizer1 = wx.FlexGridSizer(cols=1, hgap=0, rows=2, vgap=0)
1954
1955         self._init_coll_flexGridSizer1_Items(self.flexGridSizer1)
1956
1957         self.SetSizer(self.flexGridSizer1)
1958
1959     def _init_ctrls(self, prnt):
1960         # generated method, don't edit
1961         wx.Dialog.__init__(self, id=wxID_NODEINFOSDIALOG,
1962               name='NodeInfosDialog', parent=prnt, pos=wx.Point(376, 223),
1963               size=wx.Size(249, 250), style=wx.DEFAULT_DIALOG_STYLE,
1964               title='Node Infos')
1965         self.SetClientSize(wx.Size(249, 250))
1966
1967         self.MainPanel = wx.Panel(id=wxID_NODEINFOSDIALOGMAINPANEL,
1968               name='MainPanel', parent=self, pos=wx.Point(0, 0),
1969               size=wx.Size(231, 264), style=wx.TAB_TRAVERSAL)
1970         self.MainPanel.SetAutoLayout(True)
1971
1972         self.staticText1 = wx.StaticText(id=wxID_NODEINFOSDIALOGSTATICTEXT1,
1973               label='Name:', 
1974               name='staticText1', parent=self.MainPanel,
1975               pos=wx.Point(24, 24), size=wx.Size(156, 17), style=0)
1976
1977         self.Name = wx.TextCtrl(id=wxID_NODEINFOSDIALOGNAME, name='Name',
1978               parent=self.MainPanel, pos=wx.Point(24, 48), size=wx.Size(200,
1979               25), style=0, value='')
1980
1981         self.staticText2 = wx.StaticText(id=wxID_NODEINFOSDIALOGSTATICTEXT2,
1982               label='Node ID:', name='staticText2', parent=self.MainPanel,
1983               pos=wx.Point(24, 80), size=wx.Size(67, 17), style=0)
1984
1985         self.NodeID = wx.TextCtrl(id=wxID_NODEINFOSDIALOGNODEID, name='NodeID',
1986               parent=self.MainPanel, pos=wx.Point(24, 104), size=wx.Size(200,
1987               25), style=wx.TE_RIGHT, value='')
1988
1989         self.staticText3 = wx.StaticText(id=wxID_NODEINFOSDIALOGSTATICTEXT3,
1990               label='Type:', name='staticText3', parent=self.MainPanel,
1991               pos=wx.Point(24, 136), size=wx.Size(71, 17), style=0)
1992
1993         self.Type = wx.Choice(choices=[], id=wxID_NODEINFOSDIALOGTYPE,
1994               name='Type', parent=self.MainPanel, pos=wx.Point(24, 160),
1995               size=wx.Size(200, 25), style=0)
1996
1997         self.staticText4 = wx.StaticText(id=wxID_NODEINFOSDIALOGSTATICTEXT4,
1998               label='Profile:', name='staticText4', parent=self.MainPanel,
1999               pos=wx.Point(24, 192), size=wx.Size(47, 17), style=0)
2000
2001         self.Profile = wx.Choice(choices=[], id=wxID_NODEINFOSDIALOGPROFILE,
2002               name='Profile', parent=self.MainPanel, pos=wx.Point(24, 216),
2003               size=wx.Size(200, 25), style=0)
2004
2005         self._init_sizers()
2006
2007     def __init__(self, parent):
2008         self._init_ctrls(parent)
2009         self.ButtonSizer = self.CreateButtonSizer(wxOK|wxCANCEL)
2010         self.flexGridSizer1.Add(self.ButtonSizer, 1, wxALIGN_CENTER)
2011         self.Type.Append("master")
2012         self.Type.Append("slave")
2013         self.staticText4.Hide()
2014         self.Profile.Hide()
2015
2016         EVT_BUTTON(self, self.ButtonSizer.GetAffirmativeButton().GetId(), self.OnOK)
2017
2018     def OnOK(self, event):
2019         name = self.Name.GetValue()
2020         if name != "":
2021             good = not name[0].isdigit()
2022             for item in name.split("_"):
2023                 good &= item.isalnum()
2024         else:
2025             good = False
2026         if not good:
2027             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)
2028             message.ShowModal()
2029             message.Destroy()
2030             self.Name.SetFocus()
2031         else:
2032             self.EndModal(wxID_OK)
2033     
2034     def SetProfiles(self, profiles):
2035         for profile in profiles:
2036             self.Profile.Append(profile)
2037     
2038     def SetValues(self, name, id, type, profile):
2039         self.Name.SetValue(name)
2040         self.NodeID.SetValue("0x%02X"%id)
2041         self.Type.SetStringSelection(type)
2042         self.Profile.SetStringSelection(profile)
2043
2044     def GetValues(self):
2045         name = self.Name.GetValue()
2046         nodeid = eval(self.NodeID.GetValue())
2047         type = self.Type.GetStringSelection()
2048         profile = self.Profile.GetStringSelection()
2049         return name, nodeid, type, profile
2050
2051
2052
2053 #-------------------------------------------------------------------------------
2054 #                          Create New Node Dialog
2055 #-------------------------------------------------------------------------------
2056
2057
2058 [wxID_CREATENODEDIALOG, wxID_CREATENODEDIALOGEMERGENCY, 
2059  wxID_CREATENODEDIALOGGENSYNC, wxID_CREATENODEDIALOGMAINPANEL, 
2060  wxID_CREATENODEDIALOGNAME, wxID_CREATENODEDIALOGNMT_HEARTBEAT, 
2061  wxID_CREATENODEDIALOGNMT_NODEGUARDING, wxID_CREATENODEDIALOGNMT_NONE, 
2062  wxID_CREATENODEDIALOGNODEID, wxID_CREATENODEDIALOGPROFILE, 
2063  wxID_CREATENODEDIALOGSAVECONFIG, wxID_CREATENODEDIALOGSTATICTEXT1, 
2064  wxID_CREATENODEDIALOGSTATICTEXT2, wxID_CREATENODEDIALOGSTATICTEXT3, 
2065  wxID_CREATENODEDIALOGSTATICTEXT4, wxID_CREATENODEDIALOGSTATICTEXT5, 
2066  wxID_CREATENODEDIALOGSTATICTEXT6, wxID_CREATENODEDIALOGSTOREEDS, 
2067  wxID_CREATENODEDIALOGTYPE, 
2068 ] = [wx.NewId() for _init_ctrls in range(19)]
2069
2070 class CreateNodeDialog(wx.Dialog):
2071     def _init_coll_flexGridSizer1_Items(self, parent):
2072         # generated method, don't edit
2073
2074         parent.AddWindow(self.MainPanel, 0, border=0, flag=0)
2075
2076     def _init_sizers(self):
2077         # generated method, don't edit
2078         self.flexGridSizer1 = wx.FlexGridSizer(cols=1, hgap=0, rows=2, vgap=0)
2079
2080         self._init_coll_flexGridSizer1_Items(self.flexGridSizer1)
2081
2082         self.SetSizer(self.flexGridSizer1)
2083
2084     def _init_ctrls(self, prnt):
2085         # generated method, don't edit
2086         wx.Dialog.__init__(self, id=wxID_CREATENODEDIALOG,
2087               name='CreateNodeDialog', parent=prnt, pos=wx.Point(376, 223),
2088               size=wx.Size(451, 316), style=wx.DEFAULT_DIALOG_STYLE,
2089               title='Create a new Node')
2090         self.SetClientSize(wx.Size(451, 316))
2091
2092         self.MainPanel = wx.Panel(id=wxID_CREATENODEDIALOGMAINPANEL,
2093               name='MainPanel', parent=self, pos=wx.Point(0, 0),
2094               size=wx.Size(440, 278), style=wx.TAB_TRAVERSAL)
2095         self.MainPanel.SetAutoLayout(True)
2096
2097         self.staticText1 = wx.StaticText(id=wxID_CREATENODEDIALOGSTATICTEXT1,
2098               label='Name:', name='staticText1', parent=self.MainPanel,
2099               pos=wx.Point(24, 24), size=wx.Size(156, 17), style=0)
2100
2101         self.staticText2 = wx.StaticText(id=wxID_CREATENODEDIALOGSTATICTEXT2,
2102               label='Node ID:', name='staticText2', parent=self.MainPanel,
2103               pos=wx.Point(24, 80), size=wx.Size(67, 17), style=0)
2104
2105         self.staticText3 = wx.StaticText(id=wxID_CREATENODEDIALOGSTATICTEXT3,
2106               label='Type:', name='staticText3', parent=self.MainPanel,
2107               pos=wx.Point(24, 136), size=wx.Size(71, 17), style=0)
2108
2109         self.Type = wx.Choice(choices=[], id=wxID_CREATENODEDIALOGTYPE,
2110               name='Type', parent=self.MainPanel, pos=wx.Point(24, 160),
2111               size=wx.Size(200, 24), style=0)
2112
2113         self.Name = wx.TextCtrl(id=wxID_CREATENODEDIALOGNAME, name='Name',
2114               parent=self.MainPanel, pos=wx.Point(24, 48), size=wx.Size(200,
2115               25), style=0, value='')
2116
2117         self.NodeID = wx.TextCtrl(id=wxID_CREATENODEDIALOGNODEID, name='NodeID',
2118               parent=self.MainPanel, pos=wx.Point(24, 104), size=wx.Size(200,
2119               25), style=wx.TE_RIGHT, value='')
2120
2121         self.staticText4 = wx.StaticText(id=wxID_CREATENODEDIALOGSTATICTEXT4,
2122               label='Profile:', name='staticText4', parent=self.MainPanel,
2123               pos=wx.Point(24, 192), size=wx.Size(47, 17), style=0)
2124
2125         self.Profile = wx.Choice(choices=[], id=wxID_CREATENODEDIALOGPROFILE,
2126               name='Profile', parent=self.MainPanel, pos=wx.Point(24, 216),
2127               size=wx.Size(200, 24), style=0)
2128         self.Profile.Bind(wx.EVT_CHOICE, self.OnProfileChoice,
2129               id=wxID_CREATENODEDIALOGPROFILE)
2130
2131         self.staticText5 = wx.StaticText(id=wxID_CREATENODEDIALOGSTATICTEXT5,
2132               label='Network Management:', name='staticText5',
2133               parent=self.MainPanel, pos=wx.Point(256, 24), size=wx.Size(152,
2134               16), style=0)
2135
2136         self.NMT_None = wx.RadioButton(id=wxID_CREATENODEDIALOGNMT_NONE,
2137               label='None', name='NMT_None', parent=self.MainPanel,
2138               pos=wx.Point(256, 40), size=wx.Size(114, 24), style=0)
2139         self.NMT_None.SetValue(True)
2140
2141         self.NMT_NodeGuarding = wx.RadioButton(id=wxID_CREATENODEDIALOGNMT_NODEGUARDING,
2142               label='Node Guarding', name='NMT_NodeGuarding',
2143               parent=self.MainPanel, pos=wx.Point(256, 64), size=wx.Size(128,
2144               24), style=0)
2145         self.NMT_NodeGuarding.SetValue(False)
2146
2147         self.NMT_Heartbeat = wx.RadioButton(id=wxID_CREATENODEDIALOGNMT_HEARTBEAT,
2148               label='Heartbeat', name='NMT_Heartbeat', parent=self.MainPanel,
2149               pos=wx.Point(256, 88), size=wx.Size(114, 24), style=0)
2150         self.NMT_Heartbeat.SetValue(False)
2151
2152         self.staticText6 = wx.StaticText(id=wxID_CREATENODEDIALOGSTATICTEXT6,
2153               label='Options:', name='staticText6', parent=self.MainPanel,
2154               pos=wx.Point(256, 128), size=wx.Size(72, 17), style=0)
2155
2156         self.DS302 = wx.CheckBox(id=wxID_CREATENODEDIALOGGENSYNC,
2157               label='DS-302 Profile', name='DS302', parent=self.MainPanel,
2158               pos=wx.Point(256, 144), size=wx.Size(128, 24), style=0)
2159         self.DS302.SetValue(False)
2160         self.DS302.Enable(False)
2161
2162         self.GenSYNC = wx.CheckBox(id=wxID_CREATENODEDIALOGGENSYNC,
2163               label='Generate SYNC', name='GenSYNC', parent=self.MainPanel,
2164               pos=wx.Point(256, 168), size=wx.Size(128, 24), style=0)
2165         self.GenSYNC.SetValue(False)
2166
2167         self.Emergency = wx.CheckBox(id=wxID_CREATENODEDIALOGEMERGENCY,
2168               label='Emergency support', name='Emergency',
2169               parent=self.MainPanel, pos=wx.Point(256, 192), size=wx.Size(152,
2170               24), style=0)
2171         self.Emergency.SetValue(False)
2172         self.Emergency.Enable(False)
2173
2174         self.SaveConfig = wx.CheckBox(id=wxID_CREATENODEDIALOGSAVECONFIG,
2175               label='Save Configuration', name='SaveConfig',
2176               parent=self.MainPanel, pos=wx.Point(256, 216), size=wx.Size(152,
2177               24), style=0)
2178         self.SaveConfig.SetValue(False)
2179         self.SaveConfig.Enable(False)
2180
2181 #        self.StoreEDS = wx.CheckBox(id=wxID_CREATENODEDIALOGSTOREEDS,
2182 #              label='Store EDS', name='StoreEDS', parent=self.MainPanel,
2183 #              pos=wx.Point(256, 240), size=wx.Size(144, 24), style=0)
2184 #        self.StoreEDS.SetValue(False)
2185  
2186         self._init_sizers()
2187
2188     def __init__(self, parent):
2189         self._init_ctrls(parent)
2190         self.ButtonSizer = self.CreateButtonSizer(wxOK|wxCANCEL)
2191         self.flexGridSizer1.Add(self.ButtonSizer, 1, wxALIGN_CENTER)
2192         self.NodeID.SetValue("0x00")
2193         self.Type.Append("master")
2194         self.Type.Append("slave")
2195         self.Type.SetStringSelection("slave")
2196         self.ListProfile = {"None" : ""}
2197         self.Profile.Append("None")
2198         self.Directory = os.path.join(os.getcwd(), "config")
2199         listfiles = os.listdir(self.Directory)
2200         listfiles.sort()
2201         for item in listfiles:
2202             name, extend = os.path.splitext(item)
2203             if os.path.isfile(os.path.join(self.Directory, item)) and extend == ".prf" and name != "DS-302":
2204                 self.ListProfile[name] = os.path.join(self.Directory, item)
2205                 self.Profile.Append(name)
2206         self.Profile.Append("Other")
2207         self.Profile.SetStringSelection("None")
2208         self.Name.SetFocus()
2209         
2210         EVT_BUTTON(self, self.ButtonSizer.GetAffirmativeButton().GetId(), self.OnOK)
2211
2212     def OnOK(self, event):
2213         name = self.Name.GetValue()
2214         if name != "":
2215             good = not name[0].isdigit()
2216             for item in name.split("_"):
2217                 good &= item.isalnum()
2218         else:
2219             good = False
2220         if not good:
2221             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)
2222             message.ShowModal()
2223             message.Destroy()
2224             self.Name.SetFocus()
2225         else:
2226             self.EndModal(wxID_OK)
2227
2228     def GetValues(self):
2229         name = self.Name.GetValue()
2230         nodeid = 0
2231         if self.NodeID.GetValue() != "":
2232             nodeid = eval(self.NodeID.GetValue())
2233         type = self.Type.GetStringSelection()
2234         return name, nodeid, type
2235
2236     def GetProfile(self):
2237         name = self.Profile.GetStringSelection()
2238         return name, self.ListProfile[name]
2239
2240     def GetNMTManagement(self):
2241         if self.NMT_None.GetValue():
2242             return "None"
2243         elif self.NMT_NodeGuarding.GetValue():
2244             return "NodeGuarding"
2245         elif self.NMT_Heartbeat.GetValue():
2246             return "Heartbeat"
2247         return None
2248     
2249     def GetOptions(self):
2250         options = []
2251         if self.DS302.GetValue():
2252             options.append("DS302")
2253         if self.GenSYNC.GetValue():
2254             options.append("GenSYNC")
2255         if self.Emergency.GetValue():
2256             options.append("Emergency")
2257         if self.SaveConfig.GetValue():
2258             options.append("SaveConfig")
2259 #        if self.StoreEDS.GetValue():
2260 #            options.append("StoreEDS")
2261         return options
2262
2263     def OnProfileChoice(self, event):
2264         if self.Profile.GetStringSelection() == "Other":
2265             dialog = wxFileDialog(self, "Choose a file", self.Directory, "",  "OD Profile files (*.prf)|*.prf|All files|*.*", wxOPEN|wxCHANGE_DIR)
2266             dialog.ShowModal()
2267             filepath = dialog.GetPath()
2268             dialog.Destroy()
2269             if os.path.isfile(filepath):
2270                 name = os.path.splitext(os.path.basename(filepath))[0]
2271                 self.ListProfile[name] = filepath
2272                 length = self.Profile.GetCount()
2273                 self.Profile.Insert(name, length - 2)
2274                 self.Profile.SetStringSelection(name)
2275             else:
2276                 self.Profile.SetStringSelection("None")
2277         event.Skip()
2278     
2279
2280 #-------------------------------------------------------------------------------
2281 #                               Exception Handler
2282 #-------------------------------------------------------------------------------
2283
2284 Max_Traceback_List_Size = 20
2285
2286 def Display_Exception_Dialog(e_type,e_value,e_tb):
2287     trcbck_lst = []
2288     for i,line in enumerate(traceback.extract_tb(e_tb)):
2289         trcbck = " " + str(i+1) + ". "
2290         if line[0].find(os.getcwd()) == -1:
2291             trcbck += "file : " + str(line[0]) + ",   "
2292         else:
2293             trcbck += "file : " + str(line[0][len(os.getcwd()):]) + ",   "
2294         trcbck += "line : " + str(line[1]) + ",   " + "function : " + str(line[2])
2295         trcbck_lst.append(trcbck)
2296         
2297     # Allow clicking....
2298     cap = wx.Window_GetCapture()
2299     if cap:
2300         cap.ReleaseMouse()
2301
2302     dlg = wx.SingleChoiceDialog(None, 
2303         """
2304 An error happens.
2305
2306 Click on OK for saving an error report.
2307
2308 Please contact LOLITech at:
2309 +33 (0)3 29 52 95 67
2310 bugs_objdictedit@lolitech.fr
2311
2312
2313 Error:
2314 """ +
2315         str(e_type) + " : " + str(e_value), 
2316         "Error",
2317         trcbck_lst)
2318     try:
2319         res = (dlg.ShowModal() == wx.ID_OK)
2320     finally:
2321         dlg.Destroy()
2322
2323     return res
2324
2325 def Display_Error_Dialog(e_value):
2326     message = wxMessageDialog(None, str(e_value), "Error", wxOK|wxICON_ERROR)
2327     message.ShowModal()
2328     message.Destroy()
2329
2330 def get_last_traceback(tb):
2331     while tb.tb_next:
2332         tb = tb.tb_next
2333     return tb
2334
2335
2336 def format_namespace(d, indent='    '):
2337     return '\n'.join(['%s%s: %s' % (indent, k, repr(v)[:10000]) for k, v in d.iteritems()])
2338
2339
2340 ignored_exceptions = [] # a problem with a line in a module is only reported once per session
2341
2342 def wxAddExceptHook(path, app_version='[No version]'):#, ignored_exceptions=[]):
2343     
2344     def handle_exception(e_type, e_value, e_traceback):
2345         traceback.print_exception(e_type, e_value, e_traceback) # this is very helpful when there's an exception in the rest of this func
2346         last_tb = get_last_traceback(e_traceback)
2347         ex = (last_tb.tb_frame.f_code.co_filename, last_tb.tb_frame.f_lineno)
2348         if str(e_value).startswith("!!!"):
2349             Display_Error_Dialog(e_value)
2350         elif ex not in ignored_exceptions:
2351             ignored_exceptions.append(ex)
2352             result = Display_Exception_Dialog(e_type,e_value,e_traceback)
2353             if result:
2354                 info = {
2355                     'app-title' : wx.GetApp().GetAppName(), # app_title
2356                     'app-version' : app_version,
2357                     'wx-version' : wx.VERSION_STRING,
2358                     'wx-platform' : wx.Platform,
2359                     'python-version' : platform.python_version(), #sys.version.split()[0],
2360                     'platform' : platform.platform(),
2361                     'e-type' : e_type,
2362                     'e-value' : e_value,
2363                     'date' : time.ctime(),
2364                     'cwd' : os.getcwd(),
2365                     }
2366                 if e_traceback:
2367                     info['traceback'] = ''.join(traceback.format_tb(e_traceback)) + '%s: %s' % (e_type, e_value)
2368                     last_tb = get_last_traceback(e_traceback)
2369                     exception_locals = last_tb.tb_frame.f_locals # the locals at the level of the stack trace where the exception actually occurred
2370                     info['locals'] = format_namespace(exception_locals)
2371                     if 'self' in exception_locals:
2372                         info['self'] = format_namespace(exception_locals['self'].__dict__)
2373                 
2374                 output = open(path+os.sep+"bug_report_"+info['date'].replace(':','-').replace(' ','_')+".txt",'w')
2375                 lst = info.keys()
2376                 lst.sort()
2377                 for a in lst:
2378                     output.write(a+":\n"+str(info[a])+"\n\n")
2379
2380     #sys.excepthook = lambda *args: wx.CallAfter(handle_exception, *args)
2381     sys.excepthook = handle_exception
2382
2383 if __name__ == '__main__':
2384     app = wxPySimpleApp()
2385     wxInitAllImageHandlers()
2386     
2387     # Install a exception handle for bug reports
2388     wxAddExceptHook(os.getcwd(),__version__)
2389     
2390     frame = objdictedit(None)
2391
2392     frame.Show()
2393     app.MainLoop()