87 "Global": lambda x: {"Constant": "Constant", "Retain": "Retain"}.get(x, ""), |
87 "Global": lambda x: {"Constant": "Constant", "Retain": "Retain"}.get(x, ""), |
88 "External": lambda x: {"Constant": "Constant"}.get(x, "") |
88 "External": lambda x: {"Constant": "Constant"}.get(x, "") |
89 } |
89 } |
90 |
90 |
91 LOCATION_MODEL = re.compile("((?:%[IQM](?:\*|(?:[XBWLD]?[0-9]+(?:\.[0-9]+)*)))?)$") |
91 LOCATION_MODEL = re.compile("((?:%[IQM](?:\*|(?:[XBWLD]?[0-9]+(?:\.[0-9]+)*)))?)$") |
|
92 VARIABLE_NAME_SUFFIX_MODEL = re.compile("([0-9]*)$") |
92 |
93 |
93 #------------------------------------------------------------------------------- |
94 #------------------------------------------------------------------------------- |
94 # Variables Panel Table |
95 # Variables Panel Table |
95 #------------------------------------------------------------------------------- |
96 #------------------------------------------------------------------------------- |
96 |
97 |
164 else: |
165 else: |
165 grid.SetReadOnly(row, col, True) |
166 grid.SetReadOnly(row, col, True) |
166 elif col != 0 and self.GetValueByName(row, "Edit"): |
167 elif col != 0 and self.GetValueByName(row, "Edit"): |
167 grid.SetReadOnly(row, col, False) |
168 grid.SetReadOnly(row, col, False) |
168 if colname == "Name": |
169 if colname == "Name": |
169 if self.Parent.PouIsUsed and var_class in ["Input", "Output", "InOut"]: |
170 editor = wx.grid.GridCellTextEditor() |
170 grid.SetReadOnly(row, col, True) |
171 renderer = wx.grid.GridCellStringRenderer() |
171 else: |
|
172 editor = wx.grid.GridCellTextEditor() |
|
173 renderer = wx.grid.GridCellStringRenderer() |
|
174 elif colname == "Initial Value": |
172 elif colname == "Initial Value": |
175 if var_class not in ["External", "InOut"]: |
173 if var_class not in ["External", "InOut"]: |
176 if self.Parent.Controler.IsEnumeratedType(var_type): |
174 if self.Parent.Controler.IsEnumeratedType(var_type): |
177 editor = wx.grid.GridCellChoiceEditor() |
175 editor = wx.grid.GridCellChoiceEditor() |
178 editor.SetParameters(",".join(self.Parent.Controler.GetEnumeratedDataValues(var_type))) |
176 editor.SetParameters(",".join(self.Parent.Controler.GetEnumeratedDataValues(var_type))) |
186 editor = LocationCellEditor(self, self.Parent.Controler) |
184 editor = LocationCellEditor(self, self.Parent.Controler) |
187 renderer = wx.grid.GridCellStringRenderer() |
185 renderer = wx.grid.GridCellStringRenderer() |
188 else: |
186 else: |
189 grid.SetReadOnly(row, col, True) |
187 grid.SetReadOnly(row, col, True) |
190 elif colname == "Class": |
188 elif colname == "Class": |
191 if len(self.Parent.ClassList) == 1 or self.Parent.PouIsUsed and var_class in ["Input", "Output", "InOut"]: |
189 if len(self.Parent.ClassList) == 1: |
192 grid.SetReadOnly(row, col, True) |
190 grid.SetReadOnly(row, col, True) |
193 else: |
191 else: |
194 editor = wx.grid.GridCellChoiceEditor() |
192 editor = wx.grid.GridCellChoiceEditor() |
195 excluded = [] |
193 excluded = [] |
196 if self.Parent.PouIsUsed: |
|
197 excluded.extend(["Input","Output","InOut"]) |
|
198 if self.Parent.IsFunctionBlockType(var_type): |
194 if self.Parent.IsFunctionBlockType(var_type): |
199 excluded.extend(["Local","Temp"]) |
195 excluded.extend(["Local","Temp"]) |
200 editor.SetParameters(",".join([_(choice) for choice in self.Parent.ClassList if choice not in excluded])) |
196 editor.SetParameters(",".join([_(choice) for choice in self.Parent.ClassList if choice not in excluded])) |
201 elif colname != "Documentation": |
197 elif colname != "Documentation": |
202 grid.SetReadOnly(row, col, True) |
198 grid.SetReadOnly(row, col, True) |
300 message = _("Can't set an initial value to a function block instance") |
296 message = _("Can't set an initial value to a function block instance") |
301 else: |
297 else: |
302 self.ParentWindow.Table.SetValue(row, col, values[0]) |
298 self.ParentWindow.Table.SetValue(row, col, values[0]) |
303 self.ParentWindow.Table.ResetView(self.ParentWindow.VariablesGrid) |
299 self.ParentWindow.Table.ResetView(self.ParentWindow.VariablesGrid) |
304 self.ParentWindow.SaveValues() |
300 self.ParentWindow.SaveValues() |
305 elif (element_type not in ["config", "resource"] and values[1] == "Global" and self.ParentWindow.Filter in ["All", "Interface", "External"] or |
301 elif (element_type not in ["config", "resource", "function"] and values[1] == "Global" and |
306 element_type in ["config", "resource"] and values[1] == "location"): |
302 self.ParentWindow.Filter in ["All", "Interface", "External"] or |
|
303 element_type != "function" and values[1] == "location"): |
307 if values[1] == "location": |
304 if values[1] == "location": |
308 var_name = values[3] |
305 var_name = values[3] |
309 else: |
306 else: |
310 var_name = values[0] |
307 var_name = values[0] |
311 tagname = self.ParentWindow.GetTagName() |
308 tagname = self.ParentWindow.GetTagName() |
312 if var_name.upper() in [name.upper() for name in self.ParentWindow.Controler.GetProjectPouNames(self.ParentWindow.Debug)]: |
309 if var_name.upper() in [name.upper() |
|
310 for name in self.ParentWindow.Controler.\ |
|
311 GetProjectPouNames(self.ParentWindow.Debug)]: |
313 message = _("\"%s\" pou already exists!")%var_name |
312 message = _("\"%s\" pou already exists!")%var_name |
314 elif not var_name.upper() in [name.upper() for name in self.ParentWindow.Controler.GetEditedElementVariables(tagname, self.ParentWindow.Debug)]: |
313 elif not var_name.upper() in [name.upper() |
|
314 for name in self.ParentWindow.Controler.\ |
|
315 GetEditedElementVariables(tagname, self.ParentWindow.Debug)]: |
315 var_infos = self.ParentWindow.DefaultValue.copy() |
316 var_infos = self.ParentWindow.DefaultValue.copy() |
316 var_infos["Name"] = var_name |
317 var_infos["Name"] = var_name |
317 var_infos["Type"] = values[2] |
318 var_infos["Type"] = values[2] |
318 if values[1] == "location": |
319 if values[1] == "location": |
319 var_infos["Class"] = "Global" |
320 location = values[0] |
320 var_infos["Location"] = values[0] |
321 if not location.startswith("%"): |
|
322 dialog = wx.SingleChoiceDialog(self.ParentWindow.ParentWindow.ParentWindow, |
|
323 _("Select a variable class:"), _("Variable class"), |
|
324 ["Input", "Output", "Memory"], |
|
325 wx.DEFAULT_DIALOG_STYLE|wx.OK|wx.CANCEL) |
|
326 if dialog.ShowModal() == wx.ID_OK: |
|
327 selected = dialog.GetSelection() |
|
328 else: |
|
329 selected = None |
|
330 dialog.Destroy() |
|
331 if selected is None: |
|
332 return |
|
333 if selected == 0: |
|
334 location = "%I" + location |
|
335 elif selected == 1: |
|
336 location = "%Q" + location |
|
337 else: |
|
338 location = "%M" + location |
|
339 if element_type == "functionBlock": |
|
340 configs = self.ParentWindow.Controler.GetProjectConfigNames( |
|
341 self.ParentWindow.Debug) |
|
342 if len(configs) == 0: |
|
343 return |
|
344 if not var_name.upper() in [name.upper() |
|
345 for name in self.ParentWindow.Controler.\ |
|
346 GetConfigurationVariableNames(configs[0])]: |
|
347 self.ParentWindow.Controler.AddConfigurationGlobalVar( |
|
348 configs[0], values[2], var_name, location, "") |
|
349 var_infos["Class"] = "External" |
|
350 else: |
|
351 if element_type == "program": |
|
352 var_infos["Class"] = "Local" |
|
353 else: |
|
354 var_infos["Class"] = "Global" |
|
355 var_infos["Location"] = location |
321 else: |
356 else: |
322 var_infos["Class"] = "External" |
357 var_infos["Class"] = "External" |
323 var_infos["Number"] = len(self.ParentWindow.Values) |
358 var_infos["Number"] = len(self.ParentWindow.Values) |
324 self.ParentWindow.Values.append(var_infos) |
359 self.ParentWindow.Values.append(var_infos) |
325 self.ParentWindow.SaveValues() |
360 self.ParentWindow.SaveValues() |
484 "Up": self.UpButton, |
519 "Up": self.UpButton, |
485 "Down": self.DownButton}) |
520 "Down": self.DownButton}) |
486 self.VariablesGrid.SetEditable(not self.Debug) |
521 self.VariablesGrid.SetEditable(not self.Debug) |
487 |
522 |
488 def _AddVariable(new_row): |
523 def _AddVariable(new_row): |
489 if not self.PouIsUsed or self.Filter not in ["Interface", "Input", "Output", "InOut"]: |
524 if new_row > 0: |
|
525 row_content = self.Values[new_row - 1].copy() |
|
526 |
|
527 result = VARIABLE_NAME_SUFFIX_MODEL.search(row_content["Name"]) |
|
528 if result is not None: |
|
529 name = row_content["Name"][:result.start(1)] |
|
530 suffix = result.group(1) |
|
531 if suffix != "": |
|
532 start_idx = int(suffix) |
|
533 else: |
|
534 start_idx = 0 |
|
535 else: |
|
536 name = row_content["Name"] |
|
537 start_idx = 0 |
|
538 else: |
|
539 row_content = None |
|
540 start_idx = 0 |
|
541 name = "LocalVar" |
|
542 |
|
543 if row_content is not None and row_content["Edit"]: |
|
544 row_content = self.Values[new_row - 1].copy() |
|
545 else: |
490 row_content = self.DefaultValue.copy() |
546 row_content = self.DefaultValue.copy() |
491 if self.Filter in self.DefaultTypes: |
547 if self.Filter in self.DefaultTypes: |
492 row_content["Class"] = self.DefaultTypes[self.Filter] |
548 row_content["Class"] = self.DefaultTypes[self.Filter] |
493 else: |
549 else: |
494 row_content["Class"] = self.Filter |
550 row_content["Class"] = self.Filter |
495 if self.Filter == "All" and len(self.Values) > 0: |
551 |
496 self.Values.insert(new_row, row_content) |
552 row_content["Name"] = self.Controler.GenerateNewName( |
497 else: |
553 self.TagName, None, name + "%d", start_idx) |
498 self.Values.append(row_content) |
554 |
499 new_row = self.Table.GetNumberRows() |
555 if self.Filter == "All" and len(self.Values) > 0: |
500 self.SaveValues() |
556 self.Values.insert(new_row, row_content) |
501 self.RefreshValues() |
557 else: |
502 return new_row |
558 self.Values.append(row_content) |
503 return self.VariablesGrid.GetGridCursorRow() |
559 new_row = self.Table.GetNumberRows() |
|
560 self.SaveValues() |
|
561 self.RefreshValues() |
|
562 return new_row |
504 setattr(self.VariablesGrid, "_AddRow", _AddVariable) |
563 setattr(self.VariablesGrid, "_AddRow", _AddVariable) |
505 |
564 |
506 def _DeleteVariable(row): |
565 def _DeleteVariable(row): |
507 if (self.Table.GetValueByName(row, "Edit") and |
566 if self.Table.GetValueByName(row, "Edit"): |
508 (not self.PouIsUsed or self.Table.GetValueByName(row, "Class") not in ["Input", "Output", "InOut"])): |
|
509 self.Values.remove(self.Table.GetRow(row)) |
567 self.Values.remove(self.Table.GetRow(row)) |
510 self.SaveValues() |
568 self.SaveValues() |
511 self.RefreshValues() |
569 self.RefreshValues() |
512 setattr(self.VariablesGrid, "_DeleteRow", _DeleteVariable) |
570 setattr(self.VariablesGrid, "_DeleteRow", _DeleteVariable) |
513 |
571 |
514 def _MoveVariable(row, move): |
572 def _MoveVariable(row, move): |
515 if (self.Filter == "All" and |
573 if self.Filter == "All": |
516 (not self.PouIsUsed or self.Table.GetValueByName(row, "Class") not in ["Input", "Output", "InOut"])): |
|
517 new_row = max(0, min(row + move, len(self.Values) - 1)) |
574 new_row = max(0, min(row + move, len(self.Values) - 1)) |
518 if new_row != row: |
575 if new_row != row: |
519 self.Values.insert(new_row, self.Values.pop(row)) |
576 self.Values.insert(new_row, self.Values.pop(row)) |
520 self.SaveValues() |
577 self.SaveValues() |
521 self.RefreshValues() |
578 self.RefreshValues() |
530 row_edit = True |
587 row_edit = True |
531 row = 0 |
588 row = 0 |
532 if table_length > 0: |
589 if table_length > 0: |
533 row = self.VariablesGrid.GetGridCursorRow() |
590 row = self.VariablesGrid.GetGridCursorRow() |
534 row_edit = self.Table.GetValueByName(row, "Edit") |
591 row_edit = self.Table.GetValueByName(row, "Edit") |
535 if self.PouIsUsed: |
592 self.AddButton.Enable(not self.Debug) |
536 row_class = self.Table.GetValueByName(row, "Class") |
593 self.DeleteButton.Enable(not self.Debug and (table_length > 0 and row_edit)) |
537 self.AddButton.Enable(not self.Debug and (not self.PouIsUsed or self.Filter not in ["Interface", "Input", "Output", "InOut"])) |
594 self.UpButton.Enable(not self.Debug and (table_length > 0 and row > 0 and self.Filter == "All")) |
538 self.DeleteButton.Enable(not self.Debug and (table_length > 0 and row_edit and row_class not in ["Input", "Output", "InOut"])) |
595 self.DownButton.Enable(not self.Debug and (table_length > 0 and row < table_length - 1 and self.Filter == "All")) |
539 self.UpButton.Enable(not self.Debug and (table_length > 0 and row > 0 and self.Filter == "All" and row_class not in ["Input", "Output", "InOut"])) |
|
540 self.DownButton.Enable(not self.Debug and (table_length > 0 and row < table_length - 1 and self.Filter == "All" and row_class not in ["Input", "Output", "InOut"])) |
|
541 setattr(self.VariablesGrid, "RefreshButtons", _RefreshButtons) |
596 setattr(self.VariablesGrid, "RefreshButtons", _RefreshButtons) |
542 |
597 |
543 self.VariablesGrid.SetRowLabelSize(0) |
598 self.VariablesGrid.SetRowLabelSize(0) |
544 for col in range(self.Table.GetNumberCols()): |
599 for col in range(self.Table.GetNumberCols()): |
545 attr = wx.grid.GridCellAttr() |
600 attr = wx.grid.GridCellAttr() |
570 returnType = None |
625 returnType = None |
571 description = None |
626 description = None |
572 |
627 |
573 words = self.TagName.split("::") |
628 words = self.TagName.split("::") |
574 if self.ElementType == "config": |
629 if self.ElementType == "config": |
575 self.PouIsUsed = False |
|
576 self.Values = self.Controler.GetConfigurationGlobalVars(words[1], self.Debug) |
630 self.Values = self.Controler.GetConfigurationGlobalVars(words[1], self.Debug) |
577 elif self.ElementType == "resource": |
631 elif self.ElementType == "resource": |
578 self.PouIsUsed = False |
|
579 self.Values = self.Controler.GetConfigurationResourceGlobalVars(words[1], words[2], self.Debug) |
632 self.Values = self.Controler.GetConfigurationResourceGlobalVars(words[1], words[2], self.Debug) |
580 else: |
633 else: |
581 if self.ElementType == "function": |
634 if self.ElementType == "function": |
582 self.ReturnType.Clear() |
635 self.ReturnType.Clear() |
583 for data_type in self.Controler.GetDataTypes(self.TagName, debug=self.Debug): |
636 for data_type in self.Controler.GetDataTypes(self.TagName, debug=self.Debug): |
584 self.ReturnType.Append(data_type) |
637 self.ReturnType.Append(data_type) |
585 returnType = self.Controler.GetEditedElementInterfaceReturnType(self.TagName) |
638 returnType = self.Controler.GetEditedElementInterfaceReturnType(self.TagName) |
586 description = self.Controler.GetPouDescription(words[1]) |
639 description = self.Controler.GetPouDescription(words[1]) |
587 self.PouIsUsed = self.Controler.PouIsUsed(words[1]) |
|
588 self.Values = self.Controler.GetEditedElementInterfaceVars(self.TagName, self.Debug) |
640 self.Values = self.Controler.GetEditedElementInterfaceVars(self.TagName, self.Debug) |
589 |
641 |
590 if returnType is not None: |
642 if returnType is not None: |
591 self.ReturnType.SetStringSelection(returnType) |
643 self.ReturnType.SetStringSelection(returnType) |
592 self.ReturnType.Enable(not self.Debug) |
644 self.ReturnType.Enable(not self.Debug) |
623 words = self.TagName.split("::") |
675 words = self.TagName.split("::") |
624 old_description = self.Controler.GetPouDescription(words[1]) |
676 old_description = self.Controler.GetPouDescription(words[1]) |
625 new_description = self.Description.GetValue() |
677 new_description = self.Description.GetValue() |
626 if new_description != old_description: |
678 if new_description != old_description: |
627 self.Controler.SetPouDescription(words[1], new_description) |
679 self.Controler.SetPouDescription(words[1], new_description) |
628 self.ParentWindow._Refresh(TITLE, FILEMENU, EDITMENU, POUINSTANCEVARIABLESPANEL, LIBRARYTREE) |
680 self.ParentWindow._Refresh(TITLE, FILEMENU, EDITMENU, PAGETITLES, POUINSTANCEVARIABLESPANEL, LIBRARYTREE) |
629 event.Skip() |
681 event.Skip() |
630 |
682 |
631 def OnClassFilter(self, event): |
683 def OnClassFilter(self, event): |
632 self.Filter = self.FilterChoiceTransfer[VARIABLE_CHOICES_DICT[self.ClassFilter.GetStringSelection()]] |
684 self.Filter = self.FilterChoiceTransfer[VARIABLE_CHOICES_DICT[self.ClassFilter.GetStringSelection()]] |
633 self.RefreshTypeList() |
685 self.RefreshTypeList() |
664 self.SaveValues(False) |
716 self.SaveValues(False) |
665 old_value = self.Table.GetOldValue() |
717 old_value = self.Table.GetOldValue() |
666 if old_value != "": |
718 if old_value != "": |
667 self.Controler.UpdateEditedElementUsedVariable(self.TagName, old_value, value) |
719 self.Controler.UpdateEditedElementUsedVariable(self.TagName, old_value, value) |
668 self.Controler.BufferProject() |
720 self.Controler.BufferProject() |
669 self.ParentWindow.RefreshView(variablepanel = False) |
721 wx.CallAfter(self.ParentWindow.RefreshView, False) |
670 self.ParentWindow._Refresh(TITLE, FILEMENU, EDITMENU, POUINSTANCEVARIABLESPANEL, LIBRARYTREE) |
722 self.ParentWindow._Refresh(TITLE, FILEMENU, EDITMENU, PAGETITLES, POUINSTANCEVARIABLESPANEL, LIBRARYTREE) |
671 event.Skip() |
|
672 else: |
723 else: |
673 self.SaveValues() |
724 self.SaveValues() |
674 if colname == "Class": |
725 if colname == "Class": |
675 self.ParentWindow.RefreshView(variablepanel = False) |
726 wx.CallAfter(self.ParentWindow.RefreshView, False) |
676 elif colname == "Location": |
727 elif colname == "Location": |
677 wx.CallAfter(self.ParentWindow.RefreshView) |
728 wx.CallAfter(self.ParentWindow.RefreshView) |
678 |
729 |
679 if message is not None: |
730 if message is not None: |
680 dialog = wx.MessageDialog(self, message, _("Error"), wx.OK|wx.ICON_ERROR) |
731 dialog = wx.MessageDialog(self, message, _("Error"), wx.OK|wx.ICON_ERROR) |
759 self.Table.SetValueByName(row, "Type", base_type) |
810 self.Table.SetValueByName(row, "Type", base_type) |
760 self.Table.ResetView(self.VariablesGrid) |
811 self.Table.ResetView(self.VariablesGrid) |
761 self.SaveValues(False) |
812 self.SaveValues(False) |
762 self.ParentWindow.RefreshView(variablepanel = False) |
813 self.ParentWindow.RefreshView(variablepanel = False) |
763 self.Controler.BufferProject() |
814 self.Controler.BufferProject() |
764 self.ParentWindow._Refresh(TITLE, FILEMENU, EDITMENU, POUINSTANCEVARIABLESPANEL, LIBRARYTREE) |
815 self.ParentWindow._Refresh(TITLE, FILEMENU, EDITMENU, PAGETITLES, POUINSTANCEVARIABLESPANEL, LIBRARYTREE) |
765 return VariableTypeFunction |
816 return VariableTypeFunction |
766 |
817 |
767 def VariableArrayTypeFunction(self, event): |
818 def VariableArrayTypeFunction(self, event): |
768 row = self.VariablesGrid.GetGridCursorRow() |
819 row = self.VariablesGrid.GetGridCursorRow() |
769 dialog = ArrayTypeDialog(self, |
820 dialog = ArrayTypeDialog(self, |
773 self.Table.SetValueByName(row, "Type", dialog.GetValue()) |
824 self.Table.SetValueByName(row, "Type", dialog.GetValue()) |
774 self.Table.ResetView(self.VariablesGrid) |
825 self.Table.ResetView(self.VariablesGrid) |
775 self.SaveValues(False) |
826 self.SaveValues(False) |
776 self.ParentWindow.RefreshView(variablepanel = False) |
827 self.ParentWindow.RefreshView(variablepanel = False) |
777 self.Controler.BufferProject() |
828 self.Controler.BufferProject() |
778 self.ParentWindow._Refresh(TITLE, FILEMENU, EDITMENU, POUINSTANCEVARIABLESPANEL, LIBRARYTREE) |
829 self.ParentWindow._Refresh(TITLE, FILEMENU, EDITMENU, PAGETITLES, POUINSTANCEVARIABLESPANEL, LIBRARYTREE) |
779 dialog.Destroy() |
830 dialog.Destroy() |
780 |
831 |
781 def OnVariablesGridCellLeftClick(self, event): |
832 def OnVariablesGridCellLeftClick(self, event): |
782 row = event.GetRow() |
833 row = event.GetRow() |
783 if not self.Debug and (event.GetCol() == 0 and self.Table.GetValueByName(row, "Edit")): |
834 if not self.Debug and (event.GetCol() == 0 and self.Table.GetValueByName(row, "Edit")): |
809 if self.ReturnType.IsEnabled(): |
860 if self.ReturnType.IsEnabled(): |
810 self.Controler.SetPouInterfaceReturnType(words[1], self.ReturnType.GetStringSelection()) |
861 self.Controler.SetPouInterfaceReturnType(words[1], self.ReturnType.GetStringSelection()) |
811 self.Controler.SetPouInterfaceVars(words[1], self.Values) |
862 self.Controler.SetPouInterfaceVars(words[1], self.Values) |
812 if buffer: |
863 if buffer: |
813 self.Controler.BufferProject() |
864 self.Controler.BufferProject() |
814 self.ParentWindow._Refresh(TITLE, FILEMENU, EDITMENU, POUINSTANCEVARIABLESPANEL, LIBRARYTREE) |
865 self.ParentWindow._Refresh(TITLE, FILEMENU, EDITMENU, PAGETITLES, POUINSTANCEVARIABLESPANEL, LIBRARYTREE) |
815 |
866 |
816 #------------------------------------------------------------------------------- |
867 #------------------------------------------------------------------------------- |
817 # Highlights showing functions |
868 # Highlights showing functions |
818 #------------------------------------------------------------------------------- |
869 #------------------------------------------------------------------------------- |
819 |
870 |