PLCControler.py
changeset 1782 5b6ad7a7fd9d
parent 1780 c52d1460cea8
child 1785 0ff2a45dcefa
equal deleted inserted replaced
1781:b112bfdde5cc 1782:5b6ad7a7fd9d
   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)