1 import wx |
1 import wx |
2 import wx.grid |
2 import wx.grid |
3 import wx.gizmos |
3 import wx.gizmos |
4 |
4 |
5 from controls import CustomGrid, CustomTable, EditorPanel |
5 from controls import CustomGrid, CustomTable, EditorPanel |
6 |
|
7 SCAN_COMMAND = """ |
|
8 import commands |
|
9 result = commands.getoutput("ethercat slaves") |
|
10 slaves = [] |
|
11 for slave_line in result.splitlines(): |
|
12 chunks = slave_line.split() |
|
13 idx, pos, state, flag = chunks[:4] |
|
14 name = " ".join(chunks[4:]) |
|
15 alias, position = pos.split(":") |
|
16 slave = {"idx": int(idx), |
|
17 "alias": int(alias), |
|
18 "position": int(position), |
|
19 "name": name} |
|
20 details = commands.getoutput("ethercat slaves -p %d -v" % slave["idx"]) |
|
21 for details_line in details.splitlines(): |
|
22 details_line = details_line.strip() |
|
23 for header, param in [("Vendor Id:", "vendor_id"), |
|
24 ("Product code:", "product_code"), |
|
25 ("Revision number:", "revision_number")]: |
|
26 if details_line.startswith(header): |
|
27 slave[param] = int(details_line.split()[-1], 16) |
|
28 break |
|
29 slaves.append(slave) |
|
30 returnVal = slaves |
|
31 """ |
|
32 |
6 |
33 [ETHERCAT_VENDOR, ETHERCAT_GROUP, ETHERCAT_DEVICE] = range(3) |
7 [ETHERCAT_VENDOR, ETHERCAT_GROUP, ETHERCAT_DEVICE] = range(3) |
34 |
8 |
35 def AppendMenu(parent, help, id, kind, text): |
9 def AppendMenu(parent, help, id, kind, text): |
36 if wx.VERSION >= (2, 6, 0): |
10 if wx.VERSION >= (2, 6, 0): |
37 parent.Append(help=help, id=id, kind=kind, text=text) |
11 parent.Append(help=help, id=id, kind=kind, text=text) |
38 else: |
12 else: |
39 parent.Append(helpString=help, id=id, kind=kind, item=text) |
13 parent.Append(helpString=help, id=id, kind=kind, item=text) |
40 |
14 |
41 [ID_SLAVETYPECHOICEDIALOG, ID_SLAVETYPECHOICEDIALOGSTATICTEXT1, |
|
42 ID_SLAVETYPECHOICEDIALOGSLAVETYPESLIBRARY |
|
43 ] = [wx.NewId() for _init_ctrls in range(3)] |
|
44 |
|
45 class SlaveTypeChoiceDialog(wx.Dialog): |
|
46 |
|
47 if wx.VERSION < (2, 6, 0): |
|
48 def Bind(self, event, function, id = None): |
|
49 if id is not None: |
|
50 event(self, id, function) |
|
51 else: |
|
52 event(self, function) |
|
53 |
|
54 def _init_coll_flexGridSizer1_Items(self, parent): |
|
55 parent.AddWindow(self.staticText1, 0, border=20, flag=wx.GROW|wx.TOP|wx.LEFT|wx.RIGHT) |
|
56 parent.AddWindow(self.SlaveTypesLibrary, 0, border=20, flag=wx.GROW|wx.LEFT|wx.RIGHT) |
|
57 parent.AddSizer(self.ButtonSizer, 0, border=20, flag=wx.ALIGN_RIGHT|wx.BOTTOM|wx.LEFT|wx.RIGHT) |
|
58 |
|
59 def _init_coll_flexGridSizer1_Growables(self, parent): |
|
60 parent.AddGrowableCol(0) |
|
61 parent.AddGrowableRow(1) |
|
62 |
|
63 def _init_sizers(self): |
|
64 self.flexGridSizer1 = wx.FlexGridSizer(cols=1, hgap=0, rows=3, vgap=10) |
|
65 |
|
66 self._init_coll_flexGridSizer1_Items(self.flexGridSizer1) |
|
67 self._init_coll_flexGridSizer1_Growables(self.flexGridSizer1) |
|
68 |
|
69 self.SetSizer(self.flexGridSizer1) |
|
70 |
|
71 def _init_ctrls(self, prnt): |
|
72 wx.Dialog.__init__(self, id=ID_SLAVETYPECHOICEDIALOG, |
|
73 name='SlaveTypeChoiceDialog', parent=prnt, |
|
74 size=wx.Size(600, 400), style=wx.DEFAULT_DIALOG_STYLE|wx.RESIZE_BORDER, |
|
75 title=_('Browse slave types library')) |
|
76 self.SetClientSize(wx.Size(600, 400)) |
|
77 |
|
78 self.staticText1 = wx.StaticText(id=ID_SLAVETYPECHOICEDIALOGSTATICTEXT1, |
|
79 label=_('Choose a slave type:'), name='staticText1', parent=self, |
|
80 pos=wx.Point(0, 0), size=wx.DefaultSize, style=0) |
|
81 |
|
82 self.SlaveTypesLibrary = wx.TreeCtrl(id=ID_SLAVETYPECHOICEDIALOGSLAVETYPESLIBRARY, |
|
83 name='TypeTree', parent=self, pos=wx.Point(0, 0), |
|
84 size=wx.Size(0, 0), style=wx.TR_HAS_BUTTONS|wx.TR_SINGLE|wx.SUNKEN_BORDER|wx.TR_HIDE_ROOT|wx.TR_LINES_AT_ROOT) |
|
85 |
|
86 self.ButtonSizer = self.CreateButtonSizer(wx.OK|wx.CANCEL|wx.CENTRE) |
|
87 if wx.VERSION >= (2, 5, 0): |
|
88 self.Bind(wx.EVT_BUTTON, self.OnOK, id=self.ButtonSizer.GetAffirmativeButton().GetId()) |
|
89 else: |
|
90 self.Bind(wx.EVT_BUTTON, self.OnOK, id=self.ButtonSizer.GetChildren()[0].GetSizer().GetChildren()[0].GetWindow().GetId()) |
|
91 |
|
92 self._init_sizers() |
|
93 |
|
94 def __init__(self, parent, controler, default=None): |
|
95 self._init_ctrls(parent) |
|
96 |
|
97 slaves_types = controler.GetSlaveTypesLibrary() |
|
98 |
|
99 root = self.SlaveTypesLibrary.AddRoot("") |
|
100 self.GenerateSlaveTypesLibraryTreeBranch(root, slaves_types, default) |
|
101 |
|
102 def GenerateSlaveTypesLibraryTreeBranch(self, root, children, default): |
|
103 for infos in children: |
|
104 item = self.SlaveTypesLibrary.AppendItem(root, infos["name"]) |
|
105 if infos["type"] == ETHERCAT_DEVICE: |
|
106 self.SlaveTypesLibrary.SetPyData(item, infos["infos"]) |
|
107 if infos["infos"] == default: |
|
108 self.SlaveTypesLibrary.SelectItem(item) |
|
109 self.SlaveTypesLibrary.EnsureVisible(item) |
|
110 else: |
|
111 self.GenerateSlaveTypesLibraryTreeBranch(item, infos["children"], default) |
|
112 |
|
113 def GetType(self): |
|
114 selected = self.SlaveTypesLibrary.GetSelection() |
|
115 return self.SlaveTypesLibrary.GetPyData(selected) |
|
116 |
|
117 def OnOK(self, event): |
|
118 selected = self.SlaveTypesLibrary.GetSelection() |
|
119 if not selected.IsOk() or self.SlaveTypesLibrary.GetPyData(selected) is None: |
|
120 message = wx.MessageDialog(self, _("No valid slave type selected!"), _("Error"), wx.OK|wx.ICON_ERROR) |
|
121 message.ShowModal() |
|
122 message.Destroy() |
|
123 else: |
|
124 self.EndModal(wx.ID_OK) |
|
125 |
|
126 def GetSyncManagersTableColnames(): |
15 def GetSyncManagersTableColnames(): |
127 _ = lambda x : x |
16 _ = lambda x : x |
128 return ["#", _("Name"), _("Start Address"), _("Default Size"), _("Control Byte"), _("Enable")] |
17 return ["#", _("Name"), _("Start Address"), _("Default Size"), _("Control Byte"), _("Enable")] |
129 |
18 |
130 class SyncManagersTable(CustomTable): |
19 class SyncManagersTable(CustomTable): |
190 self._init_coll_MainSizer_Growables(self.MainSizer) |
74 self._init_coll_MainSizer_Growables(self.MainSizer) |
191 self._init_coll_MainSizer_Items(self.MainSizer) |
75 self._init_coll_MainSizer_Items(self.MainSizer) |
192 self._init_coll_SlaveInfosDetailsSizer_Growables(self.SlaveInfosDetailsSizer) |
76 self._init_coll_SlaveInfosDetailsSizer_Growables(self.SlaveInfosDetailsSizer) |
193 self._init_coll_SlaveInfosDetailsSizer_Items(self.SlaveInfosDetailsSizer) |
77 self._init_coll_SlaveInfosDetailsSizer_Items(self.SlaveInfosDetailsSizer) |
194 |
78 |
195 self.SetSizer(self.MainSizer) |
79 self.Editor.SetSizer(self.MainSizer) |
196 |
80 |
197 def _init_ctrls(self, prnt): |
81 def _init_Editor(self, prnt): |
198 wx.Panel.__init__(self, id=ID_SLAVEINFOSPANEL, name='SlavePanel', parent=prnt, |
82 self.Editor = wx.Panel(id=-1, name='SlavePanel', parent=prnt, |
199 size=wx.Size(0, 0), style=wx.TAB_TRAVERSAL) |
83 size=wx.Size(0, 0), style=wx.TAB_TRAVERSAL) |
200 |
84 |
201 self.VendorLabel = wx.StaticText(id=ID_SLAVEINFOSPANELVENDORLABEL, |
85 self.VendorLabel = wx.StaticText(id=ID_NODEEDITORVENDORLABEL, |
202 label=_('Vendor:'), name='VendorLabel', parent=self, |
86 label=_('Vendor:'), name='VendorLabel', parent=self.Editor, |
203 pos=wx.Point(0, 0), size=wx.DefaultSize, style=0) |
87 pos=wx.Point(0, 0), size=wx.DefaultSize, style=0) |
204 |
88 |
205 self.Vendor = wx.TextCtrl(id=ID_SLAVEINFOSPANELVENDOR, value='', |
89 self.Vendor = wx.TextCtrl(id=ID_NODEEDITORVENDOR, value='', |
206 name='Vendor', parent=self, pos=wx.Point(0, 0), |
90 name='Vendor', parent=self.Editor, pos=wx.Point(0, 0), |
207 size=wx.Size(0, 24), style=wx.TE_READONLY) |
91 size=wx.Size(0, 24), style=wx.TE_READONLY) |
208 |
92 |
209 self.ProductCodeLabel = wx.StaticText(id=ID_SLAVEINFOSPANELPRODUCTCODELABEL, |
93 self.ProductCodeLabel = wx.StaticText(id=ID_NODEEDITORPRODUCTCODELABEL, |
210 label=_('Product code:'), name='ProductCodeLabel', parent=self, |
94 label=_('Product code:'), name='ProductCodeLabel', parent=self.Editor, |
211 pos=wx.Point(0, 0), size=wx.DefaultSize, style=0) |
95 pos=wx.Point(0, 0), size=wx.DefaultSize, style=0) |
212 |
96 |
213 self.ProductCode = wx.TextCtrl(id=ID_SLAVEINFOSPANELPRODUCTCODE, value='', |
97 self.ProductCode = wx.TextCtrl(id=ID_NODEEDITORPRODUCTCODE, value='', |
214 name='ProductCode', parent=self, pos=wx.Point(0, 0), |
98 name='ProductCode', parent=self.Editor, pos=wx.Point(0, 0), |
215 size=wx.Size(0, 24), style=wx.TE_READONLY) |
99 size=wx.Size(0, 24), style=wx.TE_READONLY) |
216 |
100 |
217 self.RevisionNumberLabel = wx.StaticText(id=ID_SLAVEINFOSPANELREVISIONNUMBERLABEL, |
101 self.RevisionNumberLabel = wx.StaticText(id=ID_NODEEDITORREVISIONNUMBERLABEL, |
218 label=_('Revision number:'), name='RevisionNumberLabel', parent=self, |
102 label=_('Revision number:'), name='RevisionNumberLabel', parent=self.Editor, |
219 pos=wx.Point(0, 0), size=wx.DefaultSize, style=0) |
103 pos=wx.Point(0, 0), size=wx.DefaultSize, style=0) |
220 |
104 |
221 self.RevisionNumber = wx.TextCtrl(id=ID_SLAVEINFOSPANELREVISIONNUMBER, value='', |
105 self.RevisionNumber = wx.TextCtrl(id=ID_NODEEDITORREVISIONNUMBER, value='', |
222 name='RevisionNumber', parent=self, pos=wx.Point(0, 0), |
106 name='RevisionNumber', parent=self.Editor, pos=wx.Point(0, 0), |
223 size=wx.Size(0, 24), style=wx.TE_READONLY) |
107 size=wx.Size(0, 24), style=wx.TE_READONLY) |
224 |
108 |
225 self.PhysicsLabel = wx.StaticText(id=ID_SLAVEINFOSPANELPHYSICSLABEL, |
109 self.PhysicsLabel = wx.StaticText(id=ID_NODEEDITORPHYSICSLABEL, |
226 label=_('Physics:'), name='PhysicsLabel', parent=self, |
110 label=_('Physics:'), name='PhysicsLabel', parent=self.Editor, |
227 pos=wx.Point(0, 0), size=wx.DefaultSize, style=0) |
111 pos=wx.Point(0, 0), size=wx.DefaultSize, style=0) |
228 |
112 |
229 self.Physics = wx.TextCtrl(id=ID_SLAVEINFOSPANELPHYSICS, value='', |
113 self.Physics = wx.TextCtrl(id=ID_NODEEDITORPHYSICS, value='', |
230 name='Physics', parent=self, pos=wx.Point(0, 0), |
114 name='Physics', parent=self.Editor, pos=wx.Point(0, 0), |
231 size=wx.Size(0, 24), style=wx.TE_READONLY) |
115 size=wx.Size(0, 24), style=wx.TE_READONLY) |
232 |
116 |
233 self.SyncManagersLabel = wx.StaticText(id=ID_SLAVEINFOSPANELSYNCMANAGERSLABEL, |
117 self.SyncManagersLabel = wx.StaticText(id=ID_NODEEDITORSYNCMANAGERSLABEL, |
234 label=_('Sync managers:'), name='SyncManagersLabel', parent=self, |
118 label=_('Sync managers:'), name='SyncManagersLabel', parent=self.Editor, |
235 pos=wx.Point(0, 0), size=wx.DefaultSize, style=0) |
119 pos=wx.Point(0, 0), size=wx.DefaultSize, style=0) |
236 |
120 |
237 self.SyncManagersGrid = CustomGrid(id=ID_SLAVEINFOSPANELSYNCMANAGERSGRID, |
121 self.SyncManagersGrid = CustomGrid(id=ID_NODEEDITORSYNCMANAGERSGRID, |
238 name='SyncManagersGrid', parent=self, pos=wx.Point(0, 0), |
122 name='SyncManagersGrid', parent=self.Editor, pos=wx.Point(0, 0), |
239 size=wx.Size(0, 0), style=wx.VSCROLL) |
123 size=wx.Size(0, 0), style=wx.VSCROLL) |
240 |
124 |
241 self.VariablesLabel = wx.StaticText(id=ID_SLAVEINFOSPANELVARIABLESLABEL, |
125 self.VariablesLabel = wx.StaticText(id=ID_NODEEDITORVARIABLESLABEL, |
242 label=_('Variable entries:'), name='VariablesLabel', parent=self, |
126 label=_('Variable entries:'), name='VariablesLabel', parent=self, |
243 pos=wx.Point(0, 0), size=wx.DefaultSize, style=0) |
127 pos=wx.Point(0, 0), size=wx.DefaultSize, style=0) |
244 |
128 |
245 self.VariablesGrid = wx.gizmos.TreeListCtrl(id=ID_SLAVEINFOSPANELVARIABLESGRID, |
129 self.VariablesGrid = wx.gizmos.TreeListCtrl(id=ID_NODEEDITORVARIABLESGRID, |
246 name='VariablesGrid', parent=self, pos=wx.Point(0, 0), |
130 name='VariablesGrid', parent=self.Editor, pos=wx.Point(0, 0), |
247 size=wx.Size(0, 0), style=wx.TR_DEFAULT_STYLE | |
131 size=wx.Size(0, 0), style=wx.TR_DEFAULT_STYLE | |
248 wx.TR_ROW_LINES | |
132 wx.TR_ROW_LINES | |
249 wx.TR_COLUMN_LINES | |
133 wx.TR_COLUMN_LINES | |
250 wx.TR_HIDE_ROOT | |
134 wx.TR_HIDE_ROOT | |
251 wx.TR_FULL_ROW_HIGHLIGHT) |
135 wx.TR_FULL_ROW_HIGHLIGHT) |
252 self.VariablesGrid.GetMainWindow().Bind(wx.EVT_LEFT_DOWN, self.OnVariablesGridLeftClick) |
136 self.VariablesGrid.GetMainWindow().Bind(wx.EVT_LEFT_DOWN, self.OnVariablesGridLeftClick) |
253 |
137 |
254 self._init_sizers() |
138 self._init_sizers() |
255 |
139 |
256 def __init__(self, parent, controler): |
140 def __init__(self, parent, controler, window): |
257 self._init_ctrls(parent) |
141 EditorPanel.__init__(self, parent, "", window, controler) |
258 |
142 |
259 self.Controler = controler |
|
260 self.Slave = None |
|
261 self.Type = None |
|
262 |
|
263 self.SyncManagersTable = SyncManagersTable(self, [], GetSyncManagersTableColnames()) |
143 self.SyncManagersTable = SyncManagersTable(self, [], GetSyncManagersTableColnames()) |
264 self.SyncManagersGrid.SetTable(self.SyncManagersTable) |
144 self.SyncManagersGrid.SetTable(self.SyncManagersTable) |
265 self.SyncManagersGridColAlignements = [wx.ALIGN_RIGHT, wx.ALIGN_LEFT, wx.ALIGN_RIGHT, |
145 self.SyncManagersGridColAlignements = [wx.ALIGN_RIGHT, wx.ALIGN_LEFT, wx.ALIGN_RIGHT, |
266 wx.ALIGN_RIGHT, wx.ALIGN_RIGHT, wx.ALIGN_RIGHT] |
146 wx.ALIGN_RIGHT, wx.ALIGN_RIGHT, wx.ALIGN_RIGHT] |
267 self.SyncManagersGridColSizes = [40, 150, 100, 100, 100, 100] |
147 self.SyncManagersGridColSizes = [40, 150, 100, 100, 100, 100] |
351 if (col == -1 and pdo_mapping != "" and |
242 if (col == -1 and pdo_mapping != "" and |
352 self.Controler.GetSizeOfType(data_type) is not None): |
243 self.Controler.GetSizeOfType(data_type) is not None): |
353 |
244 |
354 entry_index = self.Controler.ExtractHexDecValue(entry.get("Index", "0")) |
245 entry_index = self.Controler.ExtractHexDecValue(entry.get("Index", "0")) |
355 entry_subindex = self.Controler.ExtractHexDecValue(entry.get("SubIndex", "0")) |
246 entry_subindex = self.Controler.ExtractHexDecValue(entry.get("SubIndex", "0")) |
356 var_name = "%s_%4.4x_%2.2x" % (self.Type, entry_index, entry_subindex) |
247 var_name = "%s_%4.4x_%2.2x" % (self.Controler.PlugName(), entry_index, entry_subindex) |
357 if pdo_mapping == "R": |
248 if pdo_mapping == "R": |
358 dir = "%I" |
249 dir = "%I" |
359 else: |
250 else: |
360 dir = "%Q" |
251 dir = "%Q" |
361 location = "%s%s" % (dir, self.Controler.GetSizeOfType(data_type)) + \ |
252 location = "%s%s" % (dir, self.Controler.GetSizeOfType(data_type)) + \ |
362 ".".join(map(lambda x:str(x), self.Controler.GetCurrentLocation() + self.Slave + (entry_index, entry_subindex))) |
253 ".".join(map(lambda x:str(x), self.Controler.GetCurrentLocation() + (self.Controler.GetSlavePos(), entry_index, entry_subindex))) |
363 |
254 |
364 data = wx.TextDataObject(str((location, "location", data_type, var_name, ""))) |
255 data = wx.TextDataObject(str((location, "location", data_type, var_name, ""))) |
365 dragSource = wx.DropSource(self.VariablesGrid) |
256 dragSource = wx.DropSource(self.VariablesGrid) |
366 dragSource.SetData(data) |
257 dragSource.SetData(data) |
367 dragSource.DoDragDrop() |
258 dragSource.DoDragDrop() |
368 |
259 |
369 event.Skip() |
260 event.Skip() |
370 |
261 |
371 [ID_SLAVEPANEL, ID_SLAVEPANELTYPELABEL, |
262 DS402NodeEditor = NodeEditor |
372 ID_SLAVEPANELTYPE, ID_SLAVEPANELTYPEBROWSE, |
|
373 ID_SLAVEPANELALIASLABEL, ID_SLAVEPANELALIAS, |
|
374 ID_SLAVEPANELPOSLABEL, ID_SLAVEPANELPOS, |
|
375 ID_SLAVEPANELSLAVEINFOSSTATICBOX, |
|
376 ] = [wx.NewId() for _init_ctrls in range(9)] |
|
377 |
|
378 class SlavePanel(wx.Panel): |
|
379 |
|
380 if wx.VERSION < (2, 6, 0): |
|
381 def Bind(self, event, function, id = None): |
|
382 if id is not None: |
|
383 event(self, id, function) |
|
384 else: |
|
385 event(self, function) |
|
386 |
|
387 def _init_coll_MainSizer_Items(self, parent): |
|
388 parent.AddSizer(self.PositionSizer, 0, border=5, flag=wx.GROW|wx.TOP|wx.LEFT|wx.RIGHT) |
|
389 parent.AddSizer(self.SlaveInfosBoxSizer, 0, border=5, flag=wx.GROW|wx.ALIGN_RIGHT|wx.LEFT|wx.RIGHT) |
|
390 |
|
391 def _init_coll_MainSizer_Growables(self, parent): |
|
392 parent.AddGrowableCol(0) |
|
393 parent.AddGrowableRow(1) |
|
394 |
|
395 def _init_coll_PositionSizer_Items(self, parent): |
|
396 parent.AddWindow(self.TypeLabel, 0, border=0, flag=wx.ALIGN_CENTER_VERTICAL) |
|
397 parent.AddSizer(self.TypeSizer, 0, border=0, flag=wx.GROW) |
|
398 parent.AddWindow(self.AliasLabel, 0, border=0, flag=wx.ALIGN_CENTER_VERTICAL) |
|
399 parent.AddWindow(self.Alias, 0, border=0, flag=wx.GROW) |
|
400 parent.AddWindow(self.PosLabel, 0, border=0, flag=wx.ALIGN_CENTER_VERTICAL) |
|
401 parent.AddWindow(self.Pos, 0, border=0, flag=wx.GROW) |
|
402 |
|
403 def _init_coll_PositionSizer_Growables(self, parent): |
|
404 parent.AddGrowableCol(1) |
|
405 parent.AddGrowableCol(3) |
|
406 parent.AddGrowableCol(5) |
|
407 parent.AddGrowableRow(0) |
|
408 |
|
409 def _init_coll_TypeSizer_Items(self, parent): |
|
410 parent.AddWindow(self.Type, 1, border=0, flag=0) |
|
411 parent.AddWindow(self.TypeBrowse, 0, border=0, flag=0) |
|
412 |
|
413 def _init_coll_SlaveInfosBoxSizer_Items(self, parent): |
|
414 parent.AddWindow(self.SlaveInfosPanel, 1, border=0, flag=wx.GROW) |
|
415 |
|
416 def _init_sizers(self): |
|
417 self.MainSizer = wx.FlexGridSizer(cols=1, hgap=0, rows=2, vgap=5) |
|
418 self.PositionSizer = wx.FlexGridSizer(cols=6, hgap=5, rows=1, vgap=0) |
|
419 self.TypeSizer = wx.BoxSizer(wx.HORIZONTAL) |
|
420 self.SlaveInfosBoxSizer = wx.StaticBoxSizer(self.SlaveInfosStaticBox, wx.VERTICAL) |
|
421 |
|
422 self._init_coll_MainSizer_Growables(self.MainSizer) |
|
423 self._init_coll_MainSizer_Items(self.MainSizer) |
|
424 self._init_coll_PositionSizer_Growables(self.PositionSizer) |
|
425 self._init_coll_PositionSizer_Items(self.PositionSizer) |
|
426 self._init_coll_TypeSizer_Items(self.TypeSizer) |
|
427 self._init_coll_SlaveInfosBoxSizer_Items(self.SlaveInfosBoxSizer) |
|
428 |
|
429 self.SetSizer(self.MainSizer) |
|
430 |
|
431 def _init_ctrls(self, prnt): |
|
432 wx.Panel.__init__(self, id=ID_SLAVEPANEL, name='SlavePanel', parent=prnt, |
|
433 size=wx.Size(0, 0), style=wx.TAB_TRAVERSAL) |
|
434 |
|
435 self.TypeLabel = wx.StaticText(id=ID_SLAVEPANELTYPELABEL, |
|
436 label=_('Type:'), name='TypeLabel', parent=self, |
|
437 pos=wx.Point(0, 0), size=wx.DefaultSize, style=0) |
|
438 |
|
439 self.Type = wx.TextCtrl(id=ID_SLAVEPANELTYPE, value='', |
|
440 name='Type', parent=self, pos=wx.Point(0, 0), |
|
441 size=wx.Size(0, 24), style=wx.TE_READONLY) |
|
442 |
|
443 self.TypeBrowse = wx.Button(id=ID_SLAVEPANELTYPEBROWSE, label='...', |
|
444 name='TypeBrowse', parent=self, pos=wx.Point(0, 0), |
|
445 size=wx.Size(30, 24), style=0) |
|
446 self.Bind(wx.EVT_BUTTON, self.OnTypeBrowseClick, id=ID_SLAVEPANELTYPEBROWSE) |
|
447 |
|
448 self.AliasLabel = wx.StaticText(id=ID_SLAVEPANELALIASLABEL, |
|
449 label=_('Alias:'), name='AliasLabel', parent=self, |
|
450 pos=wx.Point(0, 0), size=wx.DefaultSize, style=0) |
|
451 |
|
452 self.Alias = wx.SpinCtrl(id=ID_SLAVEPANELALIAS, |
|
453 name='Alias', parent=self, pos=wx.Point(0, 0), |
|
454 size=wx.Size(0, 24), style=wx.SP_ARROW_KEYS, min=0, max=0xffff) |
|
455 self.Bind(wx.EVT_SPINCTRL, self.OnAliasChanged, id=ID_SLAVEPANELALIAS) |
|
456 |
|
457 self.PosLabel = wx.StaticText(id=ID_SLAVEPANELPOSLABEL, |
|
458 label=_('Position:'), name='PositionLabel', parent=self, |
|
459 pos=wx.Point(0, 0), size=wx.DefaultSize, style=0) |
|
460 |
|
461 self.Pos = wx.SpinCtrl(id=ID_SLAVEPANELPOS, |
|
462 name='Pos', parent=self, pos=wx.Point(0, 0), |
|
463 size=wx.Size(0, 24), style=wx.SP_ARROW_KEYS, min=0, max=0xffff) |
|
464 self.Bind(wx.EVT_SPINCTRL, self.OnPositionChanged, id=ID_SLAVEPANELPOS) |
|
465 |
|
466 self.SlaveInfosStaticBox = wx.StaticBox(id=ID_SLAVEPANELSLAVEINFOSSTATICBOX, |
|
467 label=_('Slave infos:'), name='SlaveInfosStaticBox', parent=self, |
|
468 pos=wx.Point(0, 0), size=wx.Size(0, 0), style=0) |
|
469 |
|
470 self.SlaveInfosPanel = SlaveInfosPanel(self, self.Controler) |
|
471 |
|
472 self._init_sizers() |
|
473 |
|
474 def __init__(self, parent, controler, window, slave): |
|
475 self.Controler = controler |
|
476 self.ParentWindow = window |
|
477 self.Slave = slave |
|
478 |
|
479 self._init_ctrls(parent) |
|
480 |
|
481 self.RefreshView() |
|
482 |
|
483 def GetSlaveTitle(self): |
|
484 type_infos = self.Controler.GetSlaveType(self.Slave) |
|
485 return "%s (%d:%d)" % (type_infos["device_type"], self.Slave[0], self.Slave[1]) |
|
486 |
|
487 def GetSlave(self): |
|
488 return self.Slave |
|
489 |
|
490 def SetSlave(self, slave): |
|
491 if self.Slave != slave: |
|
492 self.Slave = slave |
|
493 self.RefreshView() |
|
494 |
|
495 def RefreshView(self): |
|
496 self.Alias.SetValue(self.Slave[0]) |
|
497 self.Pos.SetValue(self.Slave[1]) |
|
498 slave_infos = self.Controler.GetSlaveInfos(self.Slave) |
|
499 if slave_infos is not None: |
|
500 self.Type.SetValue(slave_infos["device_type"]) |
|
501 else: |
|
502 type_infos = self.Controler.GetSlaveType(self.Slave) |
|
503 self.Type.SetValue(type_infos["device_type"]) |
|
504 self.SlaveInfosPanel.SetSlaveInfos(self.Slave, slave_infos) |
|
505 |
|
506 def OnAliasChanged(self, event): |
|
507 alias = self.Alias.GetValue() |
|
508 if alias != self.Slave[0]: |
|
509 result = self.Controler.SetSlavePos(self.Slave[:2], alias = alias) |
|
510 if result is not None: |
|
511 message = wx.MessageDialog(self, result, _("Error"), wx.OK|wx.ICON_ERROR) |
|
512 message.ShowModal() |
|
513 message.Destroy() |
|
514 else: |
|
515 wx.CallAfter(self.ParentWindow.RefreshView, (alias, self.Slave[1])) |
|
516 wx.CallAfter(self.ParentWindow.RefreshParentWindow) |
|
517 event.Skip() |
|
518 |
|
519 def OnPositionChanged(self, event): |
|
520 position = self.Pos.GetValue() |
|
521 if position != self.Slave[1]: |
|
522 result = self.Controler.SetSlavePos(self.Slave, position = position) |
|
523 if result is not None: |
|
524 message = wx.MessageDialog(self, result, _("Error"), wx.OK|wx.ICON_ERROR) |
|
525 message.ShowModal() |
|
526 message.Destroy() |
|
527 else: |
|
528 wx.CallAfter(self.ParentWindow.RefreshView, (self.Slave[0], position)) |
|
529 wx.CallAfter(self.ParentWindow.RefreshParentWindow) |
|
530 event.Skip() |
|
531 |
|
532 def OnTypeBrowseClick(self, event): |
|
533 dialog = SlaveTypeChoiceDialog(self, self.Controler, self.Controler.GetSlaveType(self.Slave)) |
|
534 if dialog.ShowModal() == wx.ID_OK: |
|
535 result = self.Controler.SetSlaveType(self.Slave, dialog.GetType()) |
|
536 if result is not None: |
|
537 message = wx.MessageDialog(self, result, _("Error"), wx.OK|wx.ICON_ERROR) |
|
538 message.ShowModal() |
|
539 message.Destroy() |
|
540 else: |
|
541 wx.CallAfter(self.RefreshView) |
|
542 wx.CallAfter(self.ParentWindow.RefreshSlaveNodesTitles) |
|
543 wx.CallAfter(self.ParentWindow.RefreshParentWindow) |
|
544 dialog.Destroy() |
|
545 event.Skip() |
|
546 |
|
547 [ID_CONFIGEDITOR, ID_CONFIGEDITORSLAVENODES, |
|
548 ] = [wx.NewId() for _init_ctrls in range(2)] |
|
549 |
|
550 [ID_CONFIGEDITORPLUGINMENUSCANNETWORK, ID_CONFIGEDITORPLUGINMENUADDSLAVE, |
|
551 ID_CONFIGEDITORPLUGINMENUDELETESLAVE, |
|
552 ] = [wx.NewId() for _init_coll_PluginMenu_Items in range(3)] |
|
553 |
|
554 class ConfigEditor(EditorPanel): |
|
555 |
|
556 ID = ID_CONFIGEDITOR |
|
557 |
|
558 def _init_coll_MainSizer_Items(self, parent): |
|
559 parent.AddWindow(self.SlaveNodes, 0, border=5, flag=wx.GROW|wx.ALL) |
|
560 |
|
561 def _init_coll_MainSizer_Growables(self, parent): |
|
562 parent.AddGrowableCol(0) |
|
563 parent.AddGrowableRow(0) |
|
564 |
|
565 def _init_sizers(self): |
|
566 self.MainSizer = wx.FlexGridSizer(cols=1, hgap=0, rows=1, vgap=0) |
|
567 |
|
568 self._init_coll_MainSizer_Items(self.MainSizer) |
|
569 self._init_coll_MainSizer_Growables(self.MainSizer) |
|
570 |
|
571 self.Editor.SetSizer(self.MainSizer) |
|
572 |
|
573 def _init_Editor(self, prnt): |
|
574 self.Editor = wx.Panel(id=-1, parent=prnt, pos=wx.Point(0, 0), |
|
575 size=wx.Size(0, 0), style=wx.TAB_TRAVERSAL) |
|
576 |
|
577 self.SlaveNodes = wx.Notebook(id=ID_CONFIGEDITORSLAVENODES, |
|
578 name='SlaveNodes', parent=self.Editor, pos=wx.Point(0, 0), |
|
579 size=wx.Size(0, 0), style=wx.NB_LEFT) |
|
580 |
|
581 self._init_sizers() |
|
582 |
|
583 def _init_MenuItems(self): |
|
584 self.MenuItems = [ |
|
585 (wx.ITEM_NORMAL, (_("Scan network"), ID_CONFIGEDITORPLUGINMENUSCANNETWORK, '', self.OnScanNetworkMenu)), |
|
586 (wx.ITEM_SEPARATOR, None), |
|
587 (wx.ITEM_NORMAL, (_("Add slave"), ID_CONFIGEDITORPLUGINMENUADDSLAVE, '', self.OnAddSlaveMenu)), |
|
588 (wx.ITEM_NORMAL, (_("Delete slave"), ID_CONFIGEDITORPLUGINMENUDELETESLAVE, '', self.OnDeleteSlaveMenu)), |
|
589 ] |
|
590 |
|
591 def __init__(self, parent, controler, window): |
|
592 EditorPanel.__init__(self, parent, "", window, controler) |
|
593 |
|
594 img = wx.Bitmap(self.Controler.GetIconPath("Cfile.png"), wx.BITMAP_TYPE_PNG).ConvertToImage() |
|
595 self.SetIcon(wx.BitmapFromImage(img.Rescale(16, 16))) |
|
596 |
|
597 def __del__(self): |
|
598 self.Controler.OnCloseEditor(self) |
|
599 |
|
600 def GetTitle(self): |
|
601 fullname = self.Controler.PlugFullName() |
|
602 if not self.Controler.ConfigIsSaved(): |
|
603 return "~%s~" % fullname |
|
604 return fullname |
|
605 |
|
606 def GetBufferState(self): |
|
607 return self.Controler.GetBufferState() |
|
608 |
|
609 def Undo(self): |
|
610 self.Controler.LoadPrevious() |
|
611 self.RefreshView() |
|
612 |
|
613 def Redo(self): |
|
614 self.Controler.LoadNext() |
|
615 self.RefreshView() |
|
616 |
|
617 def RefreshView(self, slave_pos=None): |
|
618 slaves = self.Controler.GetSlaves() |
|
619 for i, slave in enumerate(slaves): |
|
620 if i < self.SlaveNodes.GetPageCount(): |
|
621 panel = self.SlaveNodes.GetPage(i) |
|
622 panel.SetSlave(slave) |
|
623 else: |
|
624 panel = SlavePanel(self.SlaveNodes, self.Controler, self, slave) |
|
625 self.SlaveNodes.AddPage(panel, "") |
|
626 while self.SlaveNodes.GetPageCount() > len(slaves): |
|
627 self.SlaveNodes.RemovePage(len(slaves)) |
|
628 self.RefreshSlaveNodesTitles() |
|
629 if slave_pos is not None: |
|
630 self.SelectSlave(slave_pos) |
|
631 |
|
632 def RefreshParentWindow(self): |
|
633 self.ParentWindow.RefreshTitle() |
|
634 self.ParentWindow.RefreshFileMenu() |
|
635 self.ParentWindow.RefreshEditMenu() |
|
636 self.ParentWindow.RefreshPluginMenu() |
|
637 self.ParentWindow.RefreshPageTitles() |
|
638 |
|
639 def RefreshSlaveNodesTitles(self): |
|
640 for idx in xrange(self.SlaveNodes.GetPageCount()): |
|
641 panel = self.SlaveNodes.GetPage(idx) |
|
642 self.SlaveNodes.SetPageText(idx, panel.GetSlaveTitle()) |
|
643 |
|
644 def RefreshPluginMenu(self, plugin_menu): |
|
645 plugin_menu.Enable(ID_CONFIGEDITORPLUGINMENUDELETESLAVE, |
|
646 self.SlaveNodes.GetPageCount() > 0) |
|
647 |
|
648 def SelectSlave(self, slave): |
|
649 for idx in xrange(self.SlaveNodes.GetPageCount()): |
|
650 panel = self.SlaveNodes.GetPage(idx) |
|
651 if panel.GetSlave() == slave: |
|
652 self.SlaveNodes.SetSelection(idx) |
|
653 return |
|
654 |
|
655 def OnScanNetworkMenu(self, event): |
|
656 error, returnVal = self.Controler.RemoteExec(SCAN_COMMAND, returnVal = None) |
|
657 if error != 0: |
|
658 dialog = wx.MessageDialog(self, returnVal, "Error", wx.OK|wx.ICON_ERROR) |
|
659 dialog.ShowModal() |
|
660 dialog.Destroy() |
|
661 elif returnVal is not None: |
|
662 print returnVal |
|
663 wx.CallAfter(self.RefreshView) |
|
664 |
|
665 def OnAddSlaveMenu(self, event): |
|
666 slave = self.Controler.AddSlave() |
|
667 self.RefreshParentWindow() |
|
668 wx.CallAfter(self.RefreshView, slave) |
|
669 |
|
670 def OnDeleteSlaveMenu(self, event): |
|
671 selected = self.SlaveNodes.GetSelection() |
|
672 if selected != -1: |
|
673 panel = self.SlaveNodes.GetPage(selected) |
|
674 if self.Controler.RemoveSlave(panel.GetSlave()[:2]): |
|
675 self.RefreshParentWindow() |
|
676 wx.CallAfter(self.RefreshView) |
|
677 |
|
678 |
|
679 [ID_DS402NODEEDITOR, |
|
680 ] = [wx.NewId() for _init_ctrls in range(1)] |
|
681 |
|
682 class DS402NodeEditor(EditorPanel): |
|
683 |
|
684 ID = ID_DS402NODEEDITOR |
|
685 |
|
686 def _init_Editor(self, prnt): |
|
687 self.Editor = SlaveInfosPanel(prnt, self.Controler) |
|
688 |
|
689 def __init__(self, parent, controler, window): |
|
690 EditorPanel.__init__(self, parent, "", window, controler) |
|
691 |
|
692 img = wx.Bitmap(self.Controler.GetIconPath("Cfile.png"), wx.BITMAP_TYPE_PNG).ConvertToImage() |
|
693 self.SetIcon(wx.BitmapFromImage(img.Rescale(16, 16))) |
|
694 |
|
695 def __del__(self): |
|
696 self.Controler.OnCloseEditor(self) |
|
697 |
|
698 def GetTitle(self): |
|
699 return self.Controler.PlugFullName() |
|
700 |
|
701 def GetBufferState(self): |
|
702 return False, False |
|
703 |
|
704 def RefreshView(self): |
|
705 self.Editor.SetSlaveInfos(self.Controler.GetSlavePos(), self.Controler.GetSlaveInfos()) |
|
706 |
|