PLCOpenEditor.py
changeset 37 256eedd275d0
parent 28 fc23e1f415d8
child 41 0688db995ddf
equal deleted inserted replaced
36:e7d67b27877f 37:256eedd275d0
   882             while item_type not in [ITEM_POU, ITEM_RESOURCE, ITEM_CONFIGURATION] and item.IsOk():
   882             while item_type not in [ITEM_POU, ITEM_RESOURCE, ITEM_CONFIGURATION] and item.IsOk():
   883                 item = self.ProjectTree.GetItemParent(item)
   883                 item = self.ProjectTree.GetItemParent(item)
   884                 item_type = self.ProjectTree.GetPyData(item)
   884                 item_type = self.ProjectTree.GetPyData(item)
   885             item_name = self.ProjectTree.GetItemText(item)
   885             item_name = self.ProjectTree.GetItemText(item)
   886             if item_type == ITEM_POU:
   886             if item_type == ITEM_POU:
   887                 dialog = EditVariableDialog(self, item_name, self.Controler.GetPouType(item_name), name)
   887                 dialog = EditVariableDialog(self, item_name, self.Controler.GetPouType(item_name), self.Controler.PouIsUsed(item_name), name)
   888                 dialog.SetPouNames(self.Controler.GetProjectPouNames())
   888                 dialog.SetPouNames(self.Controler.GetProjectPouNames())
   889                 values = {}
   889                 values = {}
   890                 values["returnType"] = self.Controler.GetPouInterfaceReturnTypeByName(item_name)
   890                 values["returnType"] = self.Controler.GetPouInterfaceReturnTypeByName(item_name)
   891                 values["data"] = self.Controler.GetPouInterfaceVarsByName(item_name)
   891                 values["data"] = self.Controler.GetPouInterfaceVarsByName(item_name)
   892                 dialog.SetValues(values)
   892                 dialog.SetValues(values)
   893                 if dialog.ShowModal() == wxID_OK:
   893                 if dialog.ShowModal() == wxID_OK:
   894                     if not self.Controler.PouIsUsed(item_name):
   894                     new_values = dialog.GetValues()
   895                         new_values = dialog.GetValues()
   895                     if "returnType" in new_values:
   896                         if "returnType" in new_values:
   896                         self.Controler.SetPouInterfaceReturnType(item_name, new_values["returnType"])
   897                             self.Controler.SetPouInterfaceReturnType(item_name, new_values["returnType"])
   897                     self.Controler.SetPouInterfaceVars(item_name, new_values["data"])
   898                         self.Controler.SetPouInterfaceVars(item_name, new_values["data"])
   898                     pou_names = self.Controler.GetElementsOpenedNames()
   899                         pou_names = self.Controler.GetElementsOpenedNames()
   899                     if item_name in pou_names:
   900                         if item_name in pou_names:
   900                         window = self.TabsOpened.GetPage(pou_names.index(item_name))
   901                             window = self.TabsOpened.GetPage(pou_names.index(item_name))
   901                         if isinstance(window, TextViewer):
   902                             if isinstance(window, TextViewer):
   902                             varlist = []
   903                                 varlist = []
   903                             if "returnType" in new_values:
   904                                 if "returnType" in new_values:
   904                                 varlist.append(name)
   905                                     varlist.append(name)
   905                             for var in new_values["data"]:
   906                                 for var in new_values["data"]:
   906                                 varlist.append(var["Name"])
   907                                     varlist.append(var["Name"])
   907                             window.SetVariables(varlist)
   908                                 window.SetVariables(varlist)
       
   909                     else:
       
   910                         message = wxMessageDialog(self, "\"%s\" is used by one or more POUs. Its interface can't be changed!"%pou_name, "Error", wxOK|wxICON_ERROR)
       
   911                         message.ShowModal()
       
   912                         message.Destroy()
       
   913                 dialog.Destroy()
   908                 dialog.Destroy()
   914                 self.RefreshProjectTree()
   909                 self.RefreshProjectTree()
   915             elif item_type == ITEM_CONFIGURATION:
   910             elif item_type == ITEM_CONFIGURATION:
   916                 dialog = EditVariableDialog(self, item_name, None, name)
   911                 dialog = EditVariableDialog(self, item_name, None, name)
   917                 dialog.SetPouNames(self.Controler.GetProjectPouNames())
   912                 dialog.SetPouNames(self.Controler.GetProjectPouNames())
  1904             for col in range(self.GetNumberCols()):
  1899             for col in range(self.GetNumberCols()):
  1905                 editor = None
  1900                 editor = None
  1906                 renderer = None
  1901                 renderer = None
  1907                 colname = self.GetColLabelValue(col)
  1902                 colname = self.GetColLabelValue(col)
  1908                 grid.SetReadOnly(row, col, False)
  1903                 grid.SetReadOnly(row, col, False)
  1909                 if colname in ["Name","Initial Value","Location"]:
  1904                 if colname == "Name":
  1910                     editor = wxGridCellTextEditor()
  1905                     if self.Parent.PouIsUsed and self.GetValueByName(row, "Class") in ["Input", "Output", "InOut"]:
  1911                     renderer = wxGridCellStringRenderer()    
       
  1912                 elif colname == "Class":
       
  1913                     if len(self.Parent.ClassList) == 1:
       
  1914                         grid.SetReadOnly(row, col, True)
  1906                         grid.SetReadOnly(row, col, True)
  1915                     else:
  1907                     else:
  1916                         editor = wxGridCellChoiceEditor()    
  1908                         editor = wxGridCellTextEditor()
  1917                         editor.SetParameters(",".join(self.Parent.ClassList))
  1909                         renderer = wxGridCellStringRenderer()
       
  1910                 if colname in ["Initial Value","Location"]:
       
  1911                     editor = wxGridCellTextEditor()
       
  1912                     renderer = wxGridCellStringRenderer()
       
  1913                 elif colname == "Class":
       
  1914                     if len(self.Parent.ClassList) == 1 or self.Parent.PouIsUsed and self.GetValueByName(row, "Class") in ["Input", "Output", "InOut"]:
       
  1915                         grid.SetReadOnly(row, col, True)
       
  1916                     else:
       
  1917                         editor = wxGridCellChoiceEditor()
       
  1918                         excluded = []
       
  1919                         if self.Parent.PouIsUsed:
       
  1920                             excluded.extend(["Input","Output","InOut"])    
       
  1921                         editor.SetParameters(",".join([choice for choice in self.Parent.ClassList if choice not in excluded]))
  1918                 elif colname == "Type":
  1922                 elif colname == "Type":
  1919                     editor = wxGridCellChoiceEditor()
  1923                     if self.Parent.PouIsUsed and self.GetValueByName(row, "Class") in ["Input", "Output", "InOut"]:
  1920                     editor.SetParameters(self.Parent.TypeList)
  1924                         grid.SetReadOnly(row, col, True)
       
  1925                     else:
       
  1926                         editor = wxGridCellChoiceEditor()
       
  1927                         editor.SetParameters(self.Parent.TypeList)
  1921                 elif colname in ["Retain", "Constant"]:
  1928                 elif colname in ["Retain", "Constant"]:
  1922                     editor = wxGridCellChoiceEditor()
  1929                     editor = wxGridCellChoiceEditor()
  1923                     editor.SetParameters(self.Parent.OptionList)
  1930                     editor.SetParameters(self.Parent.OptionList)
  1924                     
  1931                     
  1925                 grid.SetCellEditor(row, col, editor)
  1932                 grid.SetCellEditor(row, col, editor)
  2016         self.VariablesGrid.SetLabelFont(wx.Font(10, 77, wx.NORMAL, wx.NORMAL,
  2023         self.VariablesGrid.SetLabelFont(wx.Font(10, 77, wx.NORMAL, wx.NORMAL,
  2017               False, 'Sans'))
  2024               False, 'Sans'))
  2018         self.VariablesGrid.DisableDragGridSize()
  2025         self.VariablesGrid.DisableDragGridSize()
  2019         self.VariablesGrid.EnableScrolling(False, True)
  2026         self.VariablesGrid.EnableScrolling(False, True)
  2020         self.VariablesGrid.Bind(wx.grid.EVT_GRID_CELL_CHANGE, self.OnVariablesGridCellChange)
  2027         self.VariablesGrid.Bind(wx.grid.EVT_GRID_CELL_CHANGE, self.OnVariablesGridCellChange)
       
  2028         self.VariablesGrid.Bind(wx.grid.EVT_GRID_SELECT_CELL, self.OnVariablesGridSelectCell)
  2021 
  2029 
  2022         self.AddButton = wx.Button(id=wxID_EDITVARIABLEDIALOGADDBUTTON, label='Add',
  2030         self.AddButton = wx.Button(id=wxID_EDITVARIABLEDIALOGADDBUTTON, label='Add',
  2023               name='AddButton', parent=self.MainPanel, pos=wx.Point(345, 340),
  2031               name='AddButton', parent=self.MainPanel, pos=wx.Point(345, 340),
  2024               size=wx.Size(72, 32), style=0)
  2032               size=wx.Size(72, 32), style=0)
  2025         EVT_BUTTON(self, wxID_EDITVARIABLEDIALOGADDBUTTON, self.OnAddButton)
  2033         EVT_BUTTON(self, wxID_EDITVARIABLEDIALOGADDBUTTON, self.OnAddButton)
  2039               size=wx.Size(32, 32), style=0)
  2047               size=wx.Size(32, 32), style=0)
  2040         EVT_BUTTON(self, wxID_EDITVARIABLEDIALOGDOWNBUTTON, self.OnDownButton)
  2048         EVT_BUTTON(self, wxID_EDITVARIABLEDIALOGDOWNBUTTON, self.OnDownButton)
  2041 
  2049 
  2042         self._init_sizers()
  2050         self._init_sizers()
  2043 
  2051 
  2044     def __init__(self, parent, name, pou_type, filter = "All"):
  2052     def __init__(self, parent, name, pou_type, pou_is_used, filter = "All"):
  2045         self._init_ctrls(parent, name)
  2053         self._init_ctrls(parent, name)
  2046         self.ButtonSizer = self.CreateButtonSizer(wxOK|wxCANCEL|wxCENTRE)
  2054         self.ButtonSizer = self.CreateButtonSizer(wxOK|wxCANCEL|wxCENTRE)
  2047         self.flexGridSizer1.Add(self.ButtonSizer, 1, wxALIGN_RIGHT)
  2055         self.flexGridSizer1.Add(self.ButtonSizer, 1, wxALIGN_RIGHT)
  2048         self.Filter = filter
  2056         self.Filter = filter
       
  2057         self.PouIsUsed = pou_is_used
  2049         self.FilterChoices = []
  2058         self.FilterChoices = []
  2050         self.FilterChoiceTransfer = {"All" : "All", "Interface" : "Interface", 
  2059         self.FilterChoiceTransfer = {"All" : "All", "Interface" : "Interface", 
  2051             "Input" : "   Input", "Output" : "   Output", "InOut" : "   InOut", 
  2060             "   Input" : "Input", "   Output" : "Output", "   InOut" : "InOut", 
  2052             "External" : "   External", "Variables" : "Variables", "Local" : "   Local",
  2061             "   External" : "External", "Variables" : "Variables", "   Local" : "Local",
  2053             "Temp" : "   Temp", "Global" : "Global", "Access" : "Access"}
  2062             "   Temp" : "Temp", "Global" : "Global", "Access" : "Access"}
  2054         
  2063         
  2055         if pou_type:
  2064         if pou_type:
  2056             self.DefaultTypes = {"All" : "Input", "Interface" : "Input", "Variables" : "Local"}
  2065             self.DefaultTypes = {"All" : "Local", "Interface" : "Input", "Variables" : "Local"}
  2057             self.DefaultValue = {"Name" : "", "Class" : "", "Type" : "INT", "Location" : "", "Initial Value" : "", "Retain" : "No", "Constant" : "No"}
  2066             self.DefaultValue = {"Name" : "", "Class" : "", "Type" : "INT", "Location" : "", "Initial Value" : "", "Retain" : "No", "Constant" : "No"}
  2058         else:
  2067         else:
  2059             self.DefaultTypes = {"All" : "Global"}
  2068             self.DefaultTypes = {"All" : "Global"}
  2060             self.DefaultValue = {"Name" : "", "Class" : "", "Type" : "INT", "Location" : "", "Initial Value" : "", "Retain" : "No", "Constant" : "No"}
  2069             self.DefaultValue = {"Name" : "", "Class" : "", "Type" : "INT", "Location" : "", "Initial Value" : "", "Retain" : "No", "Constant" : "No"}
  2061         if not pou_type or pou_type == "program":
  2070         if not pou_type or pou_type == "program":
  2071             self.FilterChoices = ["All","Interface","   Input","   Output","   InOut","   External","Variables","   Local","   Temp"]
  2080             self.FilterChoices = ["All","Interface","   Input","   Output","   InOut","   External","Variables","   Local","   Temp"]
  2072             self.ColSizes = [120, 70, 80, 120, 60, 70]
  2081             self.ColSizes = [120, 70, 80, 120, 60, 70]
  2073             self.ColAlignements = [wxALIGN_LEFT, wxALIGN_LEFT, wxALIGN_LEFT, wxALIGN_LEFT, wxALIGN_CENTER, wxALIGN_CENTER]
  2082             self.ColAlignements = [wxALIGN_LEFT, wxALIGN_LEFT, wxALIGN_LEFT, wxALIGN_LEFT, wxALIGN_CENTER, wxALIGN_CENTER]
  2074         for choice in self.FilterChoices:
  2083         for choice in self.FilterChoices:
  2075             self.ClassFilter.Append(choice)
  2084             self.ClassFilter.Append(choice)
  2076         self.ClassFilter.SetStringSelection(self.FilterChoiceTransfer[self.Filter])
  2085         reverse_transfer = {}
       
  2086         for filter, choice in self.FilterChoiceTransfer.items():
       
  2087             reverse_transfer[choice] = filter
       
  2088         self.ClassFilter.SetStringSelection(reverse_transfer[self.Filter])
  2077         self.RefreshTypeList()
  2089         self.RefreshTypeList()
  2078         self.RefreshUpDownButtons()
  2090         self.RefreshButtons()
  2079 
  2091 
  2080         self.OptionList = "Yes,No"
  2092         self.OptionList = "Yes,No"
  2081         self.TypeList = ",".join([value for value, parent in TypeHierarchy_list if not value.startswith("ANY")])
  2093         self.TypeList = ",".join([value for value, parent in TypeHierarchy_list if not value.startswith("ANY")])
  2082         
  2094         
  2083         if pou_type == "function":
  2095         if pou_type == "function":
  2095         
  2107         
  2096         self.Table.ResetView(self.VariablesGrid)
  2108         self.Table.ResetView(self.VariablesGrid)
  2097 
  2109 
  2098         self.PouNames = []
  2110         self.PouNames = []
  2099 
  2111 
       
  2112         if self.PouIsUsed:
       
  2113             wxCallAfter(self.WarningMessage, name)
       
  2114 
  2100         EVT_BUTTON(self, self.ButtonSizer.GetAffirmativeButton().GetId(), self.OnOK)
  2115         EVT_BUTTON(self, self.ButtonSizer.GetAffirmativeButton().GetId(), self.OnOK)
       
  2116     
       
  2117     def WarningMessage(self, name):
       
  2118         message = wxMessageDialog(self, "\"%s\" is used by one or more POUs. Its interface can't be changed!"%name, "WARNING", wxOK|wxICON_EXCLAMATION)
       
  2119         message.ShowModal()
       
  2120         message.Destroy()
  2101     
  2121     
  2102     def OnOK(self, event):
  2122     def OnOK(self, event):
  2103         self.VariablesGrid.SetGridCursor(0, 0)
  2123         self.VariablesGrid.SetGridCursor(0, 0)
  2104         error = []
  2124         error = []
  2105         if self.ReturnType.IsEnabled() and self.ReturnType.GetStringSelection() == "":
  2125         if self.ReturnType.IsEnabled() and self.ReturnType.GetStringSelection() == "":
  2118             message.Destroy()
  2138             message.Destroy()
  2119         else:
  2139         else:
  2120             self.EndModal(wxID_OK)
  2140             self.EndModal(wxID_OK)
  2121 
  2141 
  2122     def OnClassFilter(self, event):
  2142     def OnClassFilter(self, event):
  2123         reverse_transfer = {}
  2143         self.Filter = self.FilterChoiceTransfer[self.ClassFilter.GetStringSelection()]
  2124         for filter, choice in self.FilterChoiceTransfer.items():
       
  2125             reverse_transfer[choice] = filter
       
  2126         self.Filter = reverse_transfer[self.ClassFilter.GetStringSelection()]
       
  2127         self.RefreshTypeList()
  2144         self.RefreshTypeList()
  2128         self.RefreshValues()
  2145         self.RefreshValues()
  2129         self.RefreshUpDownButtons()
  2146         self.RefreshButtons()
  2130         event.Skip()
  2147         event.Skip()
  2131 
  2148 
  2132     def RefreshTypeList(self):
  2149     def RefreshTypeList(self):
  2133         if self.Filter == "All":
  2150         if self.Filter == "All":
  2134             self.ClassList = [choice for choice in self.FilterChoiceTransfer.keys() if choice not in ["All","Interface","Variables"]]
  2151             self.ClassList = [self.FilterChoiceTransfer[choice] for choice in self.FilterChoices if self.FilterChoiceTransfer[choice] not in ["All","Interface","Variables"]]
  2135         elif self.Filter == "Interface":
  2152         elif self.Filter == "Interface":
  2136             self.ClassList = ["Input","Output","InOut","External"]
  2153             self.ClassList = ["Input","Output","InOut","External"]
  2137         elif self.Filter == "Variables":
  2154         elif self.Filter == "Variables":
  2138             self.ClassList = ["Local","Temp"]
  2155             self.ClassList = ["Local","Temp"]
  2139         else:
  2156         else:
  2140             self.ClassList = [self.Filter]
  2157             self.ClassList = [self.Filter]
  2141 
  2158 
  2142     def RefreshUpDownButtons(self):
  2159     def RefreshButtons(self):
  2143         if self.Filter == "All":
  2160         table_length = len(self.Table.data)
  2144             self.UpButton.Enable(True)
  2161         row_class = None
  2145             self.DownButton.Enable(True)
  2162         if table_length and self.PouIsUsed:
  2146         else:
  2163             row = self.VariablesGrid.GetGridCursorRow()
  2147             self.UpButton.Enable(False)
  2164             row_class = self.Table.GetValueByName(row, "Class")
  2148             self.DownButton.Enable(False)
  2165         self.AddButton.Enable(not self.PouIsUsed or self.Filter not in ["Interface", "Input", "Output", "InOut"])
  2149 
  2166         self.DeleteButton.Enable(table_length > 0 and row_class not in ["Input", "Output", "InOut"])
       
  2167         self.UpButton.Enable(table_length > 0 and self.Filter == "All" and row_class not in ["Input", "Output", "InOut"])
       
  2168         self.DownButton.Enable(table_length > 0 and self.Filter == "All" and row_class not in ["Input", "Output", "InOut"])
       
  2169     
  2150     def OnAddButton(self, event):
  2170     def OnAddButton(self, event):
  2151         new_row = self.DefaultValue.copy()
  2171         new_row = self.DefaultValue.copy()
  2152         if self.Filter in self.DefaultTypes:
  2172         if self.Filter in self.DefaultTypes:
  2153             new_row["Class"] = self.DefaultTypes[self.Filter]
  2173             new_row["Class"] = self.DefaultTypes[self.Filter]
  2154         else:
  2174         else:
  2155             new_row["Class"] = self.Filter
  2175             new_row["Class"] = self.Filter
  2156         self.Values.append(new_row)
  2176         self.Values.append(new_row)
  2157         self.RefreshValues()
  2177         self.RefreshValues()
       
  2178         self.RefreshButtons()
  2158         event.Skip()
  2179         event.Skip()
  2159 
  2180 
  2160     def OnDeleteButton(self, event):
  2181     def OnDeleteButton(self, event):
  2161         row = self.Table.GetRow(self.VariablesGrid.GetGridCursorRow())
  2182         row = self.Table.GetRow(self.VariablesGrid.GetGridCursorRow())
  2162         self.Values.remove(row)
  2183         self.Values.remove(row)
  2163         self.RefreshValues()
  2184         self.RefreshValues()
       
  2185         self.RefreshButtons()
  2164         event.Skip()
  2186         event.Skip()
  2165 
  2187 
  2166     def OnUpButton(self, event):
  2188     def OnUpButton(self, event):
  2167         self.MoveValue(self.VariablesGrid.GetGridCursorRow(), -1)
  2189         self.MoveValue(self.VariablesGrid.GetGridCursorRow(), -1)
       
  2190         self.RefreshButtons()
  2168         event.Skip()
  2191         event.Skip()
  2169 
  2192 
  2170     def OnDownButton(self, event):
  2193     def OnDownButton(self, event):
  2171         self.MoveValue(self.VariablesGrid.GetGridCursorRow(), 1)
  2194         self.MoveValue(self.VariablesGrid.GetGridCursorRow(), 1)
       
  2195         self.RefreshButtons()
  2172         event.Skip()
  2196         event.Skip()
  2173 
  2197 
  2174     def OnVariablesGridCellChange(self, event):
  2198     def OnVariablesGridCellChange(self, event):
  2175         row, col = event.GetRow(), event.GetCol()
  2199         row, col = event.GetRow(), event.GetCol()
  2176         colname = self.Table.GetColLabelValue(col)
  2200         colname = self.Table.GetColLabelValue(col)
  2199             else:
  2223             else:
  2200                 event.Skip()
  2224                 event.Skip()
  2201         else:
  2225         else:
  2202             event.Skip()
  2226             event.Skip()
  2203 
  2227 
       
  2228     def OnVariablesGridSelectCell(self, event):
       
  2229         wxCallAfter(self.RefreshButtons)
       
  2230         event.Skip()
       
  2231 
  2204     def SetPouNames(self, pou_names):
  2232     def SetPouNames(self, pou_names):
  2205         self.PouNames = [pou_name.upper() for pou_name in pou_names]
  2233         self.PouNames = [pou_name.upper() for pou_name in pou_names]
  2206 
  2234 
  2207     def SetValues(self, values):
  2235     def SetValues(self, values):
  2208         for item, value in values.items():
  2236         for item, value in values.items():
  2220             self.VariablesGrid.SetGridCursor(new_index, self.VariablesGrid.GetGridCursorCol())
  2248             self.VariablesGrid.SetGridCursor(new_index, self.VariablesGrid.GetGridCursorCol())
  2221         else:
  2249         else:
  2222             self.RefreshValues()
  2250             self.RefreshValues()
  2223     
  2251     
  2224     def RefreshValues(self):
  2252     def RefreshValues(self):
  2225         self.VariablesGrid.SetGridCursor(0, 0)
  2253         if len(self.Table.data) > 0:
       
  2254             self.VariablesGrid.SetGridCursor(0, 0)
  2226         data = []
  2255         data = []
  2227         for variable in self.Values:
  2256         for variable in self.Values:
  2228             if variable["Class"] in self.ClassList:
  2257             if variable["Class"] in self.ClassList:
  2229                 data.append(variable)
  2258                 data.append(variable)
  2230         self.Table.SetData(data)
  2259         self.Table.SetData(data)