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