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 from xml.dom import minidom |
25 from xml.dom import minidom |
26 from types import StringType, UnicodeType, TupleType |
26 from types import StringType, UnicodeType, TupleType |
27 from lxml import etree |
27 from lxml import etree |
28 from copy import deepcopy |
28 from copy import deepcopy |
965 # prevent violations of POU content restrictions: |
965 # prevent violations of POU content restrictions: |
966 # function blocks cannot be pasted as functions, |
966 # function blocks cannot be pasted as functions, |
967 # programs cannot be pasted as functions or function blocks |
967 # programs cannot be pasted as functions or function blocks |
968 if orig_type == 'functionBlock' and pou_type == 'function' or \ |
968 if orig_type == 'functionBlock' and pou_type == 'function' or \ |
969 orig_type == 'program' and pou_type in ['function', 'functionBlock']: |
969 orig_type == 'program' and pou_type in ['function', 'functionBlock']: |
970 return _('''%s "%s" can't be pasted as a %s.''') % (orig_type, name, pou_type) |
970 msg = _('''{a1} "{a2}" can't be pasted as a {a3}.''').format(a1 = orig_type, a2 = name, a3 = pou_type) |
|
971 return msg |
971 |
972 |
972 new_pou.setpouType(pou_type) |
973 new_pou.setpouType(pou_type) |
973 |
974 |
974 self.Project.insertpou(0, new_pou) |
975 self.Project.insertpou(0, new_pou) |
975 self.BufferProject() |
976 self.BufferProject() |
1960 if element_type_type == "array": |
1961 if element_type_type == "array": |
1961 dimensions = [] |
1962 dimensions = [] |
1962 for dimension in element_type.getdimension(): |
1963 for dimension in element_type.getdimension(): |
1963 dimensions.append((dimension.getlower(), dimension.getupper())) |
1964 dimensions.append((dimension.getlower(), dimension.getupper())) |
1964 base_type = element_type.baseType.getcontent() |
1965 base_type = element_type.baseType.getcontent() |
1965 base_type_type = element_type.getLocalTag() |
1966 base_type_type = base_type.getLocalTag() |
1966 element_infos["Type"] = ("array", |
1967 element_infos["Type"] = ("array", |
1967 base_type.getname() |
1968 base_type.getname() |
1968 if base_type_type == "derived" |
1969 if base_type_type == "derived" |
1969 else base_type_type.upper(), dimensions) |
1970 else base_type_type.upper(), dimensions) |
1970 elif element_type_type == "derived": |
1971 elif element_type_type == "derived": |
1971 element_infos["Type"] = element_type.getname() |
1972 element_infos["Type"] = element_type.getname() |
1972 else: |
1973 else: |
1973 element_infos["Type"] = element_type_type.upper() |
1974 element_infos["Type"] = element_type_type.upper() |
1974 if element.initialValue is not None: |
1975 if element.initialValue is not None: |
1975 element_infos["Initial Value"] = str(element.initialValue.getvalue()) |
1976 element_infos["Initial Value"] = element.initialValue.getvalue() |
1976 else: |
1977 else: |
1977 element_infos["Initial Value"] = "" |
1978 element_infos["Initial Value"] = "" |
1978 infos["elements"].append(element_infos) |
1979 infos["elements"].append(element_infos) |
1979 else: |
1980 else: |
1980 infos["type"] = "Directly" |
1981 infos["type"] = "Directly" |
1981 infos["base_type"] = (basetype_content.getname() |
1982 infos["base_type"] = (basetype_content.getname() |
1982 if basetype_content_type == "derived" |
1983 if basetype_content_type == "derived" |
1983 else basetype_content_type.upper()) |
1984 else basetype_content_type.upper()) |
1984 |
1985 |
1985 if datatype.initialValue is not None: |
1986 if datatype.initialValue is not None: |
1986 infos["initial"] = str(datatype.initialValue.getvalue()) |
1987 infos["initial"] = datatype.initialValue.getvalue() |
1987 else: |
1988 else: |
1988 infos["initial"] = "" |
1989 infos["initial"] = "" |
1989 return infos |
1990 return infos |
1990 return None |
1991 return None |
1991 |
1992 |
2060 element_type = PLCOpenParser.CreateElement("type", "variable") |
2061 element_type = PLCOpenParser.CreateElement("type", "variable") |
2061 if isinstance(element_infos["Type"], TupleType): |
2062 if isinstance(element_infos["Type"], TupleType): |
2062 if element_infos["Type"][0] == "array": |
2063 if element_infos["Type"][0] == "array": |
2063 array_type, base_type_name, dimensions = element_infos["Type"] |
2064 array_type, base_type_name, dimensions = element_infos["Type"] |
2064 array = PLCOpenParser.CreateElement("array", "dataType") |
2065 array = PLCOpenParser.CreateElement("array", "dataType") |
|
2066 baseType = PLCOpenParser.CreateElement("baseType", "array") |
|
2067 array.setbaseType(baseType) |
2065 element_type.setcontent(array) |
2068 element_type.setcontent(array) |
2066 for j, dimension in enumerate(dimensions): |
2069 for j, dimension in enumerate(dimensions): |
2067 dimension_range = PLCOpenParser.CreateElement("dimension", "array") |
2070 dimension_range = PLCOpenParser.CreateElement("dimension", "array") |
2068 dimension_range.setlower(dimension[0]) |
2071 dimension_range.setlower(dimension[0]) |
2069 dimension_range.setupper(dimension[1]) |
2072 dimension_range.setupper(dimension[1]) |
2070 if j == 0: |
2073 if j == 0: |
2071 array.setdimension([dimension_range]) |
2074 array.setdimension([dimension_range]) |
2072 else: |
2075 else: |
2073 array.appenddimension(dimension_range) |
2076 array.appenddimension(dimension_range) |
2074 if base_type_name in self.GetBaseTypes(): |
2077 if base_type_name in self.GetBaseTypes(): |
2075 array.baseType.setcontent(PLCOpenParser.CreateElement( |
2078 baseType.setcontent(PLCOpenParser.CreateElement( |
2076 base_type_name.lower() |
2079 base_type_name.lower() |
2077 if base_type_name in ["STRING", "WSTRING"] |
2080 if base_type_name in ["STRING", "WSTRING"] |
2078 else base_type_name, "dataType")) |
2081 else base_type_name, "dataType")) |
2079 else: |
2082 else: |
2080 derived_datatype = PLCOpenParser.CreateElement("derived", "dataType") |
2083 derived_datatype = PLCOpenParser.CreateElement("derived", "dataType") |
2179 if project is not None: |
2182 if project is not None: |
2180 pou = self.Project.getpou(words[1]) |
2183 pou = self.Project.getpou(words[1]) |
2181 if pou is not None: |
2184 if pou is not None: |
2182 return self.GetPouInterfaceReturnType(pou, tree, debug) |
2185 return self.GetPouInterfaceReturnType(pou, tree, debug) |
2183 elif words[0] == 'T': |
2186 elif words[0] == 'T': |
2184 return "BOOL" |
2187 return ["BOOL", ([], [])] |
2185 return None |
2188 return None |
2186 |
2189 |
2187 # Change the edited element text |
2190 # Change the edited element text |
2188 def SetEditedElementText(self, tagname, text): |
2191 def SetEditedElementText(self, tagname, text): |
2189 if self.Project is not None: |
2192 if self.Project is not None: |
2313 # Get ids already by all the instances in edited element |
2316 # Get ids already by all the instances in edited element |
2314 used_id = dict([(instance.getlocalId(), True) for instance in element.getinstances()]) |
2317 used_id = dict([(instance.getlocalId(), True) for instance in element.getinstances()]) |
2315 new_id = {} |
2318 new_id = {} |
2316 |
2319 |
2317 try: |
2320 try: |
2318 instances, error = LoadPouInstances(text.encode("utf-8"), bodytype) |
2321 instances, error = LoadPouInstances(text, bodytype) |
2319 except: |
2322 except: |
2320 instances, error = [], "" |
2323 instances, error = [], "" |
2321 if error is not None or len(instances) == 0: |
2324 if error is not None or len(instances) == 0: |
2322 return _("Invalid plcopen element(s)!!!") |
2325 return _("Invalid plcopen element(s)!!!") |
2323 |
2326 |
3188 return self.Project.Search(criteria) |
3191 return self.Project.Search(criteria) |
3189 |
3192 |
3190 def SearchInPou(self, tagname, criteria, debug=False): |
3193 def SearchInPou(self, tagname, criteria, debug=False): |
3191 pou = self.GetEditedElement(tagname, debug) |
3194 pou = self.GetEditedElement(tagname, debug) |
3192 if pou is not None: |
3195 if pou is not None: |
3193 return pou.Search(criteria) |
3196 search_results = pou.Search(criteria, [tagname]) |
|
3197 if tagname.split("::")[0] in ['A', 'T']: |
|
3198 parent_pou_tagname = "P::%s" % (tagname.split("::")[-2]) |
|
3199 parent_pou = self.GetEditedElement(parent_pou_tagname, debug) |
|
3200 for infos, start, end, text in parent_pou.Search(criteria): |
|
3201 if infos[1] in ["var_local", "var_input", "var_output", "var_inout"]: |
|
3202 search_results.append((infos, start, end, text)) |
|
3203 return search_results |
3194 return [] |
3204 return [] |
3195 |
3205 |
3196 #------------------------------------------------------------------------------- |
3206 #------------------------------------------------------------------------------- |
3197 # Current Buffering Management Functions |
3207 # Current Buffering Management Functions |
3198 #------------------------------------------------------------------------------- |
3208 #------------------------------------------------------------------------------- |