1 #!/usr/bin/env python |
1 #!/usr/bin/env python |
2 # -*- coding: utf-8 -*- |
2 # -*- coding: utf-8 -*- |
3 |
3 |
4 #This file is part of PLCOpenEditor, a library implementing an IEC 61131-3 editor |
4 # This file is part of Beremiz, a Integrated Development Environment for |
5 #based on the plcopen standard. |
5 # programming IEC 61131-3 automates supporting plcopen standard and CanFestival. |
6 # |
6 # |
7 #Copyright (C) 2007: Edouard TISSERANT and Laurent BESSARD |
7 # Copyright (C) 2007: Edouard TISSERANT and Laurent BESSARD |
8 # |
8 # |
9 #See COPYING file for copyrights details. |
9 # See COPYING file for copyrights details. |
10 # |
10 # |
11 #This library is free software; you can redistribute it and/or |
11 # This program is free software; you can redistribute it and/or |
12 #modify it under the terms of the GNU General Public |
12 # modify it under the terms of the GNU General Public License |
13 #License as published by the Free Software Foundation; either |
13 # as published by the Free Software Foundation; either version 2 |
14 #version 2.1 of the License, or (at your option) any later version. |
14 # of the License, or (at your option) any later version. |
15 # |
15 # |
16 #This library is distributed in the hope that it will be useful, |
16 # This program is distributed in the hope that it will be useful, |
17 #but WITHOUT ANY WARRANTY; without even the implied warranty of |
17 # but WITHOUT ANY WARRANTY; without even the implied warranty of |
18 #MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU |
18 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
19 #General Public License for more details. |
19 # GNU General Public License for more details. |
20 # |
20 # |
21 #You should have received a copy of the GNU General Public |
21 # You should have received a copy of the GNU General Public License |
22 #License along with this library; if not, write to the Free Software |
22 # along with this program; if not, write to the Free Software |
23 #Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA |
23 # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. |
24 |
24 |
25 import os |
25 import os |
26 import re |
26 import re |
27 from types import TupleType, StringType, UnicodeType |
27 from types import TupleType, StringType, UnicodeType |
28 |
28 |
141 colname = "InitialValue" |
141 colname = "InitialValue" |
142 setattr(self.data[row], colname, value) |
142 setattr(self.data[row], colname, value) |
143 |
143 |
144 def GetOldValue(self): |
144 def GetOldValue(self): |
145 return self.old_value |
145 return self.old_value |
|
146 |
|
147 def _GetRowEdit(self, row): |
|
148 row_edit = self.GetValueByName(row, "Edit") |
|
149 var_type = self.Parent.GetTagName() |
|
150 bodytype = self.Parent.Controler.GetEditedElementBodyType(var_type) |
|
151 if bodytype in ["ST", "IL"]: |
|
152 row_edit = True; |
|
153 return row_edit |
146 |
154 |
147 def _updateColAttrs(self, grid): |
155 def _updateColAttrs(self, grid): |
148 """ |
156 """ |
149 wx.grid.Grid -> update the column attributes to add the |
157 wx.grid.Grid -> update the column attributes to add the |
150 appropriate renderer given the column name. |
158 appropriate renderer given the column name. |
169 if len(options) > 1: |
177 if len(options) > 1: |
170 editor = wx.grid.GridCellChoiceEditor() |
178 editor = wx.grid.GridCellChoiceEditor() |
171 editor.SetParameters(",".join(map(_, options))) |
179 editor.SetParameters(",".join(map(_, options))) |
172 else: |
180 else: |
173 grid.SetReadOnly(row, col, True) |
181 grid.SetReadOnly(row, col, True) |
174 elif col != 0 and self.GetValueByName(row, "Edit"): |
182 elif col != 0 and self._GetRowEdit(row): |
175 grid.SetReadOnly(row, col, False) |
183 grid.SetReadOnly(row, col, False) |
176 if colname == "Name": |
184 if colname == "Name": |
177 editor = wx.grid.GridCellTextEditor() |
185 editor = wx.grid.GridCellTextEditor() |
178 renderer = wx.grid.GridCellStringRenderer() |
186 renderer = wx.grid.GridCellStringRenderer() |
179 elif colname == "Initial Value": |
187 elif colname == "Initial Value": |
236 |
244 |
237 def OnDropText(self, x, y, data): |
245 def OnDropText(self, x, y, data): |
238 self.ParentWindow.ParentWindow.Select() |
246 self.ParentWindow.ParentWindow.Select() |
239 x, y = self.ParentWindow.VariablesGrid.CalcUnscrolledPosition(x, y) |
247 x, y = self.ParentWindow.VariablesGrid.CalcUnscrolledPosition(x, y) |
240 col = self.ParentWindow.VariablesGrid.XToCol(x) |
248 col = self.ParentWindow.VariablesGrid.XToCol(x) |
241 row = self.ParentWindow.VariablesGrid.YToRow(y - self.ParentWindow.VariablesGrid.GetColLabelSize()) |
249 row = self.ParentWindow.VariablesGrid.YToRow(y) |
242 message = None |
250 message = None |
243 element_type = self.ParentWindow.ElementType |
251 element_type = self.ParentWindow.ElementType |
244 try: |
252 try: |
245 values = eval(data) |
253 values = eval(data) |
246 except: |
254 except: |
263 base_type = self.ParentWindow.Controler.GetBaseType(variable_type) |
271 base_type = self.ParentWindow.Controler.GetBaseType(variable_type) |
264 |
272 |
265 if values[2] is not None: |
273 if values[2] is not None: |
266 base_location_type = self.ParentWindow.Controler.GetBaseType(values[2]) |
274 base_location_type = self.ParentWindow.Controler.GetBaseType(values[2]) |
267 if values[2] != variable_type and base_type != base_location_type: |
275 if values[2] != variable_type and base_type != base_location_type: |
268 message = _("Incompatible data types between \"%s\" and \"%s\"")%(values[2], variable_type) |
276 message = _("Incompatible data types between \"{a1}\" and \"{a2}\"").\ |
|
277 format(a1 = values[2], a2 = variable_type) |
269 |
278 |
270 if message is None: |
279 if message is None: |
271 if not location.startswith("%"): |
280 if not location.startswith("%"): |
272 if location[0].isdigit() and base_type != "BOOL": |
281 if location[0].isdigit() and base_type != "BOOL": |
273 message = _("Incompatible size of data between \"%s\" and \"BOOL\"")%location |
282 message = _("Incompatible size of data between \"%s\" and \"BOOL\"")%location |
274 elif location[0] not in LOCATIONDATATYPES: |
283 elif location[0] not in LOCATIONDATATYPES: |
275 message = _("Unrecognized data size \"%s\"")%location[0] |
284 message = _("Unrecognized data size \"%s\"")%location[0] |
276 elif base_type not in LOCATIONDATATYPES[location[0]]: |
285 elif base_type not in LOCATIONDATATYPES[location[0]]: |
277 message = _("Incompatible size of data between \"%s\" and \"%s\"")%(location, variable_type) |
286 message = _("Incompatible size of data between \"{a1}\" and \"{a2}\"").\ |
|
287 format(a1 = location, a2 = variable_type) |
278 else: |
288 else: |
279 dialog = wx.SingleChoiceDialog(self.ParentWindow.ParentWindow.ParentWindow, |
289 dialog = wx.SingleChoiceDialog(self.ParentWindow.ParentWindow.ParentWindow, |
280 _("Select a variable class:"), _("Variable class"), |
290 _("Select a variable class:"), _("Variable class"), |
281 ["Input", "Output", "Memory"], |
291 [_("Input"), _("Output"), _("Memory")], |
282 wx.DEFAULT_DIALOG_STYLE|wx.OK|wx.CANCEL) |
292 wx.DEFAULT_DIALOG_STYLE|wx.OK|wx.CANCEL) |
283 if dialog.ShowModal() == wx.ID_OK: |
293 if dialog.ShowModal() == wx.ID_OK: |
284 selected = dialog.GetSelection() |
294 selected = dialog.GetSelection() |
285 else: |
295 else: |
286 selected = None |
296 selected = None |
314 var_name = values[0] |
324 var_name = values[0] |
315 tagname = self.ParentWindow.GetTagName() |
325 tagname = self.ParentWindow.GetTagName() |
316 dlg = wx.TextEntryDialog( |
326 dlg = wx.TextEntryDialog( |
317 self.ParentWindow.ParentWindow.ParentWindow, |
327 self.ParentWindow.ParentWindow.ParentWindow, |
318 _("Confirm or change variable name"), |
328 _("Confirm or change variable name"), |
319 'Variable Drop', var_name) |
329 _('Variable Drop'), var_name) |
320 dlg.SetValue(var_name) |
330 dlg.SetValue(var_name) |
321 var_name = dlg.GetValue() if dlg.ShowModal() == wx.ID_OK else None |
331 var_name = dlg.GetValue() if dlg.ShowModal() == wx.ID_OK else None |
322 dlg.Destroy() |
332 dlg.Destroy() |
323 if var_name is None: |
333 if var_name is None: |
324 return |
334 return |
336 if values[1] == "location": |
346 if values[1] == "location": |
337 location = values[0] |
347 location = values[0] |
338 if not location.startswith("%"): |
348 if not location.startswith("%"): |
339 dialog = wx.SingleChoiceDialog(self.ParentWindow.ParentWindow.ParentWindow, |
349 dialog = wx.SingleChoiceDialog(self.ParentWindow.ParentWindow.ParentWindow, |
340 _("Select a variable class:"), _("Variable class"), |
350 _("Select a variable class:"), _("Variable class"), |
341 ["Input", "Output", "Memory"], |
351 [_("Input"), _("Output"), _("Memory")], |
342 wx.DEFAULT_DIALOG_STYLE|wx.OK|wx.CANCEL) |
352 wx.DEFAULT_DIALOG_STYLE|wx.OK|wx.CANCEL) |
343 if dialog.ShowModal() == wx.ID_OK: |
353 if dialog.ShowModal() == wx.ID_OK: |
344 selected = dialog.GetSelection() |
354 selected = dialog.GetSelection() |
345 else: |
355 else: |
346 selected = None |
356 selected = None |
582 self.RefreshValues() |
592 self.RefreshValues() |
583 return new_row |
593 return new_row |
584 setattr(self.VariablesGrid, "_AddRow", _AddVariable) |
594 setattr(self.VariablesGrid, "_AddRow", _AddVariable) |
585 |
595 |
586 def _DeleteVariable(row): |
596 def _DeleteVariable(row): |
587 if self.Table.GetValueByName(row, "Edit"): |
597 if _GetRowEdit(row): |
588 self.Values.remove(self.Table.GetRow(row)) |
598 self.Values.remove(self.Table.GetRow(row)) |
589 self.SaveValues() |
599 self.SaveValues() |
590 if self.ElementType == "resource": |
600 if self.ElementType == "resource": |
591 self.ParentWindow.RefreshView(variablepanel = False) |
601 self.ParentWindow.RefreshView(variablepanel = False) |
592 self.RefreshValues() |
602 self.RefreshValues() |
601 self.RefreshValues() |
611 self.RefreshValues() |
602 return new_row |
612 return new_row |
603 return row |
613 return row |
604 setattr(self.VariablesGrid, "_MoveRow", _MoveVariable) |
614 setattr(self.VariablesGrid, "_MoveRow", _MoveVariable) |
605 |
615 |
|
616 def _GetRowEdit(row): |
|
617 row_edit = False |
|
618 if self: |
|
619 row_edit = self.Table.GetValueByName(row, "Edit") |
|
620 bodytype = self.Controler.GetEditedElementBodyType(self.TagName) |
|
621 row_edit = row_edit or (bodytype in ["ST", "IL"]) |
|
622 return row_edit |
|
623 |
606 def _RefreshButtons(): |
624 def _RefreshButtons(): |
607 if self: |
625 if self: |
608 table_length = len(self.Table.data) |
626 table_length = len(self.Table.data) |
609 row_class = None |
627 row_class = None |
610 row_edit = True |
628 row_edit = True |
611 row = 0 |
629 row = 0 |
612 if table_length > 0: |
630 if table_length > 0: |
613 row = self.VariablesGrid.GetGridCursorRow() |
631 row = self.VariablesGrid.GetGridCursorRow() |
614 row_edit = self.Table.GetValueByName(row, "Edit") |
632 row_edit = _GetRowEdit(row) |
615 self.AddButton.Enable(not self.Debug) |
633 self.AddButton.Enable(not self.Debug) |
616 self.DeleteButton.Enable(not self.Debug and (table_length > 0 and row_edit)) |
634 self.DeleteButton.Enable(not self.Debug and (table_length > 0 and row_edit)) |
617 self.UpButton.Enable(not self.Debug and (table_length > 0 and row > 0 and self.Filter == "All")) |
635 self.UpButton.Enable(not self.Debug and (table_length > 0 and row > 0 and self.Filter == "All")) |
618 self.DownButton.Enable(not self.Debug and (table_length > 0 and row < table_length - 1 and self.Filter == "All")) |
636 self.DownButton.Enable(not self.Debug and (table_length > 0 and row < table_length - 1 and self.Filter == "All")) |
619 setattr(self.VariablesGrid, "RefreshButtons", _RefreshButtons) |
637 setattr(self.VariablesGrid, "RefreshButtons", _RefreshButtons) |