|
1 import wx |
|
2 |
|
3 from controls import CustomGrid, CustomTable, EditorPanel |
|
4 |
|
5 [ETHERCAT_VENDOR, ETHERCAT_GROUP, ETHERCAT_DEVICE] = range(3) |
|
6 |
|
7 def AppendMenu(parent, help, id, kind, text): |
|
8 if wx.VERSION >= (2, 6, 0): |
|
9 parent.Append(help=help, id=id, kind=kind, text=text) |
|
10 else: |
|
11 parent.Append(helpString=help, id=id, kind=kind, item=text) |
|
12 |
|
13 [ID_SLAVETYPECHOICEDIALOG, ID_SLAVETYPECHOICEDIALOGSTATICTEXT1, |
|
14 ID_SLAVETYPECHOICEDIALOGSLAVETYPESLIBRARY |
|
15 ] = [wx.NewId() for _init_ctrls in range(3)] |
|
16 |
|
17 class SlaveTypeChoiceDialog(wx.Dialog): |
|
18 |
|
19 if wx.VERSION < (2, 6, 0): |
|
20 def Bind(self, event, function, id = None): |
|
21 if id is not None: |
|
22 event(self, id, function) |
|
23 else: |
|
24 event(self, function) |
|
25 |
|
26 def _init_coll_flexGridSizer1_Items(self, parent): |
|
27 parent.AddWindow(self.staticText1, 0, border=20, flag=wx.GROW|wx.TOP|wx.LEFT|wx.RIGHT) |
|
28 parent.AddWindow(self.SlaveTypesLibrary, 0, border=20, flag=wx.GROW|wx.LEFT|wx.RIGHT) |
|
29 parent.AddSizer(self.ButtonSizer, 0, border=20, flag=wx.ALIGN_RIGHT|wx.BOTTOM|wx.LEFT|wx.RIGHT) |
|
30 |
|
31 def _init_coll_flexGridSizer1_Growables(self, parent): |
|
32 parent.AddGrowableCol(0) |
|
33 parent.AddGrowableRow(1) |
|
34 |
|
35 def _init_sizers(self): |
|
36 self.flexGridSizer1 = wx.FlexGridSizer(cols=1, hgap=0, rows=3, vgap=10) |
|
37 |
|
38 self._init_coll_flexGridSizer1_Items(self.flexGridSizer1) |
|
39 self._init_coll_flexGridSizer1_Growables(self.flexGridSizer1) |
|
40 |
|
41 self.SetSizer(self.flexGridSizer1) |
|
42 |
|
43 def _init_ctrls(self, prnt): |
|
44 wx.Dialog.__init__(self, id=ID_SLAVETYPECHOICEDIALOG, |
|
45 name='SlaveTypeChoiceDialog', parent=prnt, |
|
46 size=wx.Size(600, 400), style=wx.DEFAULT_DIALOG_STYLE|wx.RESIZE_BORDER, |
|
47 title=_('Browse slave types library')) |
|
48 self.SetClientSize(wx.Size(600, 400)) |
|
49 |
|
50 self.staticText1 = wx.StaticText(id=ID_SLAVETYPECHOICEDIALOGSTATICTEXT1, |
|
51 label=_('Choose a slave type:'), name='staticText1', parent=self, |
|
52 pos=wx.Point(0, 0), size=wx.DefaultSize, style=0) |
|
53 |
|
54 self.SlaveTypesLibrary = wx.TreeCtrl(id=ID_SLAVETYPECHOICEDIALOGSLAVETYPESLIBRARY, |
|
55 name='TypeTree', parent=self, pos=wx.Point(0, 0), |
|
56 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) |
|
57 |
|
58 self.ButtonSizer = self.CreateButtonSizer(wx.OK|wx.CANCEL|wx.CENTRE) |
|
59 if wx.VERSION >= (2, 5, 0): |
|
60 self.Bind(wx.EVT_BUTTON, self.OnOK, id=self.ButtonSizer.GetAffirmativeButton().GetId()) |
|
61 else: |
|
62 self.Bind(wx.EVT_BUTTON, self.OnOK, id=self.ButtonSizer.GetChildren()[0].GetSizer().GetChildren()[0].GetWindow().GetId()) |
|
63 |
|
64 self._init_sizers() |
|
65 |
|
66 def __init__(self, parent, controler, default=None): |
|
67 self._init_ctrls(parent) |
|
68 |
|
69 slaves_types = controler.GetSlaveTypesLibrary() |
|
70 |
|
71 root = self.SlaveTypesLibrary.AddRoot("") |
|
72 self.GenerateSlaveTypesLibraryTreeBranch(root, slaves_types, default) |
|
73 |
|
74 def GenerateSlaveTypesLibraryTreeBranch(self, root, children, default): |
|
75 for infos in children: |
|
76 item = self.SlaveTypesLibrary.AppendItem(root, infos["name"]) |
|
77 if infos["type"] == ETHERCAT_DEVICE: |
|
78 self.SlaveTypesLibrary.SetPyData(item, infos["infos"]) |
|
79 if infos["infos"] == default: |
|
80 self.SlaveTypesLibrary.SelectItem(item) |
|
81 self.SlaveTypesLibrary.EnsureVisible(item) |
|
82 else: |
|
83 self.GenerateSlaveTypesLibraryTreeBranch(item, infos["children"], default) |
|
84 |
|
85 def GetType(self): |
|
86 selected = self.SlaveTypesLibrary.GetSelection() |
|
87 return self.SlaveTypesLibrary.GetPyData(selected) |
|
88 |
|
89 def OnOK(self, event): |
|
90 selected = self.SlaveTypesLibrary.GetSelection() |
|
91 if not selected.IsOk() or self.SlaveTypesLibrary.GetPyData(selected) is None: |
|
92 message = wx.MessageDialog(self, _("No valid slave type selected!"), _("Error"), wx.OK|wx.ICON_ERROR) |
|
93 message.ShowModal() |
|
94 message.Destroy() |
|
95 else: |
|
96 self.EndModal(wx.ID_OK) |
|
97 |
|
98 |
|
99 def GetPDOsTableColnames(): |
|
100 _ = lambda x : x |
|
101 return ["#", _("Index"), _("Name"), _("Type")] |
|
102 |
|
103 def GetVariablesTableColnames(): |
|
104 _ = lambda x : x |
|
105 return ["#", _("Index"), _("SubIndex"), _("Name"), _("Type"), _("PDO")] |
|
106 |
|
107 class PDOsTable(CustomTable): |
|
108 |
|
109 def GetValue(self, row, col): |
|
110 if row < self.GetNumberRows(): |
|
111 if col == 0: |
|
112 return row + 1 |
|
113 colname = self.GetColLabelValue(col, False) |
|
114 value = self.data[row].get(colname, "") |
|
115 if colname == "Type": |
|
116 value = _(value) |
|
117 return value |
|
118 |
|
119 class VariablesTable(CustomTable): |
|
120 |
|
121 def GetValue(self, row, col): |
|
122 if row < self.GetNumberRows(): |
|
123 if col == 0: |
|
124 return row + 1 |
|
125 return self.data[row].get(self.GetColLabelValue(col, False), "") |
|
126 |
|
127 [ID_SLAVEPANEL, ID_SLAVEPANELTYPELABEL, |
|
128 ID_SLAVEPANELTYPE, ID_SLAVEPANELTYPEBROWSE, |
|
129 ID_SLAVEPANELALIASLABEL, ID_SLAVEPANELALIAS, |
|
130 ID_SLAVEPANELPOSLABEL, ID_SLAVEPANELPOS, |
|
131 ID_SLAVEPANELSLAVEINFOSSTATICBOX, ID_SLAVEPANELVENDORLABEL, |
|
132 ID_SLAVEPANELVENDOR, ID_SLAVEPANELPRODUCTCODELABEL, |
|
133 ID_SLAVEPANELPRODUCTCODE, ID_SLAVEPANELREVISIONNUMBERLABEL, |
|
134 ID_SLAVEPANELREVISIONNUMBER, ID_SLAVEPANELPHYSICSLABEL, |
|
135 ID_SLAVEPANELPHYSICS, ID_SLAVEPANELPDOSLABEL, |
|
136 ID_SLAVEPANELPDOSGRID, ID_SLAVEPANELVARIABLESLABEL, |
|
137 ID_SLAVEPANELVARIABLESGRID, |
|
138 ] = [wx.NewId() for _init_ctrls in range(21)] |
|
139 |
|
140 class SlavePanel(wx.Panel): |
|
141 |
|
142 if wx.VERSION < (2, 6, 0): |
|
143 def Bind(self, event, function, id = None): |
|
144 if id is not None: |
|
145 event(self, id, function) |
|
146 else: |
|
147 event(self, function) |
|
148 |
|
149 def _init_coll_MainSizer_Items(self, parent): |
|
150 parent.AddSizer(self.PositionSizer, 0, border=5, flag=wx.GROW|wx.TOP|wx.LEFT|wx.RIGHT) |
|
151 parent.AddSizer(self.SlaveInfosBoxSizer, 0, border=5, flag=wx.GROW|wx.ALIGN_RIGHT|wx.LEFT|wx.RIGHT) |
|
152 |
|
153 def _init_coll_MainSizer_Growables(self, parent): |
|
154 parent.AddGrowableCol(0) |
|
155 parent.AddGrowableRow(1) |
|
156 |
|
157 def _init_coll_PositionSizer_Items(self, parent): |
|
158 parent.AddWindow(self.TypeLabel, 0, border=0, flag=wx.ALIGN_CENTER_VERTICAL) |
|
159 parent.AddSizer(self.TypeSizer, 0, border=0, flag=wx.GROW) |
|
160 parent.AddWindow(self.AliasLabel, 0, border=0, flag=wx.ALIGN_CENTER_VERTICAL) |
|
161 parent.AddWindow(self.Alias, 0, border=0, flag=wx.GROW) |
|
162 parent.AddWindow(self.PosLabel, 0, border=0, flag=wx.ALIGN_CENTER_VERTICAL) |
|
163 parent.AddWindow(self.Pos, 0, border=0, flag=wx.GROW) |
|
164 |
|
165 def _init_coll_PositionSizer_Growables(self, parent): |
|
166 parent.AddGrowableCol(1) |
|
167 parent.AddGrowableCol(3) |
|
168 parent.AddGrowableCol(5) |
|
169 parent.AddGrowableRow(0) |
|
170 |
|
171 def _init_coll_TypeSizer_Items(self, parent): |
|
172 parent.AddWindow(self.Type, 1, border=0, flag=0) |
|
173 parent.AddWindow(self.TypeBrowse, 0, border=0, flag=0) |
|
174 |
|
175 def _init_coll_SlaveInfosBoxSizer_Items(self, parent): |
|
176 parent.AddSizer(self.SlaveInfosSizer, 1, border=5, flag=wx.GROW|wx.ALL) |
|
177 |
|
178 def _init_coll_SlaveInfosSizer_Items(self, parent): |
|
179 parent.AddSizer(self.SlaveInfosDetailsSizer, 0, border=0, flag=wx.GROW) |
|
180 parent.AddWindow(self.PDOsLabel, 0, border=0, flag=wx.GROW) |
|
181 parent.AddWindow(self.PDOsGrid, 0, border=0, flag=wx.GROW) |
|
182 parent.AddWindow(self.VariablesLabel, 0, border=0, flag=wx.GROW) |
|
183 parent.AddWindow(self.VariablesGrid, 0, border=0, flag=wx.GROW) |
|
184 |
|
185 def _init_coll_SlaveInfosSizer_Growables(self, parent): |
|
186 parent.AddGrowableCol(0) |
|
187 parent.AddGrowableRow(2) |
|
188 parent.AddGrowableRow(4) |
|
189 |
|
190 def _init_coll_SlaveInfosDetailsSizer_Items(self, parent): |
|
191 parent.AddWindow(self.VendorLabel, 0, border=0, flag=wx.ALIGN_CENTER_VERTICAL|wx.GROW) |
|
192 parent.AddWindow(self.Vendor, 0, border=0, flag=wx.GROW) |
|
193 parent.AddWindow(self.ProductCodeLabel, 0, border=0, flag=wx.ALIGN_CENTER_VERTICAL|wx.GROW) |
|
194 parent.AddWindow(self.ProductCode, 0, border=0, flag=wx.GROW) |
|
195 parent.AddWindow(self.RevisionNumberLabel, 0, border=0, flag=wx.ALIGN_CENTER_VERTICAL|wx.GROW) |
|
196 parent.AddWindow(self.RevisionNumber, 0, border=0, flag=wx.GROW) |
|
197 parent.AddWindow(self.PhysicsLabel, 0, border=0, flag=wx.ALIGN_CENTER_VERTICAL|wx.GROW) |
|
198 parent.AddWindow(self.Physics, 0, border=0, flag=wx.GROW) |
|
199 |
|
200 def _init_coll_SlaveInfosDetailsSizer_Growables(self, parent): |
|
201 parent.AddGrowableCol(1) |
|
202 parent.AddGrowableCol(3) |
|
203 |
|
204 def _init_sizers(self): |
|
205 self.MainSizer = wx.FlexGridSizer(cols=1, hgap=0, rows=2, vgap=5) |
|
206 self.PositionSizer = wx.FlexGridSizer(cols=6, hgap=5, rows=1, vgap=0) |
|
207 self.TypeSizer = wx.BoxSizer(wx.HORIZONTAL) |
|
208 self.SlaveInfosBoxSizer = wx.StaticBoxSizer(self.SlaveInfosStaticBox, wx.VERTICAL) |
|
209 self.SlaveInfosSizer = wx.FlexGridSizer(cols=1, hgap=0, rows=5, vgap=5) |
|
210 self.SlaveInfosDetailsSizer = wx.FlexGridSizer(cols=4, hgap=5, rows=2, vgap=5) |
|
211 |
|
212 self._init_coll_MainSizer_Growables(self.MainSizer) |
|
213 self._init_coll_MainSizer_Items(self.MainSizer) |
|
214 self._init_coll_PositionSizer_Growables(self.PositionSizer) |
|
215 self._init_coll_PositionSizer_Items(self.PositionSizer) |
|
216 self._init_coll_TypeSizer_Items(self.TypeSizer) |
|
217 self._init_coll_SlaveInfosBoxSizer_Items(self.SlaveInfosBoxSizer) |
|
218 self._init_coll_SlaveInfosSizer_Growables(self.SlaveInfosSizer) |
|
219 self._init_coll_SlaveInfosSizer_Items(self.SlaveInfosSizer) |
|
220 self._init_coll_SlaveInfosDetailsSizer_Growables(self.SlaveInfosDetailsSizer) |
|
221 self._init_coll_SlaveInfosDetailsSizer_Items(self.SlaveInfosDetailsSizer) |
|
222 |
|
223 self.SetSizer(self.MainSizer) |
|
224 |
|
225 def _init_ctrls(self, prnt): |
|
226 wx.Panel.__init__(self, id=ID_SLAVEPANEL, name='SlavePanel', parent=prnt, |
|
227 size=wx.Size(0, 0), style=wx.TAB_TRAVERSAL) |
|
228 |
|
229 self.TypeLabel = wx.StaticText(id=ID_SLAVEPANELTYPELABEL, |
|
230 label=_('Type:'), name='TypeLabel', parent=self, |
|
231 pos=wx.Point(0, 0), size=wx.DefaultSize, style=0) |
|
232 |
|
233 self.Type = wx.TextCtrl(id=ID_SLAVEPANELTYPE, value='', |
|
234 name='Type', parent=self, pos=wx.Point(0, 0), |
|
235 size=wx.Size(0, 24), style=wx.TE_READONLY) |
|
236 |
|
237 self.TypeBrowse = wx.Button(id=ID_SLAVEPANELTYPEBROWSE, label='...', |
|
238 name='TypeBrowse', parent=self, pos=wx.Point(0, 0), |
|
239 size=wx.Size(30, 24), style=0) |
|
240 self.Bind(wx.EVT_BUTTON, self.OnTypeBrowseClick, id=ID_SLAVEPANELTYPEBROWSE) |
|
241 |
|
242 self.AliasLabel = wx.StaticText(id=ID_SLAVEPANELALIASLABEL, |
|
243 label=_('Alias:'), name='AliasLabel', parent=self, |
|
244 pos=wx.Point(0, 0), size=wx.DefaultSize, style=0) |
|
245 |
|
246 self.Alias = wx.SpinCtrl(id=ID_SLAVEPANELALIAS, |
|
247 name='Alias', parent=self, pos=wx.Point(0, 0), |
|
248 size=wx.Size(0, 24), style=wx.SP_ARROW_KEYS, min=0, max=0xffff) |
|
249 self.Bind(wx.EVT_SPINCTRL, self.OnAliasChanged, id=ID_SLAVEPANELALIAS) |
|
250 |
|
251 self.PosLabel = wx.StaticText(id=ID_SLAVEPANELPOSLABEL, |
|
252 label=_('Position:'), name='PositionLabel', parent=self, |
|
253 pos=wx.Point(0, 0), size=wx.DefaultSize, style=0) |
|
254 |
|
255 self.Pos = wx.SpinCtrl(id=ID_SLAVEPANELPOS, |
|
256 name='Pos', parent=self, pos=wx.Point(0, 0), |
|
257 size=wx.Size(0, 24), style=wx.SP_ARROW_KEYS, min=0, max=0xffff) |
|
258 self.Bind(wx.EVT_SPINCTRL, self.OnPositionChanged, id=ID_SLAVEPANELPOS) |
|
259 |
|
260 self.SlaveInfosStaticBox = wx.StaticBox(id=ID_SLAVEPANELSLAVEINFOSSTATICBOX, |
|
261 label=_('Slave infos:'), name='SlaveInfosStaticBox', parent=self, |
|
262 pos=wx.Point(0, 0), size=wx.Size(0, 0), style=0) |
|
263 |
|
264 self.VendorLabel = wx.StaticText(id=ID_SLAVEPANELVENDORLABEL, |
|
265 label=_('Vendor:'), name='VendorLabel', parent=self, |
|
266 pos=wx.Point(0, 0), size=wx.DefaultSize, style=0) |
|
267 |
|
268 self.Vendor = wx.TextCtrl(id=ID_SLAVEPANELVENDOR, value='', |
|
269 name='Vendor', parent=self, pos=wx.Point(0, 0), |
|
270 size=wx.Size(0, 24), style=wx.TE_READONLY) |
|
271 |
|
272 self.ProductCodeLabel = wx.StaticText(id=ID_SLAVEPANELPRODUCTCODELABEL, |
|
273 label=_('Product code:'), name='ProductCodeLabel', parent=self, |
|
274 pos=wx.Point(0, 0), size=wx.DefaultSize, style=0) |
|
275 |
|
276 self.ProductCode = wx.TextCtrl(id=ID_SLAVEPANELPRODUCTCODE, value='', |
|
277 name='ProductCode', parent=self, pos=wx.Point(0, 0), |
|
278 size=wx.Size(0, 24), style=wx.TE_READONLY) |
|
279 |
|
280 self.RevisionNumberLabel = wx.StaticText(id=ID_SLAVEPANELREVISIONNUMBERLABEL, |
|
281 label=_('Revision number:'), name='RevisionNumberLabel', parent=self, |
|
282 pos=wx.Point(0, 0), size=wx.DefaultSize, style=0) |
|
283 |
|
284 self.RevisionNumber = wx.TextCtrl(id=ID_SLAVEPANELREVISIONNUMBER, value='', |
|
285 name='RevisionNumber', parent=self, pos=wx.Point(0, 0), |
|
286 size=wx.Size(0, 24), style=wx.TE_READONLY) |
|
287 |
|
288 self.PhysicsLabel = wx.StaticText(id=ID_SLAVEPANELPHYSICSLABEL, |
|
289 label=_('Physics:'), name='PhysicsLabel', parent=self, |
|
290 pos=wx.Point(0, 0), size=wx.DefaultSize, style=0) |
|
291 |
|
292 self.Physics = wx.TextCtrl(id=ID_SLAVEPANELPHYSICS, value='', |
|
293 name='Physics', parent=self, pos=wx.Point(0, 0), |
|
294 size=wx.Size(0, 24), style=wx.TE_READONLY) |
|
295 |
|
296 self.PDOsLabel = wx.StaticText(id=ID_SLAVEPANELPDOSLABEL, |
|
297 label=_('PDO entries:'), name='PDOsLabel', parent=self, |
|
298 pos=wx.Point(0, 0), size=wx.DefaultSize, style=0) |
|
299 |
|
300 self.PDOsGrid = CustomGrid(id=ID_SLAVEPANELPDOSGRID, |
|
301 name='PDOsGrid', parent=self, pos=wx.Point(0, 0), |
|
302 size=wx.Size(0, 0), style=wx.VSCROLL) |
|
303 |
|
304 self.VariablesLabel = wx.StaticText(id=ID_SLAVEPANELVARIABLESLABEL, |
|
305 label=_('Variable entries:'), name='VariablesLabel', parent=self, |
|
306 pos=wx.Point(0, 0), size=wx.DefaultSize, style=0) |
|
307 |
|
308 self.VariablesGrid = CustomGrid(id=ID_SLAVEPANELPDOSGRID, |
|
309 name='PDOsGrid', parent=self, pos=wx.Point(0, 0), |
|
310 size=wx.Size(0, 0), style=wx.VSCROLL) |
|
311 if wx.VERSION >= (2, 5, 0): |
|
312 self.VariablesGrid.Bind(wx.grid.EVT_GRID_CELL_LEFT_CLICK, self.OnVariablesGridCellLeftClick) |
|
313 else: |
|
314 wx.grid.EVT_GRID_CELL_LEFT_CLICK(self.VariablesGrid, self.OnVariablesGridCellLeftClick) |
|
315 |
|
316 self._init_sizers() |
|
317 |
|
318 def __init__(self, parent, controler, window, slave): |
|
319 self._init_ctrls(parent) |
|
320 |
|
321 self.Controler = controler |
|
322 self.ParentWindow = window |
|
323 self.Slave = slave |
|
324 |
|
325 self.PDOsTable = PDOsTable(self, [], GetPDOsTableColnames()) |
|
326 self.PDOsGrid.SetTable(self.PDOsTable) |
|
327 self.PDOsGridColAlignements = [wx.ALIGN_RIGHT, wx.ALIGN_RIGHT, wx.ALIGN_LEFT, wx.ALIGN_LEFT] |
|
328 self.PDOsGridColSizes = [40, 100, 150, 150] |
|
329 self.PDOsGrid.SetRowLabelSize(0) |
|
330 for col in range(self.PDOsTable.GetNumberCols()): |
|
331 attr = wx.grid.GridCellAttr() |
|
332 attr.SetAlignment(self.PDOsGridColAlignements[col], wx.ALIGN_CENTRE) |
|
333 self.PDOsGrid.SetColAttr(col, attr) |
|
334 self.PDOsGrid.SetColMinimalWidth(col, self.PDOsGridColSizes[col]) |
|
335 self.PDOsGrid.AutoSizeColumn(col, False) |
|
336 |
|
337 self.VariablesTable = VariablesTable(self, [], GetVariablesTableColnames()) |
|
338 self.VariablesGrid.SetTable(self.VariablesTable) |
|
339 self.VariablesGridColAlignements = [wx.ALIGN_RIGHT, wx.ALIGN_RIGHT, wx.ALIGN_RIGHT, wx.ALIGN_LEFT, wx.ALIGN_LEFT, wx.ALIGN_RIGHT] |
|
340 self.VariablesGridColSizes = [40, 100, 100, 150, 150, 100] |
|
341 self.VariablesGrid.SetRowLabelSize(0) |
|
342 for col in range(self.VariablesTable.GetNumberCols()): |
|
343 attr = wx.grid.GridCellAttr() |
|
344 attr.SetAlignment(self.VariablesGridColAlignements[col], wx.ALIGN_CENTRE) |
|
345 self.VariablesGrid.SetColAttr(col, attr) |
|
346 self.VariablesGrid.SetColMinimalWidth(col, self.VariablesGridColSizes[col]) |
|
347 self.VariablesGrid.AutoSizeColumn(col, False) |
|
348 |
|
349 self.RefreshView() |
|
350 |
|
351 def GetSlaveTitle(self): |
|
352 type_infos = self.Controler.GetSlaveType(self.Slave) |
|
353 return "%s (%d:%d)" % (type_infos["device_type"], self.Slave[0], self.Slave[1]) |
|
354 |
|
355 def GetSlave(self): |
|
356 return self.Slave |
|
357 |
|
358 def SetSlave(self, slave): |
|
359 if self.Slave != slave: |
|
360 self.Slave = slave |
|
361 self.RefreshView() |
|
362 |
|
363 def RefreshView(self): |
|
364 self.Alias.SetValue(self.Slave[0]) |
|
365 self.Pos.SetValue(self.Slave[1]) |
|
366 slave_infos = self.Controler.GetSlaveInfos(self.Slave) |
|
367 if slave_infos is not None: |
|
368 self.Type.SetValue(slave_infos["device_type"]) |
|
369 self.Vendor.SetValue(slave_infos["vendor"]) |
|
370 self.ProductCode.SetValue(slave_infos["product_code"]) |
|
371 self.RevisionNumber.SetValue(slave_infos["revision_number"]) |
|
372 self.Physics.SetValue(slave_infos["physics"]) |
|
373 self.PDOsTable.SetData(slave_infos["pdos"]) |
|
374 self.PDOsTable.ResetView(self.PDOsGrid) |
|
375 self.VariablesTable.SetData(slave_infos["variables"]) |
|
376 self.VariablesTable.ResetView(self.VariablesGrid) |
|
377 else: |
|
378 type_infos = self.Controler.GetSlaveType(self.Slave) |
|
379 self.Type.SetValue(type_infos["device_type"]) |
|
380 |
|
381 def OnAliasChanged(self, event): |
|
382 alias = self.Alias.GetValue() |
|
383 if alias != self.Slave[0]: |
|
384 result = self.Controler.SetSlavePos(self.Slave[:2], alias = alias) |
|
385 if result is not None: |
|
386 message = wx.MessageDialog(self, result, _("Error"), wx.OK|wx.ICON_ERROR) |
|
387 message.ShowModal() |
|
388 message.Destroy() |
|
389 else: |
|
390 wx.CallAfter(self.ParentWindow.RefreshView, (alias, self.Slave[1])) |
|
391 wx.CallAfter(self.ParentWindow.RefreshParentWindow) |
|
392 event.Skip() |
|
393 |
|
394 def OnPositionChanged(self, event): |
|
395 position = self.Pos.GetValue() |
|
396 if position != self.Slave[1]: |
|
397 result = self.Controler.SetSlavePos(self.Slave, position = position) |
|
398 if result is not None: |
|
399 message = wx.MessageDialog(self, result, _("Error"), wx.OK|wx.ICON_ERROR) |
|
400 message.ShowModal() |
|
401 message.Destroy() |
|
402 else: |
|
403 wx.CallAfter(self.ParentWindow.RefreshView, (self.Slave[0], position)) |
|
404 wx.CallAfter(self.ParentWindow.RefreshParentWindow) |
|
405 event.Skip() |
|
406 |
|
407 def OnTypeBrowseClick(self, event): |
|
408 dialog = SlaveTypeChoiceDialog(self, self.Controler, self.Controler.GetSlaveType(self.Slave)) |
|
409 if dialog.ShowModal() == wx.ID_OK: |
|
410 result = self.Controler.SetSlaveType(self.Slave, dialog.GetType()) |
|
411 if result is not None: |
|
412 message = wx.MessageDialog(self, result, _("Error"), wx.OK|wx.ICON_ERROR) |
|
413 message.ShowModal() |
|
414 message.Destroy() |
|
415 else: |
|
416 wx.CallAfter(self.RefreshView) |
|
417 wx.CallAfter(self.ParentWindow.RefreshSlaveNodesTitles) |
|
418 wx.CallAfter(self.ParentWindow.RefreshParentWindow) |
|
419 dialog.Destroy() |
|
420 event.Skip() |
|
421 |
|
422 def OnVariablesGridCellLeftClick(self, event): |
|
423 if event.GetCol() == 0: |
|
424 row = event.GetRow() |
|
425 data_type = self.VariablesTable.GetValueByName(row, "Type") |
|
426 var_name = self.VariablesTable.GetValueByName(row, "Name") |
|
427 entry_index = self.Controler.ExtractHexDecValue(self.VariablesTable.GetValueByName(row, "Index")) |
|
428 entry_subindex = self.VariablesTable.GetValueByName(row, "SubIndex") |
|
429 pdo_index = self.VariablesTable.GetValueByName(row, "PDO") |
|
430 for pdo_row in xrange(self.PDOsTable.GetNumberRows()): |
|
431 if self.PDOsTable.GetValueByName(row, "Index") == pdo_index: |
|
432 if self.PDOsTable.GetValueByName(row, "Type") == "Transmit": |
|
433 dir = "%I" |
|
434 else: |
|
435 dir = "%Q" |
|
436 break |
|
437 location = "%s%s" % (dir, self.Controler.GetSizeOfType(data_type)) + \ |
|
438 ".".join(map(lambda x:str(x), self.Controler.GetCurrentLocation() + self.Slave + (entry_index, entry_subindex))) |
|
439 data = wx.TextDataObject(str((location, "location", data_type, var_name, ""))) |
|
440 dragSource = wx.DropSource(self.VariablesGrid) |
|
441 dragSource.SetData(data) |
|
442 dragSource.DoDragDrop() |
|
443 event.Skip() |
|
444 |
|
445 [ID_CONFIGEDITOR, ID_CONFIGEDITORADDSLAVEBUTTON, |
|
446 ID_CONFIGEDITORDELETESLAVEBUTTON, ID_CONFIGEDITORSLAVENODES, |
|
447 ] = [wx.NewId() for _init_ctrls in range(4)] |
|
448 |
|
449 class ConfigEditor(EditorPanel): |
|
450 |
|
451 ID = ID_CONFIGEDITOR |
|
452 |
|
453 def _init_coll_MainSizer_Items(self, parent): |
|
454 parent.AddSizer(self.ButtonSizer, 0, border=5, flag=wx.ALIGN_RIGHT|wx.TOP|wx.LEFT|wx.RIGHT) |
|
455 parent.AddWindow(self.SlaveNodes, 0, border=5, flag=wx.GROW|wx.BOTTOM|wx.LEFT|wx.RIGHT) |
|
456 |
|
457 def _init_coll_MainSizer_Growables(self, parent): |
|
458 parent.AddGrowableCol(0) |
|
459 parent.AddGrowableRow(1) |
|
460 |
|
461 def _init_coll_ButtonSizer_Items(self, parent): |
|
462 parent.AddWindow(self.AddSlaveButton, 0, border=5, flag=wx.RIGHT) |
|
463 parent.AddWindow(self.DeleteSlaveButton, 0, border=5, flag=0) |
|
464 |
|
465 def _init_sizers(self): |
|
466 self.MainSizer = wx.FlexGridSizer(cols=1, hgap=0, rows=2, vgap=10) |
|
467 self.ButtonSizer = wx.BoxSizer(wx.HORIZONTAL) |
|
468 |
|
469 self._init_coll_MainSizer_Items(self.MainSizer) |
|
470 self._init_coll_MainSizer_Growables(self.MainSizer) |
|
471 self._init_coll_ButtonSizer_Items(self.ButtonSizer) |
|
472 |
|
473 self.Editor.SetSizer(self.MainSizer) |
|
474 |
|
475 def _init_Editor(self, prnt): |
|
476 self.Editor = wx.Panel(id=-1, parent=prnt, pos=wx.Point(0, 0), |
|
477 size=wx.Size(0, 0), style=wx.TAB_TRAVERSAL) |
|
478 |
|
479 self.AddSlaveButton = wx.Button(id=ID_CONFIGEDITORADDSLAVEBUTTON, label=_('Add slave'), |
|
480 name='AddSlaveButton', parent=self.Editor, pos=wx.Point(0, 0), |
|
481 size=wx.DefaultSize, style=0) |
|
482 self.Bind(wx.EVT_BUTTON, self.OnAddSlaveButtonClick, id=ID_CONFIGEDITORADDSLAVEBUTTON) |
|
483 |
|
484 self.DeleteSlaveButton = wx.Button(id=ID_CONFIGEDITORDELETESLAVEBUTTON, label=_('Delete slave'), |
|
485 name='DeleteSlaveButton', parent=self.Editor, pos=wx.Point(0, 0), |
|
486 size=wx.DefaultSize, style=0) |
|
487 self.Bind(wx.EVT_BUTTON, self.OnDeleteSlaveButtonClick, id=ID_CONFIGEDITORDELETESLAVEBUTTON) |
|
488 |
|
489 self.SlaveNodes = wx.Notebook(id=ID_CONFIGEDITORSLAVENODES, |
|
490 name='SlaveNodes', parent=self.Editor, pos=wx.Point(0, 0), |
|
491 size=wx.Size(0, 0), style=wx.NB_LEFT) |
|
492 |
|
493 self._init_sizers() |
|
494 |
|
495 def __init__(self, parent, controler, window): |
|
496 EditorPanel.__init__(self, parent, "", window, controler) |
|
497 |
|
498 img = wx.Bitmap(self.Controler.GetIconPath("Cfile.png"), wx.BITMAP_TYPE_PNG).ConvertToImage() |
|
499 self.SetIcon(wx.BitmapFromImage(img.Rescale(16, 16))) |
|
500 |
|
501 def GetTitle(self): |
|
502 filename = self.Controler.GetFilename() |
|
503 if not self.Controler.ConfigIsSaved(): |
|
504 return "~%s~" % filename |
|
505 return filename |
|
506 |
|
507 def GetBufferState(self): |
|
508 return self.Controler.GetBufferState() |
|
509 |
|
510 def Undo(self): |
|
511 self.Controler.LoadPrevious() |
|
512 self.RefreshView() |
|
513 |
|
514 def Redo(self): |
|
515 self.Controler.LoadNext() |
|
516 self.RefreshView() |
|
517 |
|
518 def RefreshView(self, slave_pos=None): |
|
519 slaves = self.Controler.GetSlaves() |
|
520 for i, slave in enumerate(slaves): |
|
521 if i < self.SlaveNodes.GetPageCount(): |
|
522 panel = self.SlaveNodes.GetPage(i) |
|
523 panel.SetSlave(slave) |
|
524 else: |
|
525 panel = SlavePanel(self.SlaveNodes, self.Controler, self, slave) |
|
526 self.SlaveNodes.AddPage(panel, "") |
|
527 while self.SlaveNodes.GetPageCount() > len(slaves): |
|
528 self.SlaveNodes.RemovePage(len(slaves)) |
|
529 self.RefreshSlaveNodesTitles() |
|
530 self.RefreshButtons() |
|
531 if slave_pos is not None: |
|
532 self.SelectSlave(slave_pos) |
|
533 |
|
534 def RefreshParentWindow(self): |
|
535 self.ParentWindow.RefreshTitle() |
|
536 self.ParentWindow.RefreshFileMenu() |
|
537 self.ParentWindow.RefreshEditMenu() |
|
538 self.ParentWindow.RefreshPageTitles() |
|
539 |
|
540 def RefreshSlaveNodesTitles(self): |
|
541 for idx in xrange(self.SlaveNodes.GetPageCount()): |
|
542 panel = self.SlaveNodes.GetPage(idx) |
|
543 self.SlaveNodes.SetPageText(idx, panel.GetSlaveTitle()) |
|
544 |
|
545 def RefreshButtons(self): |
|
546 self.DeleteSlaveButton.Enable(self.SlaveNodes.GetPageCount() > 0) |
|
547 |
|
548 def SelectSlave(self, slave): |
|
549 for idx in xrange(self.SlaveNodes.GetPageCount()): |
|
550 panel = self.SlaveNodes.GetPage(idx) |
|
551 if panel.GetSlave() == slave: |
|
552 self.SlaveNodes.SetSelection(idx) |
|
553 return |
|
554 |
|
555 def OnAddSlaveButtonClick(self, event): |
|
556 slave = self.Controler.AddSlave() |
|
557 self.RefreshParentWindow() |
|
558 wx.CallAfter(self.RefreshView, slave) |
|
559 event.Skip() |
|
560 |
|
561 def OnDeleteSlaveButtonClick(self, event): |
|
562 selected = self.SlaveNodes.GetSelection() |
|
563 if selected != -1: |
|
564 panel = self.SlaveNodes.GetPage(selected) |
|
565 if self.Controler.RemoveSlave(panel.GetSlave()[:2]): |
|
566 self.RefreshParentWindow() |
|
567 wx.CallAfter(self.RefreshView) |
|
568 |