]> rtime.felk.cvut.cz Git - CanFestival-3.git/blob - objdictgen/subindextable.py
Cleaning code for using only wxPython 2.6 class naming
[CanFestival-3.git] / objdictgen / subindextable.py
1 #!/usr/bin/env python
2 # -*- coding: utf-8 -*-
3
4 #This file is part of CanFestival, a library implementing CanOpen Stack. 
5 #
6 #Copyright (C): Edouard TISSERANT, Francis DUPIN and Laurent BESSARD
7 #
8 #See COPYING file for copyrights details.
9 #
10 #This library is free software; you can redistribute it and/or
11 #modify it under the terms of the GNU Lesser General Public
12 #License as published by the Free Software Foundation; either
13 #version 2.1 of the License, or (at your option) any later version.
14 #
15 #This library is distributed in the hope that it will be useful,
16 #but WITHOUT ANY WARRANTY; without even the implied warranty of
17 #MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
18 #Lesser General Public License for more details.
19 #
20 #You should have received a copy of the GNU Lesser General Public
21 #License along with this library; if not, write to the Free Software
22 #Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
23
24 import wx
25 import wx.grid
26
27 from types import *
28
29 from node import OD_Subindex, OD_MultipleSubindexes, OD_IdenticalSubindexes, OD_IdenticalIndexes
30
31 ColSizes = [75, 250, 150, 125, 100, 60, 250]
32 ColAlignements = [wx.ALIGN_CENTER, wx.ALIGN_LEFT, wx.ALIGN_CENTER, wx.ALIGN_RIGHT, wx.ALIGN_CENTER, wx.ALIGN_CENTER, wx.ALIGN_LEFT]
33 AccessList = "Read Only,Write Only,Read/Write"
34 RAccessList = "Read Only,Read/Write"
35 BoolList = "True,False"
36 OptionList = "Yes,No"
37
38 DictionaryOrganisation = [
39     {"minIndex" : 0x0001, "maxIndex" : 0x0FFF, "name" : "Data Type Definitions"},
40     {"minIndex" : 0x1000, "maxIndex" : 0x1029, "name" : "Communication Parameters"},
41     {"minIndex" : 0x1200, "maxIndex" : 0x12FF, "name" : "SDO Parameters"},
42     {"minIndex" : 0x1400, "maxIndex" : 0x15FF, "name" : "Receive PDO Parameters"},
43     {"minIndex" : 0x1600, "maxIndex" : 0x17FF, "name" : "Receive PDO Mapping"},
44     {"minIndex" : 0x1800, "maxIndex" : 0x19FF, "name" : "Transmit PDO Parameters"},
45     {"minIndex" : 0x1A00, "maxIndex" : 0x1BFF, "name" : "Transmit PDO Mapping"},
46     {"minIndex" : 0x1C00, "maxIndex" : 0x1FFF, "name" : "Other Communication Parameters"},
47     {"minIndex" : 0x2000, "maxIndex" : 0x5FFF, "name" : "Manufacturer Specific"},
48     {"minIndex" : 0x6000, "maxIndex" : 0x9FFF, "name" : "Standardized Device Profile"},
49     {"minIndex" : 0xA000, "maxIndex" : 0xBFFF, "name" : "Standardized Interface Profile"}]
50
51 SizeConversion = {1 : "X", 8 : "B", 16 : "W", 24 : "D", 32 : "D", 40 : "L", 48 : "L", 56 : "L", 64 : "L"}
52
53 class SubindexTable(wx.grid.PyGridTableBase):
54     
55     """
56     A custom wxGrid Table using user supplied data
57     """
58     def __init__(self, parent, data, editors, colnames):
59         # The base class must be initialized *first*
60         wx.grid.PyGridTableBase.__init__(self)
61         self.data = data
62         self.editors = editors
63         self.CurrentIndex = 0
64         self.colnames = colnames
65         self.Parent = parent
66         self.Editable = True
67         # XXX
68         # we need to store the row length and collength to
69         # see if the table has changed size
70         self._rows = self.GetNumberRows()
71         self._cols = self.GetNumberCols()
72     
73     def Disable(self):
74         self.Editable = False
75         
76     def Enable(self):
77         self.Editable = True
78     
79     def GetNumberCols(self):
80         return len(self.colnames)
81         
82     def GetNumberRows(self):
83         return len(self.data)
84
85     def GetColLabelValue(self, col):
86         if col < len(self.colnames):
87             return self.colnames[col]
88
89     def GetRowLabelValues(self, row):
90         return row
91
92     def GetValue(self, row, col):
93         if row < self.GetNumberRows():
94             value = self.data[row].get(self.GetColLabelValue(col), "")
95             if (type(value) == UnicodeType):
96                 return value
97             else: 
98                 return str(value)
99     
100     def GetEditor(self, row, col):
101         if row < self.GetNumberRows():
102             return self.editors[row].get(self.GetColLabelValue(col), "")
103     
104     def GetValueByName(self, row, colname):
105         return self.data[row].get(colname)
106
107     def SetValue(self, row, col, value):
108         if col < len(self.colnames):
109             self.data[row][self.GetColLabelValue(col)] = value
110         
111     def ResetView(self, grid):
112         """
113         (wx.grid.Grid) -> Reset the grid view.   Call this to
114         update the grid if rows and columns have been added or deleted
115         """
116         grid.BeginBatch()
117         for current, new, delmsg, addmsg in [
118             (self._rows, self.GetNumberRows(), wx.grid.GRIDTABLE_NOTIFY_ROWS_DELETED, wx.grid.GRIDTABLE_NOTIFY_ROWS_APPENDED),
119             (self._cols, self.GetNumberCols(), wx.grid.GRIDTABLE_NOTIFY_COLS_DELETED, wx.grid.GRIDTABLE_NOTIFY_COLS_APPENDED),
120         ]:
121             if new < current:
122                 msg = wx.grid.GridTableMessage(self,delmsg,new,current-new)
123                 grid.ProcessTableMessage(msg)
124             elif new > current:
125                 msg = wx.grid.GridTableMessage(self,addmsg,new-current)
126                 grid.ProcessTableMessage(msg)
127                 self.UpdateValues(grid)
128         grid.EndBatch()
129
130         self._rows = self.GetNumberRows()
131         self._cols = self.GetNumberCols()
132         # update the column rendering scheme
133         self._updateColAttrs(grid)
134
135         # update the scrollbars and the displayed part of the grid
136         grid.AdjustScrollbars()
137         grid.ForceRefresh()
138
139
140     def UpdateValues(self, grid):
141         """Update all displayed values"""
142         # This sends an event to the grid table to update all of the values
143         msg = wx.grid.GridTableMessage(self, wx.grid.GRIDTABLE_REQUEST_VIEW_GET_VALUES)
144         grid.ProcessTableMessage(msg)
145
146     def _updateColAttrs(self, grid):
147         """
148         wx.grid.Grid -> update the column attributes to add the
149         appropriate renderer given the column name.
150
151         Otherwise default to the default renderer.
152         """
153         
154         for col in range(self.GetNumberCols()):
155             attr = wx.grid.GridCellAttr()
156             attr.SetAlignment(ColAlignements[col], wx.ALIGN_CENTRE)
157             grid.SetColAttr(col, attr)
158             grid.SetColSize(col, ColSizes[col])
159         
160         typelist = None
161         maplist = None
162         for row in range(self.GetNumberRows()):
163             editors = self.editors[row]
164             for col in range(self.GetNumberCols()):
165                 editor = None
166                 renderer = None
167                 
168                 colname = self.GetColLabelValue(col)
169                 editortype = editors[colname]
170                 if editortype and self.Editable:
171                     grid.SetReadOnly(row, col, False)
172                     if editortype == "string":
173                         editor = wx.grid.GridCellTextEditor()
174                         renderer = wx.grid.GridCellStringRenderer()
175                         if colname == "value" and "length" in editors:
176                             editor.SetParameters(editors["length"]) 
177                     elif editortype == "number":
178                         editor = wx.grid.GridCellNumberEditor()
179                         renderer = wx.grid.GridCellNumberRenderer()
180                         if colname == "value" and "min" in editors and "max" in editors:
181                             editor.SetParameters("%s,%s"%(editors["min"],editors["max"]))
182                     elif editortype == "real":
183                         editor = wx.grid.GridCellFloatEditor()
184                         renderer = wx.grid.GridCellFloatRenderer()
185                         if colname == "value" and "min" in editors and "max" in editors:
186                             editor.SetParameters("%s,%s"%(editors["min"],editors["max"]))
187                     elif editortype == "bool":
188                         editor = wx.grid.GridCellChoiceEditor()
189                         editor.SetParameters(BoolList)
190                     elif editortype == "access":
191                         editor = wx.grid.GridCellChoiceEditor()
192                         editor.SetParameters(AccessList)
193                     elif editortype == "raccess":
194                         editor = wx.grid.GridCellChoiceEditor()
195                         editor.SetParameters(RAccessList)
196                     elif editortype == "option":
197                         editor = wx.grid.GridCellChoiceEditor()
198                         editor.SetParameters(OptionList)
199                     elif editortype == "type":
200                         editor = wx.grid.GridCellChoiceEditor()
201                         if typelist == None:
202                             typelist = self.Parent.Manager.GetCurrentTypeList()
203                         editor.SetParameters(typelist)
204                     elif editortype == "map":
205                         editor = wx.grid.GridCellChoiceEditor()
206                         if maplist == None:
207                             maplist = self.Parent.Manager.GetCurrentMapList()
208                         editor.SetParameters(maplist)
209                     elif editortype == "time":
210                         editor = wx.grid.GridCellTextEditor()
211                         renderer = wx.grid.GridCellStringRenderer()
212                     elif editortype == "domain":
213                         editor = wx.grid.GridCellTextEditor()
214                         renderer = wx.grid.GridCellStringRenderer()
215                 else:
216                     grid.SetReadOnly(row, col, True)
217                     
218                 grid.SetCellEditor(row, col, editor)
219                 grid.SetCellRenderer(row, col, renderer)
220                 
221                 grid.SetCellBackgroundColour(row, col, wx.WHITE)
222     
223     def SetData(self, data):
224         self.data = data
225         
226     def SetEditors(self, editors):
227         self.editors = editors
228     
229     def GetCurrentIndex(self):
230         return self.CurrentIndex
231     
232     def SetCurrentIndex(self, index):
233         self.CurrentIndex = index
234     
235     def AppendRow(self, row_content):
236         self.data.append(row_content)
237
238     def Empty(self):
239         self.data = []
240         self.editors = []
241
242 [ID_EDITINGPANEL, ID_EDITINGPANELADDBUTTON, ID_EDITINGPANELINDEXCHOICE, 
243  ID_EDITINGPANELINDEXLIST, ID_EDITINGPANELINDEXLISTPANEL, ID_EDITINGPANELPARTLIST, 
244  ID_EDITINGPANELSECONDSPLITTER, ID_EDITINGPANELSUBINDEXGRID,
245  ID_EDITINGPANELSUBINDEXGRIDPANEL, ID_EDITINGPANELCALLBACKCHECK,
246 ] = [wx.NewId() for _init_ctrls in range(10)]
247
248 [ID_EDITINGPANELINDEXLISTMENUITEMS0, ID_EDITINGPANELINDEXLISTMENUITEMS1, 
249  ID_EDITINGPANELINDEXLISTMENUITEMS2, 
250 ] = [wx.NewId() for _init_coll_IndexListMenu_Items in range(3)]
251
252 [ID_EDITINGPANELMENU1ITEMS0, ID_EDITINGPANELMENU1ITEMS1, 
253 ] = [wx.NewId() for _init_coll_SubindexGridMenu_Items in range(2)]
254
255 class EditingPanel(wx.SplitterWindow):
256     def _init_coll_AddToListSizer_Items(self, parent):
257         parent.AddWindow(self.AddButton, 0, border=0, flag=0)
258         parent.AddWindow(self.IndexChoice, 0, border=0, flag=wx.GROW)
259
260     def _init_coll_SubindexGridSizer_Items(self, parent):
261         parent.AddWindow(self.CallbackCheck, 0, border=0, flag=0)
262         parent.AddWindow(self.SubindexGrid, 0, border=0, flag=wx.GROW)
263
264     def _init_coll_IndexListSizer_Items(self, parent):
265         parent.AddWindow(self.IndexList, 0, border=0, flag=wx.GROW)
266         parent.AddSizer(self.AddToListSizer, 0, border=0, flag=wx.GROW)
267
268     def _init_coll_AddToListSizer_Growables(self, parent):
269         parent.AddGrowableCol(1)
270
271     def _init_coll_SubindexGridSizer_Growables(self, parent):
272         parent.AddGrowableCol(0)
273         parent.AddGrowableRow(1)
274
275     def _init_coll_IndexListSizer_Growables(self, parent):
276         parent.AddGrowableCol(0)
277         parent.AddGrowableRow(0)
278
279     def _init_coll_SubindexGridMenu_Items(self, parent):
280         parent.Append(help='', id=ID_EDITINGPANELMENU1ITEMS0,
281               kind=wx.ITEM_NORMAL, text='Add')
282         parent.Append(help='', id=ID_EDITINGPANELMENU1ITEMS1,
283               kind=wx.ITEM_NORMAL, text='Delete')
284         self.Bind(wx.EVT_MENU, self.OnAddSubindexMenu,
285               id=ID_EDITINGPANELMENU1ITEMS0)
286         self.Bind(wx.EVT_MENU, self.OnDeleteSubindexMenu,
287               id=ID_EDITINGPANELMENU1ITEMS1)
288
289     def _init_coll_IndexListMenu_Items(self, parent):
290         parent.Append(help='', id=ID_EDITINGPANELINDEXLISTMENUITEMS0,
291               kind=wx.ITEM_NORMAL, text='Rename')
292         parent.Append(help='', id=ID_EDITINGPANELINDEXLISTMENUITEMS2,
293               kind=wx.ITEM_NORMAL, text='Modify')
294         parent.Append(help='', id=ID_EDITINGPANELINDEXLISTMENUITEMS1,
295               kind=wx.ITEM_NORMAL, text='Delete')
296         self.Bind(wx.EVT_MENU, self.OnRenameIndexMenu,
297               id=ID_EDITINGPANELINDEXLISTMENUITEMS0)
298         self.Bind(wx.EVT_MENU, self.OnDeleteIndexMenu,
299               id=ID_EDITINGPANELINDEXLISTMENUITEMS1)
300         self.Bind(wx.EVT_MENU, self.OnModifyIndexMenu,
301               id=ID_EDITINGPANELINDEXLISTMENUITEMS2)
302
303     def _init_utils(self):
304         self.IndexListMenu = wx.Menu(title='')
305         self.SubindexGridMenu = wx.Menu(title='')
306
307         self._init_coll_IndexListMenu_Items(self.IndexListMenu)
308         self._init_coll_SubindexGridMenu_Items(self.SubindexGridMenu)
309
310     def _init_sizers(self):
311         self.IndexListSizer = wx.FlexGridSizer(cols=1, hgap=0, rows=2, vgap=0)
312         self.SubindexGridSizer = wx.FlexGridSizer(cols=1, hgap=0, rows=2, vgap=0)
313         self.AddToListSizer = wx.FlexGridSizer(cols=2, hgap=0, rows=1, vgap=0)
314
315         self._init_coll_IndexListSizer_Growables(self.IndexListSizer)
316         self._init_coll_IndexListSizer_Items(self.IndexListSizer)
317         self._init_coll_SubindexGridSizer_Growables(self.SubindexGridSizer)
318         self._init_coll_SubindexGridSizer_Items(self.SubindexGridSizer)
319         self._init_coll_AddToListSizer_Growables(self.AddToListSizer)
320         self._init_coll_AddToListSizer_Items(self.AddToListSizer)
321
322         self.SubindexGridPanel.SetSizer(self.SubindexGridSizer)
323         self.IndexListPanel.SetSizer(self.IndexListSizer)
324         
325     def _init_ctrls(self, prnt):
326         wx.SplitterWindow.__init__(self, id=ID_EDITINGPANEL,
327               name='MainSplitter', parent=prnt, point=wx.Point(0, 0),
328               size=wx.Size(-1, -1), style=wx.SP_3D)
329         self._init_utils()
330         self.SetNeedUpdating(True)
331         self.SetMinimumPaneSize(1)
332
333         self.PartList = wx.ListBox(choices=[], id=ID_EDITINGPANELPARTLIST,
334               name='PartList', parent=self, pos=wx.Point(0, 0),
335               size=wx.Size(-1, -1), style=0)
336         self.PartList.Bind(wx.EVT_LISTBOX, self.OnPartListBoxClick,
337               id=ID_EDITINGPANELPARTLIST)
338
339         self.SecondSplitter = wx.SplitterWindow(id=ID_EDITINGPANELSECONDSPLITTER,
340               name='SecondSplitter', parent=self, point=wx.Point(0, 0), 
341               size=wx.Size(-1, -1), style=wx.SP_3D)
342         self.SecondSplitter.SetMinimumPaneSize(1)
343         self.SplitHorizontally(self.PartList, self.SecondSplitter,
344               110)
345
346         self.SubindexGridPanel = wx.Panel(id=ID_EDITINGPANELSUBINDEXGRIDPANEL,
347               name='SubindexGridPanel', parent=self.SecondSplitter, 
348               pos=wx.Point(0, 0), size=wx.Size(-1, -1), style=wx.TAB_TRAVERSAL)
349
350         self.IndexListPanel = wx.Panel(id=ID_EDITINGPANELINDEXLISTPANEL,
351               name='IndexListPanel', parent=self.SecondSplitter, 
352               pos=wx.Point(0, 0), size=wx.Size(-1, -1), style=wx.TAB_TRAVERSAL)
353         self.SecondSplitter.SplitVertically(self.IndexListPanel,
354               self.SubindexGridPanel, 280)
355
356         self.SubindexGrid = wx.grid.Grid(id=ID_EDITINGPANELSUBINDEXGRID,
357               name='SubindexGrid', parent=self.SubindexGridPanel, pos=wx.Point(0,
358               0), size=wx.Size(-1, -1), style=0)
359         self.SubindexGrid.SetFont(wx.Font(12, 77, wx.NORMAL, wx.NORMAL, False,
360               'Sans'))
361         self.SubindexGrid.SetLabelFont(wx.Font(10, 77, wx.NORMAL, wx.NORMAL,
362               False, 'Sans'))
363         self.SubindexGrid.Bind(wx.grid.EVT_GRID_CELL_CHANGE,
364               self.OnSubindexGridCellChange)
365         self.SubindexGrid.Bind(wx.grid.EVT_GRID_CELL_RIGHT_CLICK,
366               self.OnSubindexGridRightClick)
367         self.SubindexGrid.Bind(wx.grid.EVT_GRID_SELECT_CELL,
368               self.OnSubindexGridSelectCell)
369         self.SubindexGrid.Bind(wx.grid.EVT_GRID_CELL_LEFT_CLICK, self.OnSubindexGridCellLeftClick)
370
371         self.CallbackCheck = wx.CheckBox(id=ID_EDITINGPANELCALLBACKCHECK,
372               label='Have Callbacks', name='CallbackCheck',
373               parent=self.SubindexGridPanel, pos=wx.Point(0, 0), size=wx.Size(152,
374               24), style=0)
375         self.CallbackCheck.Bind(wx.EVT_CHECKBOX, self.OnCallbackCheck,
376               id=ID_EDITINGPANELCALLBACKCHECK)
377
378         self.IndexList = wx.ListBox(choices=[], id=ID_EDITINGPANELINDEXLIST,
379               name='IndexList', parent=self.IndexListPanel, pos=wx.Point(0, 0),
380               size=wx.Size(-1, -1), style=0)
381         self.IndexList.Bind(wx.EVT_LISTBOX, self.OnIndexListClick,
382               id=ID_EDITINGPANELINDEXLIST)
383         self.IndexList.Bind(wx.EVT_RIGHT_UP, self.OnIndexListRightUp)
384
385         self.AddButton = wx.Button(id=ID_EDITINGPANELADDBUTTON, label='Add',
386               name='AddButton', parent=self.IndexListPanel, pos=wx.Point(0, 0),
387               size=wx.Size(50, 30), style=0)
388         self.AddButton.Bind(wx.EVT_BUTTON, self.OnAddButtonClick,
389               id=ID_EDITINGPANELADDBUTTON)
390
391         self.IndexChoice = wx.Choice(choices=[], id=ID_EDITINGPANELINDEXCHOICE,
392               name='IndexChoice', parent=self.IndexListPanel, pos=wx.Point(50,
393               0), size=wx.Size(-1, 30), style=0)
394
395         self._init_sizers()
396
397     def __init__(self, parent, manager, editable = True):
398         self._init_ctrls(parent.GetNoteBook())
399         self.Parent = parent
400         self.Manager = manager
401         self.ListIndex = []
402         self.ChoiceIndex = []
403         self.FirstCall = False
404         self.Editable = editable
405         self.Index = None
406         
407         for values in DictionaryOrganisation:
408             text = "   0x%04X-0x%04X      %s"%(values["minIndex"],values["maxIndex"],values["name"])
409             self.PartList.Append(text)
410         self.Table = SubindexTable(self, [], [], ["subindex", "name", "type", "value", "access", "save", "comment"])
411         self.SubindexGrid.SetTable(self.Table)
412         self.SubindexGrid.SetRowLabelSize(0)
413         self.CallbackCheck.Disable()
414         self.Table.ResetView(self.SubindexGrid)
415
416         if not self.Editable:
417             self.AddButton.Disable()
418             self.IndexChoice.Disable()
419             self.CallbackCheck.Disable()
420             self.Table.Disable()
421
422     def GetIndex(self):
423         return self.Index
424     
425     def SetIndex(self, index):
426         self.Index = index
427
428     def GetSelection(self):
429         selected = self.IndexList.GetSelection()
430         if selected != wx.NOT_FOUND:
431             index = self.ListIndex[selected]
432             subIndex = self.SubindexGrid.GetGridCursorRow()
433             return index, subIndex
434         return None
435
436     def OnSubindexGridCellLeftClick(self, event):
437         wx.CallAfter(self.BeginDrag)
438         event.Skip()
439
440     def OnAddButtonClick(self, event):
441         if self.Editable:
442             self.SubindexGrid.SetGridCursor(0, 0)
443             selected = self.IndexChoice.GetStringSelection()
444             if selected != "":
445                 if selected == "User Type":
446                     self.Parent.AddUserType()
447                 elif selected == "SDO Server":
448                     self.Manager.AddSDOServerToCurrent()
449                 elif selected == "SDO Client":
450                     self.Manager.AddSDOClientToCurrent()
451                 elif selected == "PDO Receive":
452                     self.Manager.AddPDOReceiveToCurrent()
453                 elif selected == "PDO Transmit":
454                     self.Manager.AddPDOTransmitToCurrent()
455                 elif selected == "Map Variable":
456                     self.Parent.AddMapVariable()
457                 elif selected in [menu for menu, indexes in self.Manager.GetCurrentSpecificMenu()]:
458                     self.Manager.AddSpecificEntryToCurrent(selected)
459                 else:
460                     index = self.ChoiceIndex[self.IndexChoice.GetSelection()]
461                     self.Manager.ManageEntriesOfCurrent([index], [])
462                 self.Parent.RefreshBufferState()
463                 self.RefreshIndexList()
464         event.Skip()
465
466     def OnPartListBoxClick(self, event):
467         self.SubindexGrid.SetGridCursor(0, 0)
468         self.RefreshIndexList()
469         event.Skip()
470
471     def OnIndexListClick(self, event):
472         self.SubindexGrid.SetGridCursor(0, 0)
473         self.RefreshTable()
474         event.Skip()
475
476     def OnSubindexGridSelectCell(self, event):
477         wx.CallAfter(self.BeginDrag)
478         wx.CallAfter(self.Parent.RefreshStatusBar)
479         event.Skip()
480
481     def BeginDrag(self):
482         if not self.Parent.ModeSolo:
483             row = self.SubindexGrid.GetGridCursorRow()
484             col = self.SubindexGrid.GetGridCursorCol()
485             if not self.Editable and col == 0:
486                 selected = self.IndexList.GetSelection()
487                 if selected != wx.NOT_FOUND:
488                     index = self.ListIndex[selected]
489                     subindex = self.SubindexGrid.GetGridCursorRow()
490                     entry_infos = self.Manager.GetEntryInfos(index)
491                     if not entry_infos["struct"] & OD_MultipleSubindexes or row != 0:
492                         subentry_infos = self.Manager.GetSubentryInfos(index, subindex)
493                         typeinfos = self.Manager.GetEntryInfos(subentry_infos["type"])
494                         if subentry_infos["pdo"] and typeinfos:
495                             bus_id = self.Parent.GetBusId()
496                             node_id = self.Parent.GetCurrentNodeId()
497                             size = typeinfos["size"]
498                             data = wx.TextDataObject(str(("%s%d.%d.%d.%d"%(SizeConversion[size], bus_id, node_id, index, subindex), "location")))
499                             dragSource = wx.DropSource(self.SubindexGrid)
500                             dragSource.SetData(data)
501                             dragSource.DoDragDrop()
502
503 #-------------------------------------------------------------------------------
504 #                             Refresh Functions
505 #-------------------------------------------------------------------------------
506
507     def RefreshIndexList(self):
508         selected = self.IndexList.GetSelection()
509         choice = self.IndexChoice.GetStringSelection()
510         choiceindex = self.IndexChoice.GetSelection()
511         if selected != wx.NOT_FOUND:
512             selectedindex = self.ListIndex[selected]
513         self.IndexList.Clear()
514         self.IndexChoice.Clear()
515         i = self.PartList.GetSelection()
516         if i < len(DictionaryOrganisation):
517             values = DictionaryOrganisation[i]
518             self.ListIndex = []
519             for name, index in self.Manager.GetCurrentValidIndexes(values["minIndex"], values["maxIndex"]):
520                 self.IndexList.Append("0x%04X   %s"%(index, name))
521                 self.ListIndex.append(index)
522             if self.Editable:
523                 self.ChoiceIndex = []
524                 if i == 0:
525                     self.IndexChoice.Append("User Type")
526                     self.IndexChoice.SetStringSelection("User Type")
527                 elif i == 2:
528                     self.IndexChoice.Append("SDO Server")
529                     self.IndexChoice.Append("SDO Client")
530                     if choiceindex != wx.NOT_FOUND and choice == self.IndexChoice.GetString(choiceindex):
531                          self.IndexChoice.SetStringSelection(choice)
532                 elif i in (3, 4):
533                     self.IndexChoice.Append("PDO Receive")
534                     self.IndexChoice.SetStringSelection("PDO Receive")
535                 elif i in (5, 6):
536                     self.IndexChoice.Append("PDO Transmit")
537                     self.IndexChoice.SetStringSelection("PDO Transmit")
538                 elif i == 8:
539                     self.IndexChoice.Append("Map Variable")
540                     self.IndexChoice.SetStringSelection("Map Variable")
541                 else:
542                     for name, index in self.Manager.GetCurrentValidChoices(values["minIndex"], values["maxIndex"]):
543                         if index:
544                             self.IndexChoice.Append("0x%04X   %s"%(index, name))
545                         else:
546                             self.IndexChoice.Append(name)
547                         self.ChoiceIndex.append(index)
548                 if choiceindex != wx.NOT_FOUND and choice == self.IndexChoice.GetString(choiceindex):
549                     self.IndexChoice.SetStringSelection(choice)
550         if self.Editable:
551             self.IndexChoice.Enable(self.IndexChoice.GetCount() != 0)
552             self.AddButton.Enable(self.IndexChoice.GetCount() != 0)
553         if selected == wx.NOT_FOUND or selected >= len(self.ListIndex) or selectedindex != self.ListIndex[selected]:
554             self.Table.Empty()
555             self.CallbackCheck.SetValue(False)
556             self.CallbackCheck.Disable()
557             self.Table.ResetView(self.SubindexGrid)
558             self.Parent.RefreshStatusBar()
559         else:
560             self.IndexList.SetSelection(selected)
561             self.RefreshTable()
562
563     def RefreshTable(self):
564         selected = self.IndexList.GetSelection()
565         if selected != wx.NOT_FOUND:
566             index = self.ListIndex[selected]
567             if index > 0x260 and self.Editable:
568                 self.CallbackCheck.Enable()
569                 self.CallbackCheck.SetValue(self.Manager.HasCurrentEntryCallbacks(index))
570             result = self.Manager.GetCurrentEntryValues(index)
571             if result != None:
572                 self.Table.SetCurrentIndex(index)
573                 data, editors = result
574                 self.Table.SetData(data)
575                 self.Table.SetEditors(editors)
576                 self.Table.ResetView(self.SubindexGrid)
577         self.Parent.RefreshStatusBar()
578
579 #-------------------------------------------------------------------------------
580 #                        Editing Table value function
581 #-------------------------------------------------------------------------------
582
583     def OnSubindexGridCellChange(self, event):
584         if self.Editable:
585             index = self.Table.GetCurrentIndex()
586             subIndex = event.GetRow()
587             col = event.GetCol()
588             name = self.Table.GetColLabelValue(col)
589             value = self.Table.GetValue(subIndex, col)
590             editor = self.Table.GetEditor(subIndex, col)
591             self.Manager.SetCurrentEntry(index, subIndex, value, name, editor)
592             self.Parent.RefreshBufferState()
593             wx.CallAfter(self.RefreshTable)
594         event.Skip()
595
596     def OnCallbackCheck(self, event):
597         if self.Editable:
598             index = self.Table.GetCurrentIndex()
599             self.Manager.SetCurrentEntryCallbacks(index, self.CallbackCheck.GetValue())
600             self.Parent.RefreshBufferState()
601             wx.CallAfter(self.RefreshTable)
602         event.Skip()
603
604 #-------------------------------------------------------------------------------
605 #                          Contextual Menu functions
606 #-------------------------------------------------------------------------------
607
608     def OnIndexListRightUp(self, event):
609         if self.Editable:
610             if not self.FirstCall:
611                 self.FirstCall = True
612                 selected = self.IndexList.GetSelection()
613                 if selected != wx.NOT_FOUND:
614                     index = self.ListIndex[selected]
615                     if index < 0x260:
616                         self.IndexListMenu.FindItemByPosition(0).Enable(False)
617                         self.IndexListMenu.FindItemByPosition(1).Enable(True)
618                         self.PopupMenu(self.IndexListMenu)
619                     elif 0x1000 <= index <= 0x1BFF:
620                         self.IndexListMenu.FindItemByPosition(0).Enable(False)
621                         self.IndexListMenu.FindItemByPosition(1).Enable(False)
622                         self.PopupMenu(self.IndexListMenu)
623                     elif 0x2000 <= index <= 0x5FFF:
624                         self.IndexListMenu.FindItemByPosition(0).Enable(True)
625                         self.IndexListMenu.FindItemByPosition(1).Enable(False)
626                         self.PopupMenu(self.IndexListMenu)
627                     elif index >= 0x6000:
628                         self.IndexListMenu.FindItemByPosition(0).Enable(False)
629                         self.IndexListMenu.FindItemByPosition(1).Enable(False)
630                         self.PopupMenu(self.IndexListMenu)
631             else:
632                 self.FirstCall = False
633         event.Skip()
634
635     def OnSubindexGridRightClick(self, event):
636         if self.Editable:
637             selected = self.IndexList.GetSelection()
638             if selected != wx.NOT_FOUND:
639                 index = self.ListIndex[selected]
640                 if self.Manager.IsCurrentEntry(index):
641                     infos = self.Manager.GetEntryInfos(index)
642                     if index >= 0x2000 and infos["struct"] & OD_MultipleSubindexes or infos["struct"] & OD_IdenticalSubindexes:
643                         self.PopupMenu(self.SubindexGridMenu)
644         event.Skip()
645
646     def OnRenameIndexMenu(self, event):
647         if self.Editable:
648             selected = self.IndexList.GetSelection()
649             if selected != wx.NOT_FOUND:
650                 index = self.ListIndex[selected]
651                 if self.Manager.IsCurrentEntry(index):
652                     infos = self.Manager.GetEntryInfos(index)
653                     dialog = wx.TextEntryDialog(self, "Give a new name for index 0x%04X"%index,
654                                  "Rename an index", infos["name"], wx.OK|wx.CANCEL)
655                     if dialog.ShowModal() == wx.ID_OK:
656                         self.Manager.SetCurrentEntryName(index, dialog.GetValue())
657                         self.Parent.RefreshBufferState()
658                         self.RefreshIndexList()
659                     dialog.Destroy()
660         event.Skip()
661
662     def OnModifyIndexMenu(self, event):
663         if self.Editable:
664             selected = self.IndexList.GetSelection()
665             if selected != wx.NOT_FOUND:
666                 index = self.ListIndex[selected]
667                 if self.Manager.IsCurrentEntry(index) and index < 0x260:
668                     values, valuetype = self.Manager.GetCustomisedTypeValues(index)
669                     dialog = UserTypeDialog(self)
670                     dialog.SetTypeList(self.Manager.GetCustomisableTypes(), values[1])
671                     if valuetype == 0:
672                         dialog.SetValues(min = values[2], max = values[3])
673                     elif valuetype == 1:
674                         dialog.SetValues(length = values[2])
675                     if dialog.ShowModal() == wx.ID_OK:
676                         type, min, max, length = dialog.GetValues()
677                         self.Manager.SetCurrentUserType(index, type, min, max, length)
678                         self.Parent.RefreshBufferState()
679                         self.RefreshIndexList()
680         event.Skip()
681         
682     def OnDeleteIndexMenu(self, event):
683         if self.Editable:
684             selected = self.IndexList.GetSelection()
685             if selected != wx.NOT_FOUND:
686                 index = self.ListIndex[selected]
687                 if self.Manager.IsCurrentEntry(index):
688                     self.Manager.ManageEntriesOfCurrent([],[index])
689                     self.Parent.RefreshBufferState()
690                     self.RefreshIndexList()
691         event.Skip()
692
693     def OnAddSubindexMenu(self, event):
694         if self.Editable:
695             selected = self.IndexList.GetSelection()
696             if selected != wx.NOT_FOUND:
697                 index = self.ListIndex[selected]
698                 if self.Manager.IsCurrentEntry(index):
699                     dialog = wx.TextEntryDialog(self, "Number of subindexes to add:",
700                                  "Add subindexes", "1", wx.OK|wx.CANCEL)
701                     if dialog.ShowModal() == wx.ID_OK:
702                         try:
703                             number = int(dialog.GetValue())
704                             self.Manager.AddSubentriesToCurrent(index, number)
705                             self.Parent.RefreshBufferState()
706                             self.RefreshIndexList()
707                         except:
708                             message = wx.MessageDialog(self, "An integer is required!", "ERROR", wx.OK|wx.ICON_ERROR)
709                             message.ShowModal()
710                             message.Destroy()
711                     dialog.Destroy()
712         event.Skip()
713
714     def OnDeleteSubindexMenu(self, event):
715         if self.Editable:
716             selected = self.IndexList.GetSelection()
717             if selected != wx.NOT_FOUND:
718                 index = self.ListIndex[selected]
719                 if self.Manager.IsCurrentEntry(index):
720                     dialog = wx.TextEntryDialog(self, "Number of subindexes to delete:",
721                                  "Delete subindexes", "1", wx.OK|wx.CANCEL)
722                     if dialog.ShowModal() == wx.ID_OK:
723                         try:
724                             number = int(dialog.GetValue())
725                             self.Manager.RemoveSubentriesFromCurrent(index, number)
726                             self.Parent.RefreshBufferState()
727                             self.RefreshIndexList()
728                         except:
729                             message = wx.MessageDialog(self, "An integer is required!", "ERROR", wx.OK|wx.ICON_ERROR)
730                             message.ShowModal()
731                             message.Destroy()
732                     dialog.Destroy()
733         event.Skip()
734