95 #------------------------------------------------------------------------------- |
95 #------------------------------------------------------------------------------- |
96 # Variables Panel Table |
96 # Variables Panel Table |
97 #------------------------------------------------------------------------------- |
97 #------------------------------------------------------------------------------- |
98 |
98 |
99 class VariableTable(CustomTable): |
99 class VariableTable(CustomTable): |
100 |
100 |
101 """ |
101 """ |
102 A custom wx.grid.Grid Table using user supplied data |
102 A custom wx.grid.Grid Table using user supplied data |
103 """ |
103 """ |
104 def __init__(self, parent, data, colnames): |
104 def __init__(self, parent, data, colnames): |
105 # The base class must be initialized *first* |
105 # The base class must be initialized *first* |
106 CustomTable.__init__(self, parent, data, colnames) |
106 CustomTable.__init__(self, parent, data, colnames) |
107 self.old_value = None |
107 self.old_value = None |
108 |
108 |
109 def GetValueByName(self, row, colname): |
109 def GetValueByName(self, row, colname): |
110 if row < self.GetNumberRows(): |
110 if row < self.GetNumberRows(): |
111 return getattr(self.data[row], colname) |
111 return getattr(self.data[row], colname) |
112 |
112 |
113 def SetValueByName(self, row, colname, value): |
113 def SetValueByName(self, row, colname, value): |
114 if row < self.GetNumberRows(): |
114 if row < self.GetNumberRows(): |
115 setattr(self.data[row], colname, value) |
115 setattr(self.data[row], colname, value) |
116 |
116 |
117 def GetValue(self, row, col): |
117 def GetValue(self, row, col): |
118 if row < self.GetNumberRows(): |
118 if row < self.GetNumberRows(): |
119 if col == 0: |
119 if col == 0: |
120 return self.data[row].Number |
120 return self.data[row].Number |
121 colname = self.GetColLabelValue(col, False) |
121 colname = self.GetColLabelValue(col, False) |
207 if self.Parent.IsFunctionBlockType(var_type): |
207 if self.Parent.IsFunctionBlockType(var_type): |
208 excluded.extend(["Local","Temp"]) |
208 excluded.extend(["Local","Temp"]) |
209 editor.SetParameters(",".join([_(choice) for choice in self.Parent.ClassList if choice not in excluded])) |
209 editor.SetParameters(",".join([_(choice) for choice in self.Parent.ClassList if choice not in excluded])) |
210 elif colname != "Documentation": |
210 elif colname != "Documentation": |
211 grid.SetReadOnly(row, col, True) |
211 grid.SetReadOnly(row, col, True) |
212 |
212 |
213 grid.SetCellEditor(row, col, editor) |
213 grid.SetCellEditor(row, col, editor) |
214 grid.SetCellRenderer(row, col, renderer) |
214 grid.SetCellRenderer(row, col, renderer) |
215 |
215 |
216 if colname == "Location" and LOCATION_MODEL.match(self.GetValueByName(row, colname)) is None: |
216 if colname == "Location" and LOCATION_MODEL.match(self.GetValueByName(row, colname)) is None: |
217 highlight_colours = ERROR_HIGHLIGHT |
217 highlight_colours = ERROR_HIGHLIGHT |
218 else: |
218 else: |
219 highlight_colours = row_highlights.get(colname.lower(), [(wx.WHITE, wx.BLACK)])[-1] |
219 highlight_colours = row_highlights.get(colname.lower(), [(wx.WHITE, wx.BLACK)])[-1] |
220 grid.SetCellBackgroundColour(row, col, highlight_colours[0]) |
220 grid.SetCellBackgroundColour(row, col, highlight_colours[0]) |
221 grid.SetCellTextColour(row, col, highlight_colours[1]) |
221 grid.SetCellTextColour(row, col, highlight_colours[1]) |
222 self.ResizeRow(grid, row) |
222 self.ResizeRow(grid, row) |
223 |
223 |
224 #------------------------------------------------------------------------------- |
224 #------------------------------------------------------------------------------- |
225 # Variable Panel Drop Target |
225 # Variable Panel Drop Target |
226 #------------------------------------------------------------------------------- |
226 #------------------------------------------------------------------------------- |
227 |
227 |
228 class VariableDropTarget(wx.TextDropTarget): |
228 class VariableDropTarget(wx.TextDropTarget): |
229 ''' |
229 ''' |
230 This allows dragging a variable location from somewhere to the Location |
230 This allows dragging a variable location from somewhere to the Location |
231 column of a variable row. |
231 column of a variable row. |
232 |
232 |
233 The drag source should be a TextDataObject containing a Python tuple like: |
233 The drag source should be a TextDataObject containing a Python tuple like: |
234 ('%ID0.0.0', 'location', 'REAL') |
234 ('%ID0.0.0', 'location', 'REAL') |
235 |
235 |
236 c_ext/CFileEditor.py has an example of this (you can drag a C extension |
236 c_ext/CFileEditor.py has an example of this (you can drag a C extension |
237 variable to the Location column of the variable panel). |
237 variable to the Location column of the variable panel). |
238 ''' |
238 ''' |
239 def __init__(self, parent): |
239 def __init__(self, parent): |
240 wx.TextDropTarget.__init__(self) |
240 wx.TextDropTarget.__init__(self) |
241 self.ParentWindow = parent |
241 self.ParentWindow = parent |
242 |
242 |
243 def OnDropText(self, x, y, data): |
243 def OnDropText(self, x, y, data): |
244 self.ParentWindow.ParentWindow.Select() |
244 self.ParentWindow.ParentWindow.Select() |
245 x, y = self.ParentWindow.VariablesGrid.CalcUnscrolledPosition(x, y) |
245 x, y = self.ParentWindow.VariablesGrid.CalcUnscrolledPosition(x, y) |
246 col = self.ParentWindow.VariablesGrid.XToCol(x) |
246 col = self.ParentWindow.VariablesGrid.XToCol(x) |
247 row = self.ParentWindow.VariablesGrid.YToRow(y - self.ParentWindow.VariablesGrid.GetColLabelSize()) |
247 row = self.ParentWindow.VariablesGrid.YToRow(y - self.ParentWindow.VariablesGrid.GetColLabelSize()) |
248 message = None |
248 message = None |
249 element_type = self.ParentWindow.ElementType |
249 element_type = self.ParentWindow.ElementType |
250 try: |
250 try: |
251 values = eval(data) |
251 values = eval(data) |
252 except: |
252 except: |
253 message = _("Invalid value \"%s\" for variable grid element")%data |
253 message = _("Invalid value \"%s\" for variable grid element")%data |
254 values = None |
254 values = None |
255 if not isinstance(values, TupleType): |
255 if not isinstance(values, TupleType): |
256 message = _("Invalid value \"%s\" for variable grid element")%data |
256 message = _("Invalid value \"%s\" for variable grid element")%data |
265 message = _("Can only give a location to local or global variables") |
265 message = _("Can only give a location to local or global variables") |
266 else: |
266 else: |
267 location = values[0] |
267 location = values[0] |
268 variable_type = self.ParentWindow.Table.GetValueByName(row, "Type") |
268 variable_type = self.ParentWindow.Table.GetValueByName(row, "Type") |
269 base_type = self.ParentWindow.Controler.GetBaseType(variable_type) |
269 base_type = self.ParentWindow.Controler.GetBaseType(variable_type) |
270 |
270 |
271 if values[2] is not None: |
271 if values[2] is not None: |
272 base_location_type = self.ParentWindow.Controler.GetBaseType(values[2]) |
272 base_location_type = self.ParentWindow.Controler.GetBaseType(values[2]) |
273 if values[2] != variable_type and base_type != base_location_type: |
273 if values[2] != variable_type and base_type != base_location_type: |
274 message = _("Incompatible data types between \"%s\" and \"%s\"")%(values[2], variable_type) |
274 message = _("Incompatible data types between \"%s\" and \"%s\"")%(values[2], variable_type) |
275 |
275 |
276 if message is None: |
276 if message is None: |
277 if not location.startswith("%"): |
277 if not location.startswith("%"): |
278 if location[0].isdigit() and base_type != "BOOL": |
278 if location[0].isdigit() and base_type != "BOOL": |
279 message = _("Incompatible size of data between \"%s\" and \"BOOL\"")%location |
279 message = _("Incompatible size of data between \"%s\" and \"BOOL\"")%location |
280 elif location[0] not in LOCATIONDATATYPES: |
280 elif location[0] not in LOCATIONDATATYPES: |
281 message = _("Unrecognized data size \"%s\"")%location[0] |
281 message = _("Unrecognized data size \"%s\"")%location[0] |
282 elif base_type not in LOCATIONDATATYPES[location[0]]: |
282 elif base_type not in LOCATIONDATATYPES[location[0]]: |
283 message = _("Incompatible size of data between \"%s\" and \"%s\"")%(location, variable_type) |
283 message = _("Incompatible size of data between \"%s\" and \"%s\"")%(location, variable_type) |
284 else: |
284 else: |
285 dialog = wx.SingleChoiceDialog(self.ParentWindow.ParentWindow.ParentWindow, |
285 dialog = wx.SingleChoiceDialog(self.ParentWindow.ParentWindow.ParentWindow, |
286 _("Select a variable class:"), _("Variable class"), |
286 _("Select a variable class:"), _("Variable class"), |
287 ["Input", "Output", "Memory"], |
287 ["Input", "Output", "Memory"], |
288 wx.DEFAULT_DIALOG_STYLE|wx.OK|wx.CANCEL) |
288 wx.DEFAULT_DIALOG_STYLE|wx.OK|wx.CANCEL) |
289 if dialog.ShowModal() == wx.ID_OK: |
289 if dialog.ShowModal() == wx.ID_OK: |
290 selected = dialog.GetSelection() |
290 selected = dialog.GetSelection() |
291 else: |
291 else: |
292 selected = None |
292 selected = None |
309 message = _("Can't set an initial value to a function block instance") |
309 message = _("Can't set an initial value to a function block instance") |
310 else: |
310 else: |
311 self.ParentWindow.Table.SetValue(row, col, values[0]) |
311 self.ParentWindow.Table.SetValue(row, col, values[0]) |
312 self.ParentWindow.Table.ResetView(self.ParentWindow.VariablesGrid) |
312 self.ParentWindow.Table.ResetView(self.ParentWindow.VariablesGrid) |
313 self.ParentWindow.SaveValues() |
313 self.ParentWindow.SaveValues() |
314 elif (element_type not in ["config", "resource", "function"] and values[1] == "Global" and |
314 elif (element_type not in ["config", "resource", "function"] and values[1] == "Global" and |
315 self.ParentWindow.Filter in ["All", "Interface", "External"] or |
315 self.ParentWindow.Filter in ["All", "Interface", "External"] or |
316 element_type != "function" and values[1] == "location"): |
316 element_type != "function" and values[1] == "location"): |
317 if values[1] == "location": |
317 if values[1] == "location": |
318 var_name = values[3] |
318 var_name = values[3] |
319 else: |
319 else: |
320 var_name = values[0] |
320 var_name = values[0] |
321 tagname = self.ParentWindow.GetTagName() |
321 tagname = self.ParentWindow.GetTagName() |
322 if var_name.upper() in [name.upper() |
322 if var_name.upper() in [name.upper() |
323 for name in self.ParentWindow.Controler.\ |
323 for name in self.ParentWindow.Controler.\ |
324 GetProjectPouNames(self.ParentWindow.Debug)]: |
324 GetProjectPouNames(self.ParentWindow.Debug)]: |
325 message = _("\"%s\" pou already exists!")%var_name |
325 message = _("\"%s\" pou already exists!")%var_name |
326 elif not var_name.upper() in [name.upper() |
326 elif not var_name.upper() in [name.upper() |
327 for name in self.ParentWindow.Controler.\ |
327 for name in self.ParentWindow.Controler.\ |
328 GetEditedElementVariables(tagname, self.ParentWindow.Debug)]: |
328 GetEditedElementVariables(tagname, self.ParentWindow.Debug)]: |
329 var_infos = self.ParentWindow.DefaultValue.copy() |
329 var_infos = self.ParentWindow.DefaultValue.copy() |
330 var_infos.Name = var_name |
330 var_infos.Name = var_name |
331 var_infos.Type = values[2] |
331 var_infos.Type = values[2] |
332 if values[1] == "location": |
332 if values[1] == "location": |
333 location = values[0] |
333 location = values[0] |
334 if not location.startswith("%"): |
334 if not location.startswith("%"): |
335 dialog = wx.SingleChoiceDialog(self.ParentWindow.ParentWindow.ParentWindow, |
335 dialog = wx.SingleChoiceDialog(self.ParentWindow.ParentWindow.ParentWindow, |
336 _("Select a variable class:"), _("Variable class"), |
336 _("Select a variable class:"), _("Variable class"), |
337 ["Input", "Output", "Memory"], |
337 ["Input", "Output", "Memory"], |
338 wx.DEFAULT_DIALOG_STYLE|wx.OK|wx.CANCEL) |
338 wx.DEFAULT_DIALOG_STYLE|wx.OK|wx.CANCEL) |
339 if dialog.ShowModal() == wx.ID_OK: |
339 if dialog.ShowModal() == wx.ID_OK: |
340 selected = dialog.GetSelection() |
340 selected = dialog.GetSelection() |
341 else: |
341 else: |
342 selected = None |
342 selected = None |
370 var_infos.Class = "External" |
370 var_infos.Class = "External" |
371 var_infos.Number = len(self.ParentWindow.Values) |
371 var_infos.Number = len(self.ParentWindow.Values) |
372 self.ParentWindow.Values.append(var_infos) |
372 self.ParentWindow.Values.append(var_infos) |
373 self.ParentWindow.SaveValues() |
373 self.ParentWindow.SaveValues() |
374 self.ParentWindow.RefreshValues() |
374 self.ParentWindow.RefreshValues() |
375 |
375 |
376 if message is not None: |
376 if message is not None: |
377 wx.CallAfter(self.ShowMessage, message) |
377 wx.CallAfter(self.ShowMessage, message) |
378 |
378 |
379 def ShowMessage(self, message): |
379 def ShowMessage(self, message): |
380 message = wx.MessageDialog(self.ParentWindow, message, _("Error"), wx.OK|wx.ICON_ERROR) |
380 message = wx.MessageDialog(self.ParentWindow, message, _("Error"), wx.OK|wx.ICON_ERROR) |
381 message.ShowModal() |
381 message.ShowModal() |
382 message.Destroy() |
382 message.Destroy() |
383 |
383 |
384 #------------------------------------------------------------------------------- |
384 #------------------------------------------------------------------------------- |
385 # Variable Panel |
385 # Variable Panel |
386 #------------------------------------------------------------------------------- |
386 #------------------------------------------------------------------------------- |
387 |
387 |
388 class VariablePanel(wx.Panel): |
388 class VariablePanel(wx.Panel): |
389 |
389 |
390 def __init__(self, parent, window, controler, element_type, debug=False): |
390 def __init__(self, parent, window, controler, element_type, debug=False): |
391 wx.Panel.__init__(self, parent, style=wx.TAB_TRAVERSAL) |
391 wx.Panel.__init__(self, parent, style=wx.TAB_TRAVERSAL) |
392 |
392 |
393 self.MainSizer = wx.FlexGridSizer(cols=1, hgap=10, rows=2, vgap=0) |
393 self.MainSizer = wx.FlexGridSizer(cols=1, hgap=10, rows=2, vgap=0) |
394 self.MainSizer.AddGrowableCol(0) |
394 self.MainSizer.AddGrowableCol(0) |
395 self.MainSizer.AddGrowableRow(1) |
395 self.MainSizer.AddGrowableRow(1) |
396 |
396 |
397 controls_sizer = wx.FlexGridSizer(cols=10, hgap=5, rows=1, vgap=5) |
397 controls_sizer = wx.FlexGridSizer(cols=10, hgap=5, rows=1, vgap=5) |
398 controls_sizer.AddGrowableCol(5) |
398 controls_sizer.AddGrowableCol(5) |
399 controls_sizer.AddGrowableRow(0) |
399 controls_sizer.AddGrowableRow(0) |
400 self.MainSizer.AddSizer(controls_sizer, border=5, flag=wx.GROW|wx.ALL) |
400 self.MainSizer.AddSizer(controls_sizer, border=5, flag=wx.GROW|wx.ALL) |
401 |
401 |
402 self.ReturnTypeLabel = wx.StaticText(self, label=_('Return Type:')) |
402 self.ReturnTypeLabel = wx.StaticText(self, label=_('Return Type:')) |
403 controls_sizer.AddWindow(self.ReturnTypeLabel, flag=wx.ALIGN_CENTER_VERTICAL) |
403 controls_sizer.AddWindow(self.ReturnTypeLabel, flag=wx.ALIGN_CENTER_VERTICAL) |
404 |
404 |
405 self.ReturnType = wx.ComboBox(self, |
405 self.ReturnType = wx.ComboBox(self, |
406 size=wx.Size(145, -1), style=wx.CB_READONLY) |
406 size=wx.Size(145, -1), style=wx.CB_READONLY) |
407 self.Bind(wx.EVT_COMBOBOX, self.OnReturnTypeChanged, self.ReturnType) |
407 self.Bind(wx.EVT_COMBOBOX, self.OnReturnTypeChanged, self.ReturnType) |
408 controls_sizer.AddWindow(self.ReturnType) |
408 controls_sizer.AddWindow(self.ReturnType) |
409 |
409 |
410 self.DescriptionLabel = wx.StaticText(self, label=_('Description:')) |
410 self.DescriptionLabel = wx.StaticText(self, label=_('Description:')) |
411 controls_sizer.AddWindow(self.DescriptionLabel, flag=wx.ALIGN_CENTER_VERTICAL) |
411 controls_sizer.AddWindow(self.DescriptionLabel, flag=wx.ALIGN_CENTER_VERTICAL) |
412 |
412 |
413 self.Description = wx.TextCtrl(self, |
413 self.Description = wx.TextCtrl(self, |
414 size=wx.Size(250, -1), style=wx.TE_PROCESS_ENTER) |
414 size=wx.Size(250, -1), style=wx.TE_PROCESS_ENTER) |
415 self.Bind(wx.EVT_TEXT_ENTER, self.OnDescriptionChanged, self.Description) |
415 self.Bind(wx.EVT_TEXT_ENTER, self.OnDescriptionChanged, self.Description) |
416 self.Description.Bind(wx.EVT_KILL_FOCUS, self.OnDescriptionChanged) |
416 self.Description.Bind(wx.EVT_KILL_FOCUS, self.OnDescriptionChanged) |
417 controls_sizer.AddWindow(self.Description) |
417 controls_sizer.AddWindow(self.Description) |
418 |
418 |
419 class_filter_label = wx.StaticText(self, label=_('Class Filter:')) |
419 class_filter_label = wx.StaticText(self, label=_('Class Filter:')) |
420 controls_sizer.AddWindow(class_filter_label, flag=wx.ALIGN_CENTER_VERTICAL) |
420 controls_sizer.AddWindow(class_filter_label, flag=wx.ALIGN_CENTER_VERTICAL) |
421 |
421 |
422 self.ClassFilter = wx.ComboBox(self, |
422 self.ClassFilter = wx.ComboBox(self, |
423 size=wx.Size(145, -1), style=wx.CB_READONLY) |
423 size=wx.Size(145, -1), style=wx.CB_READONLY) |
424 self.Bind(wx.EVT_COMBOBOX, self.OnClassFilter, self.ClassFilter) |
424 self.Bind(wx.EVT_COMBOBOX, self.OnClassFilter, self.ClassFilter) |
425 controls_sizer.AddWindow(self.ClassFilter) |
425 controls_sizer.AddWindow(self.ClassFilter) |
426 |
426 |
427 for name, bitmap, help in [ |
427 for name, bitmap, help in [ |
428 ("AddButton", "add_element", _("Add variable")), |
428 ("AddButton", "add_element", _("Add variable")), |
429 ("DeleteButton", "remove_element", _("Remove variable")), |
429 ("DeleteButton", "remove_element", _("Remove variable")), |
430 ("UpButton", "up", _("Move variable up")), |
430 ("UpButton", "up", _("Move variable up")), |
431 ("DownButton", "down", _("Move variable down"))]: |
431 ("DownButton", "down", _("Move variable down"))]: |
432 button = wx.lib.buttons.GenBitmapButton(self, bitmap=GetBitmap(bitmap), |
432 button = wx.lib.buttons.GenBitmapButton(self, bitmap=GetBitmap(bitmap), |
433 size=wx.Size(28, 28), style=wx.NO_BORDER) |
433 size=wx.Size(28, 28), style=wx.NO_BORDER) |
434 button.SetToolTipString(help) |
434 button.SetToolTipString(help) |
435 setattr(self, name, button) |
435 setattr(self, name, button) |
436 controls_sizer.AddWindow(button) |
436 controls_sizer.AddWindow(button) |
437 |
437 |
438 self.VariablesGrid = CustomGrid(self, style=wx.VSCROLL) |
438 self.VariablesGrid = CustomGrid(self, style=wx.VSCROLL) |
439 self.VariablesGrid.SetDropTarget(VariableDropTarget(self)) |
439 self.VariablesGrid.SetDropTarget(VariableDropTarget(self)) |
440 self.VariablesGrid.Bind(wx.grid.EVT_GRID_CELL_CHANGE, |
440 self.VariablesGrid.Bind(wx.grid.EVT_GRID_CELL_CHANGE, |
441 self.OnVariablesGridCellChange) |
441 self.OnVariablesGridCellChange) |
442 self.VariablesGrid.Bind(wx.grid.EVT_GRID_CELL_LEFT_CLICK, |
442 self.VariablesGrid.Bind(wx.grid.EVT_GRID_CELL_LEFT_CLICK, |
443 self.OnVariablesGridCellLeftClick) |
443 self.OnVariablesGridCellLeftClick) |
444 self.VariablesGrid.Bind(wx.grid.EVT_GRID_EDITOR_SHOWN, |
444 self.VariablesGrid.Bind(wx.grid.EVT_GRID_EDITOR_SHOWN, |
445 self.OnVariablesGridEditorShown) |
445 self.OnVariablesGridEditorShown) |
446 self.MainSizer.AddWindow(self.VariablesGrid, flag=wx.GROW) |
446 self.MainSizer.AddWindow(self.VariablesGrid, flag=wx.GROW) |
447 |
447 |
448 self.SetSizer(self.MainSizer) |
448 self.SetSizer(self.MainSizer) |
449 |
449 |
450 self.ParentWindow = window |
450 self.ParentWindow = window |
451 self.Controler = controler |
451 self.Controler = controler |
452 self.ElementType = element_type |
452 self.ElementType = element_type |
453 self.Debug = debug |
453 self.Debug = debug |
454 |
454 |
455 self.RefreshHighlightsTimer = wx.Timer(self, -1) |
455 self.RefreshHighlightsTimer = wx.Timer(self, -1) |
456 self.Bind(wx.EVT_TIMER, self.OnRefreshHighlightsTimer, |
456 self.Bind(wx.EVT_TIMER, self.OnRefreshHighlightsTimer, |
457 self.RefreshHighlightsTimer) |
457 self.RefreshHighlightsTimer) |
458 |
458 |
459 self.Filter = "All" |
459 self.Filter = "All" |
460 self.FilterChoices = [] |
460 self.FilterChoices = [] |
461 self.FilterChoiceTransfer = GetFilterChoiceTransfer() |
461 self.FilterChoiceTransfer = GetFilterChoiceTransfer() |
462 |
462 |
463 self.DefaultValue = _VariableInfos("", "", "", "", "", True, "", "INT", ([], []), 0) |
463 self.DefaultValue = _VariableInfos("", "", "", "", "", True, "", DefaultType, ([], []), 0) |
464 |
464 |
465 if element_type in ["config", "resource"]: |
465 if element_type in ["config", "resource"]: |
466 self.DefaultTypes = {"All" : "Global"} |
466 self.DefaultTypes = {"All" : "Global"} |
467 else: |
467 else: |
468 self.DefaultTypes = {"All" : "Local", "Interface" : "Input", "Variables" : "Local"} |
468 self.DefaultTypes = {"All" : "Local", "Interface" : "Input", "Variables" : "Local"} |
469 |
469 |
544 start_idx = 0 |
544 start_idx = 0 |
545 else: |
545 else: |
546 row_content = None |
546 row_content = None |
547 start_idx = 0 |
547 start_idx = 0 |
548 name = "LocalVar" |
548 name = "LocalVar" |
549 |
549 |
550 if row_content is not None and row_content.Edit: |
550 if row_content is not None and row_content.Edit: |
551 row_content = self.Values[new_row - 1].copy() |
551 row_content = self.Values[new_row - 1].copy() |
552 else: |
552 else: |
553 row_content = self.DefaultValue.copy() |
553 row_content = self.DefaultValue.copy() |
554 if self.Filter in self.DefaultTypes: |
554 if self.Filter in self.DefaultTypes: |
555 row_content.Class = self.DefaultTypes[self.Filter] |
555 row_content.Class = self.DefaultTypes[self.Filter] |
556 else: |
556 else: |
557 row_content.Class = self.Filter |
557 row_content.Class = self.Filter |
558 |
558 |
559 row_content.Name = self.Controler.GenerateNewName( |
559 row_content.Name = self.Controler.GenerateNewName( |
560 self.TagName, None, name + "%d", start_idx) |
560 self.TagName, None, name + "%d", start_idx) |
561 |
561 |
562 if self.Filter == "All" and len(self.Values) > 0: |
562 if self.Filter == "All" and len(self.Values) > 0: |
563 self.Values.insert(new_row, row_content) |
563 self.Values.insert(new_row, row_content) |
564 else: |
564 else: |
565 self.Values.append(row_content) |
565 self.Values.append(row_content) |
566 new_row = self.Table.GetNumberRows() |
566 new_row = self.Table.GetNumberRows() |
567 self.SaveValues() |
567 self.SaveValues() |
568 self.RefreshValues() |
568 self.RefreshValues() |
569 return new_row |
569 return new_row |
570 setattr(self.VariablesGrid, "_AddRow", _AddVariable) |
570 setattr(self.VariablesGrid, "_AddRow", _AddVariable) |
571 |
571 |
572 def _DeleteVariable(row): |
572 def _DeleteVariable(row): |
573 if self.Table.GetValueByName(row, "Edit"): |
573 if self.Table.GetValueByName(row, "Edit"): |
574 self.Values.remove(self.Table.GetRow(row)) |
574 self.Values.remove(self.Table.GetRow(row)) |
575 self.SaveValues() |
575 self.SaveValues() |
576 if self.ElementType == "resource": |
576 if self.ElementType == "resource": |
577 self.ParentWindow.RefreshView(variablepanel = False) |
577 self.ParentWindow.RefreshView(variablepanel = False) |
578 self.RefreshValues() |
578 self.RefreshValues() |
579 setattr(self.VariablesGrid, "_DeleteRow", _DeleteVariable) |
579 setattr(self.VariablesGrid, "_DeleteRow", _DeleteVariable) |
580 |
580 |
581 def _MoveVariable(row, move): |
581 def _MoveVariable(row, move): |
582 if self.Filter == "All": |
582 if self.Filter == "All": |
583 new_row = max(0, min(row + move, len(self.Values) - 1)) |
583 new_row = max(0, min(row + move, len(self.Values) - 1)) |
584 if new_row != row: |
584 if new_row != row: |
585 self.Values.insert(new_row, self.Values.pop(row)) |
585 self.Values.insert(new_row, self.Values.pop(row)) |
586 self.SaveValues() |
586 self.SaveValues() |
587 self.RefreshValues() |
587 self.RefreshValues() |
588 return new_row |
588 return new_row |
589 return row |
589 return row |
590 setattr(self.VariablesGrid, "_MoveRow", _MoveVariable) |
590 setattr(self.VariablesGrid, "_MoveRow", _MoveVariable) |
591 |
591 |
592 def _RefreshButtons(): |
592 def _RefreshButtons(): |
593 if self: |
593 if self: |
594 table_length = len(self.Table.data) |
594 table_length = len(self.Table.data) |
595 row_class = None |
595 row_class = None |
596 row_edit = True |
596 row_edit = True |
601 self.AddButton.Enable(not self.Debug) |
601 self.AddButton.Enable(not self.Debug) |
602 self.DeleteButton.Enable(not self.Debug and (table_length > 0 and row_edit)) |
602 self.DeleteButton.Enable(not self.Debug and (table_length > 0 and row_edit)) |
603 self.UpButton.Enable(not self.Debug and (table_length > 0 and row > 0 and self.Filter == "All")) |
603 self.UpButton.Enable(not self.Debug and (table_length > 0 and row > 0 and self.Filter == "All")) |
604 self.DownButton.Enable(not self.Debug and (table_length > 0 and row < table_length - 1 and self.Filter == "All")) |
604 self.DownButton.Enable(not self.Debug and (table_length > 0 and row < table_length - 1 and self.Filter == "All")) |
605 setattr(self.VariablesGrid, "RefreshButtons", _RefreshButtons) |
605 setattr(self.VariablesGrid, "RefreshButtons", _RefreshButtons) |
606 |
606 |
607 self.VariablesGrid.SetRowLabelSize(0) |
607 self.VariablesGrid.SetRowLabelSize(0) |
608 for col in range(self.Table.GetNumberCols()): |
608 for col in range(self.Table.GetNumberCols()): |
609 attr = wx.grid.GridCellAttr() |
609 attr = wx.grid.GridCellAttr() |
610 attr.SetAlignment(self.ColAlignements[col], wx.ALIGN_CENTRE) |
610 attr.SetAlignment(self.ColAlignements[col], wx.ALIGN_CENTRE) |
611 self.VariablesGrid.SetColAttr(col, attr) |
611 self.VariablesGrid.SetColAttr(col, attr) |
612 self.VariablesGrid.SetColMinimalWidth(col, self.ColSizes[col]) |
612 self.VariablesGrid.SetColMinimalWidth(col, self.ColSizes[col]) |
613 self.VariablesGrid.AutoSizeColumn(col, False) |
613 self.VariablesGrid.AutoSizeColumn(col, False) |
614 |
614 |
615 def __del__(self): |
615 def __del__(self): |
616 self.RefreshHighlightsTimer.Stop() |
616 self.RefreshHighlightsTimer.Stop() |
617 |
617 |
618 def SetTagName(self, tagname): |
618 def SetTagName(self, tagname): |
619 self.TagName = tagname |
619 self.TagName = tagname |
620 self.BodyType = self.Controler.GetEditedElementBodyType(self.TagName) |
620 self.BodyType = self.Controler.GetEditedElementBodyType(self.TagName) |
621 |
621 |
622 def GetTagName(self): |
622 def GetTagName(self): |
623 return self.TagName |
623 return self.TagName |
624 |
624 |
625 def IsFunctionBlockType(self, name): |
625 def IsFunctionBlockType(self, name): |
626 if (isinstance(name, TupleType) or |
626 if (isinstance(name, TupleType) or |
627 self.ElementType != "function" and self.BodyType in ["ST", "IL"]): |
627 self.ElementType != "function" and self.BodyType in ["ST", "IL"]): |
628 return False |
628 return False |
629 else: |
629 else: |
630 return self.Controler.GetBlockType(name, debug=self.Debug) is not None |
630 return self.Controler.GetBlockType(name, debug=self.Debug) is not None |
631 |
631 |
632 def RefreshView(self): |
632 def RefreshView(self): |
633 self.PouNames = self.Controler.GetProjectPouNames(self.Debug) |
633 self.PouNames = self.Controler.GetProjectPouNames(self.Debug) |
634 returnType = None |
634 returnType = None |
635 description = None |
635 description = None |
636 |
636 |
637 words = self.TagName.split("::") |
637 words = self.TagName.split("::") |
638 if self.ElementType == "config": |
638 if self.ElementType == "config": |
639 self.Values = self.Controler.GetConfigurationGlobalVars(words[1], self.Debug) |
639 self.Values = self.Controler.GetConfigurationGlobalVars(words[1], self.Debug) |
640 elif self.ElementType == "resource": |
640 elif self.ElementType == "resource": |
641 self.Values = self.Controler.GetConfigurationResourceGlobalVars(words[1], words[2], self.Debug) |
641 self.Values = self.Controler.GetConfigurationResourceGlobalVars(words[1], words[2], self.Debug) |
645 for data_type in self.Controler.GetDataTypes(self.TagName, debug=self.Debug): |
645 for data_type in self.Controler.GetDataTypes(self.TagName, debug=self.Debug): |
646 self.ReturnType.Append(data_type) |
646 self.ReturnType.Append(data_type) |
647 returnType = self.Controler.GetEditedElementInterfaceReturnType(self.TagName, debug=self.Debug) |
647 returnType = self.Controler.GetEditedElementInterfaceReturnType(self.TagName, debug=self.Debug) |
648 description = self.Controler.GetPouDescription(words[1]) |
648 description = self.Controler.GetPouDescription(words[1]) |
649 self.Values = self.Controler.GetEditedElementInterfaceVars(self.TagName, debug=self.Debug) |
649 self.Values = self.Controler.GetEditedElementInterfaceVars(self.TagName, debug=self.Debug) |
650 |
650 |
651 if returnType is not None: |
651 if returnType is not None: |
652 self.ReturnType.SetStringSelection(returnType) |
652 self.ReturnType.SetStringSelection(returnType) |
653 self.ReturnType.Enable(not self.Debug) |
653 self.ReturnType.Enable(not self.Debug) |
654 self.ReturnTypeLabel.Show() |
654 self.ReturnTypeLabel.Show() |
655 self.ReturnType.Show() |
655 self.ReturnType.Show() |
656 else: |
656 else: |
657 self.ReturnType.Enable(False) |
657 self.ReturnType.Enable(False) |
658 self.ReturnTypeLabel.Hide() |
658 self.ReturnTypeLabel.Hide() |
659 self.ReturnType.Hide() |
659 self.ReturnType.Hide() |
660 |
660 |
661 if description is not None: |
661 if description is not None: |
662 self.Description.SetValue(description) |
662 self.Description.SetValue(description) |
663 self.Description.Enable(not self.Debug) |
663 self.Description.Enable(not self.Debug) |
664 self.DescriptionLabel.Show() |
664 self.DescriptionLabel.Show() |
665 self.Description.Show() |
665 self.Description.Show() |
666 else: |
666 else: |
667 self.Description.Enable(False) |
667 self.Description.Enable(False) |
668 self.DescriptionLabel.Hide() |
668 self.DescriptionLabel.Hide() |
669 self.Description.Hide() |
669 self.Description.Hide() |
670 |
670 |
671 self.RefreshValues() |
671 self.RefreshValues() |
672 self.VariablesGrid.RefreshButtons() |
672 self.VariablesGrid.RefreshButtons() |
673 self.MainSizer.Layout() |
673 self.MainSizer.Layout() |
674 |
674 |
675 def OnReturnTypeChanged(self, event): |
675 def OnReturnTypeChanged(self, event): |
676 words = self.TagName.split("::") |
676 words = self.TagName.split("::") |
677 self.Controler.SetPouInterfaceReturnType(words[1], self.ReturnType.GetStringSelection()) |
677 self.Controler.SetPouInterfaceReturnType(words[1], self.ReturnType.GetStringSelection()) |
678 self.Controler.BufferProject() |
678 self.Controler.BufferProject() |
679 self.ParentWindow.RefreshView(variablepanel = False) |
679 self.ParentWindow.RefreshView(variablepanel = False) |
680 self.ParentWindow._Refresh(TITLE, FILEMENU, EDITMENU, POUINSTANCEVARIABLESPANEL, LIBRARYTREE) |
680 self.ParentWindow._Refresh(TITLE, FILEMENU, EDITMENU, POUINSTANCEVARIABLESPANEL, LIBRARYTREE) |
681 event.Skip() |
681 event.Skip() |
682 |
682 |
683 def OnDescriptionChanged(self, event): |
683 def OnDescriptionChanged(self, event): |
684 words = self.TagName.split("::") |
684 words = self.TagName.split("::") |
685 old_description = self.Controler.GetPouDescription(words[1]) |
685 old_description = self.Controler.GetPouDescription(words[1]) |
686 new_description = self.Description.GetValue() |
686 new_description = self.Description.GetValue() |
687 if new_description != old_description: |
687 if new_description != old_description: |
688 self.Controler.SetPouDescription(words[1], new_description) |
688 self.Controler.SetPouDescription(words[1], new_description) |
689 self.ParentWindow._Refresh(TITLE, FILEMENU, EDITMENU, PAGETITLES, POUINSTANCEVARIABLESPANEL, LIBRARYTREE) |
689 self.ParentWindow._Refresh(TITLE, FILEMENU, EDITMENU, PAGETITLES, POUINSTANCEVARIABLESPANEL, LIBRARYTREE) |
690 event.Skip() |
690 event.Skip() |
691 |
691 |
692 def OnClassFilter(self, event): |
692 def OnClassFilter(self, event): |
693 self.Filter = self.FilterChoiceTransfer[VARIABLE_CHOICES_DICT[self.ClassFilter.GetStringSelection()]] |
693 self.Filter = self.FilterChoiceTransfer[VARIABLE_CHOICES_DICT[self.ClassFilter.GetStringSelection()]] |
694 self.RefreshTypeList() |
694 self.RefreshTypeList() |
695 self.RefreshValues() |
695 self.RefreshValues() |
696 self.VariablesGrid.RefreshButtons() |
696 self.VariablesGrid.RefreshButtons() |
767 new_id = wx.NewId() |
767 new_id = wx.NewId() |
768 AppendMenu(datatype_menu, help='', id=new_id, kind=wx.ITEM_NORMAL, text=datatype) |
768 AppendMenu(datatype_menu, help='', id=new_id, kind=wx.ITEM_NORMAL, text=datatype) |
769 self.Bind(wx.EVT_MENU, self.GetVariableTypeFunction(datatype), id=new_id) |
769 self.Bind(wx.EVT_MENU, self.GetVariableTypeFunction(datatype), id=new_id) |
770 |
770 |
771 type_menu.AppendMenu(wx.NewId(), _("User Data Types"), datatype_menu) |
771 type_menu.AppendMenu(wx.NewId(), _("User Data Types"), datatype_menu) |
772 |
772 |
773 for category in self.Controler.GetConfNodeDataTypes(): |
773 for category in self.Controler.GetConfNodeDataTypes(): |
774 |
774 |
775 if len(category["list"]) > 0: |
775 if len(category["list"]) > 0: |
776 # build a submenu containing confnode types |
776 # build a submenu containing confnode types |
777 confnode_datatype_menu = wx.Menu(title='') |
777 confnode_datatype_menu = wx.Menu(title='') |
778 for datatype in category["list"]: |
778 for datatype in category["list"]: |
779 new_id = wx.NewId() |
779 new_id = wx.NewId() |
780 AppendMenu(confnode_datatype_menu, help='', id=new_id, kind=wx.ITEM_NORMAL, text=datatype) |
780 AppendMenu(confnode_datatype_menu, help='', id=new_id, kind=wx.ITEM_NORMAL, text=datatype) |
781 self.Bind(wx.EVT_MENU, self.GetVariableTypeFunction(datatype), id=new_id) |
781 self.Bind(wx.EVT_MENU, self.GetVariableTypeFunction(datatype), id=new_id) |
782 |
782 |
783 type_menu.AppendMenu(wx.NewId(), category["name"], confnode_datatype_menu) |
783 type_menu.AppendMenu(wx.NewId(), category["name"], confnode_datatype_menu) |
784 |
784 |
785 # build a submenu containing function block types |
785 # build a submenu containing function block types |
786 bodytype = self.Controler.GetEditedElementBodyType(self.TagName) |
786 bodytype = self.Controler.GetEditedElementBodyType(self.TagName) |
787 pouname, poutype = self.Controler.GetEditedElementType(self.TagName) |
787 pouname, poutype = self.Controler.GetEditedElementType(self.TagName) |
788 classtype = self.Table.GetValueByName(row, "Class") |
788 classtype = self.Table.GetValueByName(row, "Class") |
789 |
789 |
790 new_id = wx.NewId() |
790 new_id = wx.NewId() |
791 AppendMenu(type_menu, help='', id=new_id, kind=wx.ITEM_NORMAL, text=_("Array")) |
791 AppendMenu(type_menu, help='', id=new_id, kind=wx.ITEM_NORMAL, text=_("Array")) |
792 self.Bind(wx.EVT_MENU, self.VariableArrayTypeFunction, id=new_id) |
792 self.Bind(wx.EVT_MENU, self.VariableArrayTypeFunction, id=new_id) |
793 |
793 |
794 if classtype in ["Input", "Output", "InOut", "External", "Global"] or \ |
794 if classtype in ["Input", "Output", "InOut", "External", "Global"] or \ |
795 poutype != "function" and bodytype in ["ST", "IL"]: |
795 poutype != "function" and bodytype in ["ST", "IL"]: |
796 functionblock_menu = wx.Menu(title='') |
796 functionblock_menu = wx.Menu(title='') |
797 fbtypes = self.Controler.GetFunctionBlockTypes(self.TagName) |
797 fbtypes = self.Controler.GetFunctionBlockTypes(self.TagName) |
798 for functionblock_type in fbtypes: |
798 for functionblock_type in fbtypes: |
810 self.VariablesGrid.PopupMenuXY(type_menu, corner_x, corner_y) |
810 self.VariablesGrid.PopupMenuXY(type_menu, corner_x, corner_y) |
811 type_menu.Destroy() |
811 type_menu.Destroy() |
812 event.Veto() |
812 event.Veto() |
813 else: |
813 else: |
814 event.Skip() |
814 event.Skip() |
815 |
815 |
816 def GetVariableTypeFunction(self, base_type): |
816 def GetVariableTypeFunction(self, base_type): |
817 def VariableTypeFunction(event): |
817 def VariableTypeFunction(event): |
818 row = self.VariablesGrid.GetGridCursorRow() |
818 row = self.VariablesGrid.GetGridCursorRow() |
819 self.Table.SetValueByName(row, "Type", base_type) |
819 self.Table.SetValueByName(row, "Type", base_type) |
820 self.Table.ResetView(self.VariablesGrid) |
820 self.Table.ResetView(self.VariablesGrid) |
821 self.SaveValues(False) |
821 self.SaveValues(False) |
822 self.ParentWindow.RefreshView(variablepanel = False) |
822 self.ParentWindow.RefreshView(variablepanel = False) |
823 self.Controler.BufferProject() |
823 self.Controler.BufferProject() |
824 self.ParentWindow._Refresh(TITLE, FILEMENU, EDITMENU, PAGETITLES, POUINSTANCEVARIABLESPANEL, LIBRARYTREE) |
824 self.ParentWindow._Refresh(TITLE, FILEMENU, EDITMENU, PAGETITLES, POUINSTANCEVARIABLESPANEL, LIBRARYTREE) |
825 return VariableTypeFunction |
825 return VariableTypeFunction |
826 |
826 |
827 def VariableArrayTypeFunction(self, event): |
827 def VariableArrayTypeFunction(self, event): |
828 row = self.VariablesGrid.GetGridCursorRow() |
828 row = self.VariablesGrid.GetGridCursorRow() |
829 dialog = ArrayTypeDialog(self, |
829 dialog = ArrayTypeDialog(self, |
830 self.Controler.GetDataTypes(self.TagName), |
830 self.Controler.GetDataTypes(self.TagName), |
831 self.Table.GetValueByName(row, "Type")) |
831 self.Table.GetValueByName(row, "Type")) |
832 if dialog.ShowModal() == wx.ID_OK: |
832 if dialog.ShowModal() == wx.ID_OK: |
833 self.Table.SetValueByName(row, "Type", dialog.GetValue()) |
833 self.Table.SetValueByName(row, "Type", dialog.GetValue()) |
834 self.Table.ResetView(self.VariablesGrid) |
834 self.Table.ResetView(self.VariablesGrid) |
835 self.SaveValues(False) |
835 self.SaveValues(False) |
836 self.ParentWindow.RefreshView(variablepanel = False) |
836 self.ParentWindow.RefreshView(variablepanel = False) |
837 self.Controler.BufferProject() |
837 self.Controler.BufferProject() |
838 self.ParentWindow._Refresh(TITLE, FILEMENU, EDITMENU, PAGETITLES, POUINSTANCEVARIABLESPANEL, LIBRARYTREE) |
838 self.ParentWindow._Refresh(TITLE, FILEMENU, EDITMENU, PAGETITLES, POUINSTANCEVARIABLESPANEL, LIBRARYTREE) |
839 dialog.Destroy() |
839 dialog.Destroy() |
840 |
840 |
841 def OnVariablesGridCellLeftClick(self, event): |
841 def OnVariablesGridCellLeftClick(self, event): |
842 row = event.GetRow() |
842 row = event.GetRow() |
843 if not self.Debug and (event.GetCol() == 0 and self.Table.GetValueByName(row, "Edit")): |
843 if not self.Debug and (event.GetCol() == 0 and self.Table.GetValueByName(row, "Edit")): |
844 var_name = self.Table.GetValueByName(row, "Name") |
844 var_name = self.Table.GetValueByName(row, "Name") |
845 var_class = self.Table.GetValueByName(row, "Class") |
845 var_class = self.Table.GetValueByName(row, "Class") |