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