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