109 UNEDITABLE_NAMES = GetUneditableNames() |
109 UNEDITABLE_NAMES = GetUneditableNames() |
110 [USER_DEFINED_POUS, FUNCTIONS, FUNCTION_BLOCKS, PROGRAMS, |
110 [USER_DEFINED_POUS, FUNCTIONS, FUNCTION_BLOCKS, PROGRAMS, |
111 DATA_TYPES, TRANSITIONS, ACTIONS, CONFIGURATIONS, |
111 DATA_TYPES, TRANSITIONS, ACTIONS, CONFIGURATIONS, |
112 RESOURCES, PROPERTIES] = UNEDITABLE_NAMES |
112 RESOURCES, PROPERTIES] = UNEDITABLE_NAMES |
113 |
113 |
114 #------------------------------------------------------------------------------- |
|
115 # Helper object for loading library in xslt stylesheets |
|
116 #------------------------------------------------------------------------------- |
|
117 |
|
118 |
114 |
119 class LibraryResolver(etree.Resolver): |
115 class LibraryResolver(etree.Resolver): |
|
116 """Helper object for loading library in xslt stylesheets""" |
120 |
117 |
121 def __init__(self, controller, debug=False): |
118 def __init__(self, controller, debug=False): |
122 self.Controller = controller |
119 self.Controller = controller |
123 self.Debug = debug |
120 self.Debug = debug |
124 |
121 |
134 else: |
131 else: |
135 for ctn in self.Controller.ConfNodeTypes: |
132 for ctn in self.Controller.ConfNodeTypes: |
136 lib_el.append(deepcopy(ctn["types"])) |
133 lib_el.append(deepcopy(ctn["types"])) |
137 return self.resolve_string(etree.tostring(lib_el), context) |
134 return self.resolve_string(etree.tostring(lib_el), context) |
138 |
135 |
139 #------------------------------------------------------------------------------- |
136 # ------------------------------------------------------------------------------- |
140 # Helpers functions for translating list of arguments |
137 # Helpers functions for translating list of arguments |
141 # from xslt to valid arguments |
138 # from xslt to valid arguments |
142 #------------------------------------------------------------------------------- |
139 # ------------------------------------------------------------------------------- |
143 |
140 |
144 |
141 |
145 def _StringValue(x): |
142 def _StringValue(x): |
146 return x |
143 return x |
147 |
144 |
153 def _translate_args(translations, args): |
150 def _translate_args(translations, args): |
154 return [translate(arg[0]) if len(arg) > 0 else None |
151 return [translate(arg[0]) if len(arg) > 0 else None |
155 for translate, arg in |
152 for translate, arg in |
156 zip(translations, args)] |
153 zip(translations, args)] |
157 |
154 |
158 #------------------------------------------------------------------------------- |
155 # ------------------------------------------------------------------------------- |
159 # Helpers object for generating pou var list |
156 # Helpers object for generating pou var list |
160 #------------------------------------------------------------------------------- |
157 # ------------------------------------------------------------------------------- |
161 |
158 |
162 |
159 |
163 class _VariableInfos(object): |
160 class _VariableInfos(object): |
164 __slots__ = ["Name", "Class", "Option", "Location", "InitialValue", |
161 __slots__ = ["Name", "Class", "Option", "Location", "InitialValue", |
165 "Edit", "Documentation", "Type", "Tree", "Number"] |
162 "Edit", "Documentation", "Type", "Tree", "Number"] |
206 def AddVariable(self, context, *args): |
203 def AddVariable(self, context, *args): |
207 self.Variables.append(_VariableInfos(*(_translate_args( |
204 self.Variables.append(_VariableInfos(*(_translate_args( |
208 [_StringValue] * 5 + [_BoolValue] + [_StringValue], args) + |
205 [_StringValue] * 5 + [_BoolValue] + [_StringValue], args) + |
209 [self.GetType(), self.GetTree()]))) |
206 [self.GetType(), self.GetTree()]))) |
210 |
207 |
211 #------------------------------------------------------------------------------- |
208 # ------------------------------------------------------------------------------- |
212 # Helpers object for generating pou variable instance list |
209 # Helpers object for generating pou variable instance list |
213 #------------------------------------------------------------------------------- |
210 # ------------------------------------------------------------------------------- |
214 |
211 |
215 |
212 |
216 def class_extraction(value): |
213 def class_extraction(value): |
217 class_type = { |
214 class_type = { |
218 "configuration": ITEM_CONFIGURATION, |
215 "configuration": ITEM_CONFIGURATION, |
264 self.Root.variables.append(_VariablesTreeItemInfos( |
261 self.Root.variables.append(_VariablesTreeItemInfos( |
265 *(_translate_args( |
262 *(_translate_args( |
266 [_StringValue, class_extraction, _StringValue] + |
263 [_StringValue, class_extraction, _StringValue] + |
267 [_BoolValue] * 2, args) + [[]]))) |
264 [_BoolValue] * 2, args) + [[]]))) |
268 |
265 |
269 #------------------------------------------------------------------------------- |
|
270 # Helpers object for generating instances path list |
|
271 #------------------------------------------------------------------------------- |
|
272 |
|
273 |
266 |
274 class InstancesPathFactory: |
267 class InstancesPathFactory: |
275 |
268 """Helpers object for generating instances path list""" |
276 def __init__(self, instances): |
269 def __init__(self, instances): |
277 self.Instances = instances |
270 self.Instances = instances |
278 |
271 |
279 def AddInstance(self, context, *args): |
272 def AddInstance(self, context, *args): |
280 self.Instances.append(args[0][0]) |
273 self.Instances.append(args[0][0]) |
281 |
274 |
282 #------------------------------------------------------------------------------- |
|
283 # Helpers object for generating instance tagname |
|
284 #------------------------------------------------------------------------------- |
|
285 |
|
286 |
275 |
287 class InstanceTagName: |
276 class InstanceTagName: |
|
277 """Helpers object for generating instance tagname""" |
288 |
278 |
289 def __init__(self, controller): |
279 def __init__(self, controller): |
290 self.Controller = controller |
280 self.Controller = controller |
291 self.TagName = None |
281 self.TagName = None |
292 |
282 |
306 self.TagName = self.Controller.ComputePouActionName(args[0][0], args[0][1]) |
296 self.TagName = self.Controller.ComputePouActionName(args[0][0], args[0][1]) |
307 |
297 |
308 def TransitionTagName(self, context, *args): |
298 def TransitionTagName(self, context, *args): |
309 self.TagName = self.Controller.ComputePouTransitionName(args[0][0], args[0][1]) |
299 self.TagName = self.Controller.ComputePouTransitionName(args[0][0], args[0][1]) |
310 |
300 |
311 #------------------------------------------------------------------------------- |
301 |
|
302 # ------------------------------------------------------------------------------- |
312 # Helpers object for generating pou block instances list |
303 # Helpers object for generating pou block instances list |
313 #------------------------------------------------------------------------------- |
304 # ------------------------------------------------------------------------------- |
314 |
305 |
315 |
306 |
316 _Point = namedtuple("Point", ["x", "y"]) |
307 _Point = namedtuple("Point", ["x", "y"]) |
317 |
308 |
318 _BlockInstanceInfos = namedtuple( |
309 _BlockInstanceInfos = namedtuple( |
463 |
454 |
464 |
455 |
465 pou_block_instances_xslt = etree.parse( |
456 pou_block_instances_xslt = etree.parse( |
466 os.path.join(ScriptDirectory, "plcopen", "pou_block_instances.xslt")) |
457 os.path.join(ScriptDirectory, "plcopen", "pou_block_instances.xslt")) |
467 |
458 |
468 #------------------------------------------------------------------------------- |
|
469 # Undo Buffer for PLCOpenEditor |
|
470 #------------------------------------------------------------------------------- |
|
471 |
459 |
472 # Length of the buffer |
460 # Length of the buffer |
473 UNDO_BUFFER_LENGTH = 20 |
461 UNDO_BUFFER_LENGTH = 20 |
474 |
462 |
475 |
463 |
476 class UndoBuffer: |
464 class UndoBuffer: |
477 """ |
465 """ |
|
466 Undo Buffer for PLCOpenEditor |
478 Class implementing a buffer of changes made on the current editing model |
467 Class implementing a buffer of changes made on the current editing model |
479 """ |
468 """ |
480 |
469 |
481 def __init__(self, currentstate, issaved=False): |
470 def __init__(self, currentstate, issaved=False): |
482 """ |
471 """ |
553 # Return True if current state is saved |
542 # Return True if current state is saved |
554 def IsCurrentSaved(self): |
543 def IsCurrentSaved(self): |
555 return self.LastSave == self.CurrentIndex |
544 return self.LastSave == self.CurrentIndex |
556 |
545 |
557 |
546 |
558 #------------------------------------------------------------------------------- |
|
559 # Controler for PLCOpenEditor |
|
560 #------------------------------------------------------------------------------- |
|
561 |
|
562 |
|
563 class PLCControler: |
547 class PLCControler: |
564 """ |
548 """ |
|
549 Controler for PLCOpenEditor |
565 Class which controls the operations made on the plcopen model and answers to view requests |
550 Class which controls the operations made on the plcopen model and answers to view requests |
566 """ |
551 """ |
567 |
552 |
568 # Create a new PLCControler |
553 # Create a new PLCControler |
569 def __init__(self): |
554 def __init__(self): |
595 if debug and self.CurrentCompiledProject is not None: |
580 if debug and self.CurrentCompiledProject is not None: |
596 return self.CurrentCompiledProject |
581 return self.CurrentCompiledProject |
597 else: |
582 else: |
598 return self.Project |
583 return self.Project |
599 |
584 |
600 #------------------------------------------------------------------------------- |
585 # ------------------------------------------------------------------------------- |
601 # Project management functions |
586 # Project management functions |
602 #------------------------------------------------------------------------------- |
587 # ------------------------------------------------------------------------------- |
603 |
588 |
604 # Return if a project is opened |
589 # Return if a project is opened |
605 def HasOpenedProject(self): |
590 def HasOpenedProject(self): |
606 return self.Project is not None |
591 return self.Project is not None |
607 |
592 |
959 if next_row == to_location[0] and next_col > to_location[1] or next_row > to_location[0]: |
944 if next_row == to_location[0] and next_col > to_location[1] or next_row > to_location[0]: |
960 return infos |
945 return infos |
961 row, col = next_row, next_col |
946 row, col = next_row, next_col |
962 return infos |
947 return infos |
963 |
948 |
964 #------------------------------------------------------------------------------- |
949 # ------------------------------------------------------------------------------- |
965 # Project Pous management functions |
950 # Project Pous management functions |
966 #------------------------------------------------------------------------------- |
951 # ------------------------------------------------------------------------------- |
967 |
952 |
968 # Add a Data Type to Project |
953 # Add a Data Type to Project |
969 def ProjectAddDataType(self, datatype_name=None): |
954 def ProjectAddDataType(self, datatype_name=None): |
970 if self.Project is not None: |
955 if self.Project is not None: |
971 if datatype_name is None: |
956 if datatype_name is None: |
1955 values.extend(project.GetEnumeratedDataTypeValues()) |
1940 values.extend(project.GetEnumeratedDataTypeValues()) |
1956 for confnodetype in self.ConfNodeTypes: |
1941 for confnodetype in self.ConfNodeTypes: |
1957 values.extend(confnodetype["types"].GetEnumeratedDataTypeValues()) |
1942 values.extend(confnodetype["types"].GetEnumeratedDataTypeValues()) |
1958 return values |
1943 return values |
1959 |
1944 |
1960 #------------------------------------------------------------------------------- |
1945 # ------------------------------------------------------------------------------- |
1961 # Project Element tag name computation functions |
1946 # Project Element tag name computation functions |
1962 #------------------------------------------------------------------------------- |
1947 # ------------------------------------------------------------------------------- |
1963 |
1948 |
1964 # Compute a data type name |
1949 # Compute a data type name |
1965 def ComputeDataTypeName(self, datatype): |
1950 def ComputeDataTypeName(self, datatype): |
1966 return "D::%s" % datatype |
1951 return "D::%s" % datatype |
1967 |
1952 |
1994 "A": ITEM_ACTION, |
1979 "A": ITEM_ACTION, |
1995 "C": ITEM_CONFIGURATION, |
1980 "C": ITEM_CONFIGURATION, |
1996 "R": ITEM_RESOURCE |
1981 "R": ITEM_RESOURCE |
1997 }[words[0]] |
1982 }[words[0]] |
1998 |
1983 |
1999 #------------------------------------------------------------------------------- |
1984 # ------------------------------------------------------------------------------- |
2000 # Project opened Data types management functions |
1985 # Project opened Data types management functions |
2001 #------------------------------------------------------------------------------- |
1986 # ------------------------------------------------------------------------------- |
2002 |
1987 |
2003 # Return the data type informations |
1988 # Return the data type informations |
2004 def GetDataTypeInfos(self, tagname, debug=False): |
1989 def GetDataTypeInfos(self, tagname, debug=False): |
2005 project = self.GetProject(debug) |
1990 project = self.GetProject(debug) |
2006 if project is not None: |
1991 if project is not None: |
2195 datatype.initialValue.setvalue(infos["initial"]) |
2180 datatype.initialValue.setvalue(infos["initial"]) |
2196 else: |
2181 else: |
2197 datatype.initialValue = None |
2182 datatype.initialValue = None |
2198 self.BufferProject() |
2183 self.BufferProject() |
2199 |
2184 |
2200 #------------------------------------------------------------------------------- |
2185 # ------------------------------------------------------------------------------- |
2201 # Project opened Pous management functions |
2186 # Project opened Pous management functions |
2202 #------------------------------------------------------------------------------- |
2187 # ------------------------------------------------------------------------------- |
2203 |
2188 |
2204 # Return edited element |
2189 # Return edited element |
2205 def GetEditedElement(self, tagname, debug=False): |
2190 def GetEditedElement(self, tagname, debug=False): |
2206 project = self.GetProject(debug) |
2191 project = self.GetProject(debug) |
2207 if project is not None: |
2192 if project is not None: |
3269 self.MarkProjectAsSaved() |
3254 self.MarkProjectAsSaved() |
3270 if filepath: |
3255 if filepath: |
3271 self.SetFilePath(filepath) |
3256 self.SetFilePath(filepath) |
3272 return True |
3257 return True |
3273 |
3258 |
3274 #------------------------------------------------------------------------------- |
3259 # ------------------------------------------------------------------------------- |
3275 # Search in Current Project Functions |
3260 # Search in Current Project Functions |
3276 #------------------------------------------------------------------------------- |
3261 # ------------------------------------------------------------------------------- |
3277 |
3262 |
3278 def SearchInProject(self, criteria): |
3263 def SearchInProject(self, criteria): |
3279 return self.Project.Search(criteria) |
3264 return self.Project.Search(criteria) |
3280 |
3265 |
3281 def SearchInPou(self, tagname, criteria, debug=False): |
3266 def SearchInPou(self, tagname, criteria, debug=False): |
3289 if infos[1] in ["var_local", "var_input", "var_output", "var_inout"]: |
3274 if infos[1] in ["var_local", "var_input", "var_output", "var_inout"]: |
3290 search_results.append((infos, start, end, text)) |
3275 search_results.append((infos, start, end, text)) |
3291 return search_results |
3276 return search_results |
3292 return [] |
3277 return [] |
3293 |
3278 |
3294 #------------------------------------------------------------------------------- |
3279 # ------------------------------------------------------------------------------- |
3295 # Current Buffering Management Functions |
3280 # Current Buffering Management Functions |
3296 #------------------------------------------------------------------------------- |
3281 # ------------------------------------------------------------------------------- |
3297 |
3282 |
3298 """ |
|
3299 Return a copy of the project |
|
3300 """ |
|
3301 def Copy(self, model): |
3283 def Copy(self, model): |
|
3284 """Return a copy of the project""" |
3302 return deepcopy(model) |
3285 return deepcopy(model) |
3303 |
3286 |
3304 def CreateProjectBuffer(self, saved): |
3287 def CreateProjectBuffer(self, saved): |
3305 if self.ProjectBufferEnabled: |
3288 if self.ProjectBufferEnabled: |
3306 self.ProjectBuffer = UndoBuffer(PLCOpenParser.Dumps(self.Project), saved) |
3289 self.ProjectBuffer = UndoBuffer(PLCOpenParser.Dumps(self.Project), saved) |