# HG changeset patch
# User laurent
# Date 1337587374 -7200
# Node ID ce605c1a6d049c2892c59544a7854eab5ff01a3c
# Parent 629680fb05824a0d7a5371562479c2781538d032# Parent 188906a7368c9707dab9f1c97229b6d75235654e
Merged
diff -r 188906a7368c -r ce605c1a6d04 GraphicViewer.py
--- a/GraphicViewer.py Tue May 15 05:19:13 2012 +0900
+++ b/GraphicViewer.py Mon May 21 10:02:54 2012 +0200
@@ -507,14 +507,15 @@
## Refresh the variable cursor.
# @param dc The draw canvas
def RefreshCursor(self, dc=None):
- if dc is None:
- dc = wx.BufferedDC(wx.ClientDC(self.Canvas.canvas), self.Canvas._Buffer)
-
- # Erase previous time cursor if drawn
- if self.LastCursor is not None:
- self.DrawCursor(dc, *self.LastCursor)
-
- # Draw new time cursor
- if self.CursorIdx is not None:
- self.LastCursor = self.Datas[self.CursorIdx]
- self.DrawCursor(dc, *self.LastCursor)
+ if self:
+ if dc is None:
+ dc = wx.BufferedDC(wx.ClientDC(self.Canvas.canvas), self.Canvas._Buffer)
+
+ # Erase previous time cursor if drawn
+ if self.LastCursor is not None:
+ self.DrawCursor(dc, *self.LastCursor)
+
+ # Draw new time cursor
+ if self.CursorIdx is not None:
+ self.LastCursor = self.Datas[self.CursorIdx]
+ self.DrawCursor(dc, *self.LastCursor)
diff -r 188906a7368c -r ce605c1a6d04 Images/custom_tree_background.png
Binary file Images/custom_tree_background.png has changed
diff -r 188906a7368c -r ce605c1a6d04 Images/debug.png
Binary file Images/debug.png has changed
diff -r 188906a7368c -r ce605c1a6d04 Images/edit.png
Binary file Images/edit.png has changed
diff -r 188906a7368c -r ce605c1a6d04 Images/graph.png
Binary file Images/graph.png has changed
diff -r 188906a7368c -r ce605c1a6d04 Images/icons.svg
--- a/Images/icons.svg Tue May 15 05:19:13 2012 +0900
+++ b/Images/icons.svg Mon May 21 10:02:54 2012 +0200
@@ -23,2498 +23,6524 @@
sodipodi:docname="icons.svg"
inkscape:output_extension="org.inkscape.output.svg.inkscape">
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+ id="defs4">
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ %%custom_tree_background%%
+
+
+
+
+
+
+
+
+
+
+ %%up%%
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ %%edit%%
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ %%debug%%
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ %%graph%%
diff -r 188906a7368c -r ce605c1a6d04 Images/up.png
Binary file Images/up.png has changed
diff -r 188906a7368c -r ce605c1a6d04 PLCControler.py
--- a/PLCControler.py Tue May 15 05:19:13 2012 +0900
+++ b/PLCControler.py Mon May 21 10:02:54 2012 +0200
@@ -75,7 +75,12 @@
"InOut" : (plcopen.interface_inOutVars, ITEM_VAR_INOUT)
}
-LOCATIONS_ITEMS = [LOCATION_PLUGIN,
+POU_TYPES = {"program": ITEM_PROGRAM,
+ "functionBlock": ITEM_FUNCTIONBLOCK,
+ "function": ITEM_FUNCTION,
+ }
+
+LOCATIONS_ITEMS = [LOCATION_CONFNODE,
LOCATION_MODULE,
LOCATION_GROUP,
LOCATION_VAR_INPUT,
@@ -204,7 +209,7 @@
self.ProgramOffset = 0
self.NextCompiledProject = None
self.CurrentCompiledProject = None
- self.PluginTypes = []
+ self.ConfNodeTypes = []
self.ProgramFilePath = ""
def GetQualifierTypes(self):
@@ -376,135 +381,259 @@
resources["values"].append(resource_infos)
config_infos["values"] = [resources]
configurations["values"].append(config_infos)
- infos["values"] = [{"name": PROPERTIES, "type": ITEM_PROPERTIES, "values": []},
- datatypes, pou_types["function"], pou_types["functionBlock"],
+ infos["values"] = [datatypes, pou_types["function"], pou_types["functionBlock"],
pou_types["program"], configurations]
return infos
return None
- # Return project topology informations
- def GetProjectTopology(self, debug = False):
- project = self.GetProject(debug)
- if project is not None:
- infos = {"name": project.getname(), "type": ITEM_PROJECT, "values" : []}
- for config in project.getconfigurations():
- config_infos = {"name" : config.getname(), "type": ITEM_CONFIGURATION, "values" : []}
- for resource in config.getresource():
- resource_infos = {"name" : resource.getname(), "type": ITEM_RESOURCE, "values": []}
- for task in resource.gettask():
- for pou in task.getpouInstance():
- instance_infos = self.GetPouTopology(pou.getname(), pou.gettypeName(), debug=debug)
- if instance_infos is not None:
- resource_infos["values"].append(instance_infos)
- for pou in resource.getpouInstance():
- instance_infos = self.GetPouTopology(pou.getname(), pou.gettypeName(), debug=debug)
- if instance_infos is not None:
- resource_infos["values"].append(instance_infos)
- for varlist in resource.getglobalVars():
- for variable in varlist.getvariable():
- vartype_content = variable.gettype().getcontent()
- if vartype_content["name"] == "derived":
- var_infos = self.GetPouTopology(variable.getname(), vartype_content["value"].getname(), True, debug)
- if var_infos is not None:
- resource_infos["values"].append(var_infos)
- elif vartype_content["name"] in ["string", "wstring"]:
- resource_infos["values"].append({"name" : variable.getname(),
- "elmt_type" : vartype_content["name"].upper(),
- "type" : ITEM_VAR_GLOBAL, "values" : []})
- else:
- resource_infos["values"].append({"name" : variable.getname(),
- "elmt_type" : vartype_content["name"],
- "type" : ITEM_VAR_GLOBAL, "values" : []})
- config_infos["values"].append(resource_infos)
- for varlist in config.getglobalVars():
- for variable in varlist.getvariable():
- vartype_content = variable.gettype().getcontent()
- if vartype_content["name"] == "derived":
- var_infos = self.GetPouTopology(variable.getname(), vartype_content["value"].getname(), True, debug)
- if var_infos is not None:
- config_infos["values"].append(var_infos)
- elif vartype_content["name"] in ["string", "wstring"]:
- config_infos["values"].append({"name" : variable.getname(),
- "elmt_type" : vartype_content["name"].upper(),
- "type" : ITEM_VAR_GLOBAL, "values" : []})
- else:
- config_infos["values"].append({"name" : variable.getname(),
- "elmt_type" : vartype_content["name"],
- "type" : ITEM_VAR_GLOBAL, "values" : []})
- infos["values"].append(config_infos)
- return infos
- return None
-
- # Return pou topology informations
- def GetPouTopology(self, name, type, global_var = False, debug = False):
- project = self.GetProject(debug)
- if project is not None:
- pou = project.getpou(type)
+ def GetPouVariableInfos(self, project, variable, var_class, debug=False):
+ vartype_content = variable.gettype().getcontent()
+ if vartype_content["name"] == "derived":
+ var_type = vartype_content["value"].getname()
+ pou_type = None
+ pou = project.getpou(var_type)
if pou is not None:
pou_type = pou.getpouType()
- if pou_type == "function":
- return None
- elif pou_type == "program":
- pou_infos = {"name" : name, "elmt_type" : type, "type" : ITEM_PROGRAM,
- "tagname" : self.ComputePouName(pou.getname()), "values" : []}
+ edit = debug = pou_type is not None
+ if pou_type is None:
+ block_infos = self.GetBlockType(var_type, debug = debug)
+ pou_type = block_infos["type"]
+ if pou_type is not None:
+ var_class = None
+ if pou_type == "program":
+ var_class = ITEM_PROGRAM
+ elif pou_type != "function":
+ var_class = ITEM_FUNCTIONBLOCK
+ if var_class is not None:
+ return {"name": variable.getname(),
+ "type": var_type,
+ "class": var_class,
+ "edit": edit,
+ "debug": debug}
+ elif var_type in self.GetDataTypes(debug = debug):
+ return {"name": variable.getname(),
+ "type": var_type,
+ "class": var_class,
+ "edit": False,
+ "debug": False}
+ elif vartype_content["name"] in ["string", "wstring"]:
+ return {"name": variable.getname(),
+ "type": vartype_content["name"].upper(),
+ "class": var_class,
+ "edit": False,
+ "debug": True}
+ else:
+ return {"name": variable.getname(),
+ "type": vartype_content["name"],
+ "class": var_class,
+ "edit": False,
+ "debug": True}
+ return None
+
+ def GetPouVariables(self, tagname, debug = False):
+ vars = []
+ pou_type = None
+ project = self.GetProject(debug)
+ if project is not None:
+ words = tagname.split("::")
+ if words[0] == "P":
+ pou = project.getpou(words[1])
+ if pou is not None:
+ pou_type = pou.getpouType()
+ if (pou_type in ["program", "functionBlock"] and
+ pou.interface is not None):
+ # Extract variables from every varLists
+ for varlist_type, varlist in pou.getvars():
+ var_infos = VAR_CLASS_INFOS.get(varlist_type, None)
+ if var_infos is not None:
+ var_class = var_infos[1]
+ else:
+ var_class = ITEM_VAR_LOCAL
+ for variable in varlist.getvariable():
+ var_infos = self.GetPouVariableInfos(project, variable, var_class, debug)
+ if var_infos is not None:
+ vars.append(var_infos)
+ return {"class": POU_TYPES[pou_type],
+ "type": words[1],
+ "variables": vars,
+ "edit": True,
+ "debug": True}
else:
- pou_infos = {"name" : name, "elmt_type" : type, "type" : ITEM_FUNCTIONBLOCK,
- "tagname" : self.ComputePouName(pou.getname()), "values" : []}
- if pou.getbodyType() == "SFC":
- for transition in pou.gettransitionList():
- pou_infos["values"].append({"name" : transition.getname(),
- "elmt_type" : "TRANSITION", "type" : ITEM_TRANSITION,
- "tagname" : self.ComputePouActionName(pou.getname(), transition.getname()),
- "values" : []})
- for action in pou.getactionList():
- pou_infos["values"].append({"name": action.getname(),
- "elmt_type" : "ACTION", "type": ITEM_ACTION,
- "tagname" : self.ComputePouActionName(pou.getname(), action.getname()),
- "values" : []})
- if pou.interface:
- # Extract variables from every varLists
- for type, varlist in pou.getvars():
- infos = VAR_CLASS_INFOS.get(type, None)
- if infos is not None:
- current_var_class = infos[1]
- else:
- current_var_class = ITEM_VAR_LOCAL
- for variable in varlist.getvariable():
- vartype_content = variable.gettype().getcontent()
- if vartype_content["name"] == "derived":
- var_infos = self.GetPouTopology(variable.getname(), vartype_content["value"].getname())
- if var_infos is not None:
- pou_infos["values"].append(var_infos)
- elif vartype_content["name"] in ["string", "wstring"]:
- pou_infos["values"].append({"name" : variable.getname(),
- "elmt_type" : vartype_content["name"].upper(),
- "type" : current_var_class, "values" : []})
- else:
- pou_infos["values"].append({"name" : variable.getname(),
- "elmt_type" : vartype_content["name"],
- "type" : current_var_class, "values" : []})
- return pou_infos
- block_infos = self.GetBlockType(type, debug = debug)
- if block_infos is not None:
- if block_infos["type"] == "function":
- return None
- elif block_infos["type"] == "program":
- pou_infos = {"name" : name, "elmt_type" : type, "type" : ITEM_PROGRAM, "values" : []}
- else:
- pou_infos = {"name" : name, "elmt_type" : type, "type" : ITEM_FUNCTIONBLOCK, "values" : []}
- for varname, vartype, varmodifier in block_infos["inputs"]:
- pou_infos["values"].append({"name" : varname, "elmt_type" : vartype, "type" : ITEM_VAR_INPUT, "values" : []})
- for varname, vartype, varmodifier in block_infos["outputs"]:
- pou_infos["values"].append({"name" : varname, "elmt_type" : vartype, "type" : ITEM_VAR_INPUT, "values" : []})
- return pou_infos
+ block_infos = self.GetBlockType(words[1], debug = debug)
+ if (block_infos is not None and
+ block_infos["type"] in ["program", "functionBlock"]):
+ for varname, vartype, varmodifier in block_infos["inputs"]:
+ vars.append({"name" : varname,
+ "type" : vartype,
+ "class" : ITEM_VAR_INPUT,
+ "edit": False,
+ "debug": True})
+ for varname, vartype, varmodifier in block_infos["outputs"]:
+ vars.append({"name" : varname,
+ "type" : vartype,
+ "class" : ITEM_VAR_OUTPUT,
+ "edit": False,
+ "debug": True})
+ return {"class": POU_TYPES[block_infos["type"]],
+ "type": None,
+ "variables": vars,
+ "edit": False,
+ "debug": False}
+ elif words[0] in ['C', 'R']:
+ if words[0] == 'C':
+ pou_type = ITEM_CONFIGURATION
+ element = project.getconfiguration(words[1])
+ for resource in element.getresource():
+ vars.append({"name": resource.getname(),
+ "type": None,
+ "class": ITEM_RESOURCE,
+ "edit": True,
+ "debug": False})
+ elif words[0] == 'R':
+ pou_type = ITEM_RESOURCE
+ element = project.getconfigurationResource(words[1], words[2])
+ for task in element.gettask():
+ for pou in task.getpouInstance():
+ vars.append({"name": pou.getname(),
+ "type": pou.gettypeName(),
+ "class": ITEM_PROGRAM,
+ "edit": True,
+ "debug": True})
+ for pou in element.getpouInstance():
+ vars.append({"name": pou.getname(),
+ "type": pou.gettypeName(),
+ "class": ITEM_PROGRAM,
+ "edit": True,
+ "debug": True})
+ for varlist in element.getglobalVars():
+ for variable in varlist.getvariable():
+ var_infos = self.GetPouVariableInfos(project, variable, ITEM_VAR_GLOBAL, debug)
+ if var_infos is not None:
+ vars.append(var_infos)
+ return {"class": pou_type,
+ "type": None,
+ "variables": vars,
+ "edit": True,
+ "debug": False}
+ return None
+
+ def RecursiveSearchPouInstances(self, project, pou_type, parent_path, varlists, debug = False):
+ instances = []
+ for varlist in varlists:
+ for variable in varlist.getvariable():
+ vartype_content = variable.gettype().getcontent()
+ if vartype_content["name"] == "derived":
+ var_path = "%s.%s" % (parent_path, variable.getname())
+ var_type = vartype_content["value"].getname()
+ if var_type == pou_type:
+ instances.append(var_path)
+ else:
+ pou = project.getpou(var_type)
+ if pou is not None:
+ instances.extend(
+ self.RecursiveSearchPouInstances(
+ project, pou_type, var_path,
+ [varlist for type, varlist in pou.getvars()],
+ debug))
+ return instances
+
+ def SearchPouInstances(self, tagname, debug = False):
+ project = self.GetProject(debug)
+ if project is not None:
+ words = tagname.split("::")
+ if words[0] == "P":
+ instances = []
+ for config in project.getconfigurations():
+ config_name = config.getname()
+ instances.extend(
+ self.RecursiveSearchPouInstances(
+ project, words[1], config_name,
+ config.getglobalVars(), debug))
+ for resource in config.getresource():
+ res_path = "%s.%s" % (config_name, resource.getname())
+ instances.extend(
+ self.RecursiveSearchPouInstances(
+ project, words[1], res_path,
+ resource.getglobalVars(), debug))
+ pou_instances = resource.getpouInstance()[:]
+ for task in resource.gettask():
+ pou_instances.extend(task.getpouInstance())
+ for pou_instance in pou_instances:
+ pou_path = "%s.%s" % (res_path, pou_instance.getname())
+ pou_type = pou_instance.gettypeName()
+ if pou_type == words[1]:
+ instances.append(pou_path)
+ pou = project.getpou(pou_type)
+ if pou is not None:
+ instances.extend(
+ self.RecursiveSearchPouInstances(
+ project, words[1], pou_path,
+ [varlist for type, varlist in pou.getvars()],
+ debug))
+ return instances
+ elif words[0] == 'C':
+ return [words[1]]
+ elif words[0] == 'R':
+ return ["%s.%s" % (words[1], words[2])]
+ return []
+
+ def RecursiveGetPouInstanceTagName(self, project, pou_type, parts):
+ pou = project.getpou(pou_type)
+ if pou is not None:
+ if len(parts) == 0:
+ return self.ComputePouName(pou_type)
- if type in self.GetDataTypes(debug = debug):
- if global_var:
- return {"name" : name, "elmt_type" : type, "type" : ITEM_VAR_GLOBAL, "values" : []}
- else:
- return {"name" : name, "elmt_type" : type, "type" : ITEM_VAR_LOCAL, "values" : []}
- return None
-
+ for varlist_type, varlist in pou.getvars():
+ for variable in varlist.getvariable():
+ vartype_content = variable.gettype().getcontent()
+ if vartype_content["name"] == "derived":
+ return self.RecursiveGetPouInstanceTagName(
+ project,
+ vartype_content["value"].getname(),
+ parts[1:])
+ return None
+
+ def GetPouInstanceTagName(self, instance_path, debug = False):
+ parts = instance_path.split(".")
+ if len(parts) == 1:
+ return self.ComputeConfigurationName(parts[0])
+ elif len(parts) == 2:
+ return self.ComputeConfigurationResourceName(parts[0], parts[1])
+ else:
+ project = self.GetProject(debug)
+ for config in project.getconfigurations():
+ if config.getname() == parts[0]:
+ for resource in config.getresource():
+ if resource.getname() == parts[1]:
+ pou_instances = resource.getpouInstance()[:]
+ for task in resource.gettask():
+ pou_instances.extend(task.getpouInstance())
+ for pou_instance in pou_instances:
+ if pou_instance.getname() == parts[2]:
+ if len(parts) == 3:
+ return self.ComputePouName(
+ pou_instance.gettypeName())
+ else:
+ return self.RecursiveGetPouInstanceTagName(
+ project,
+ pou_instance.gettypeName(),
+ parts[3:])
+ return None
+
+ def GetInstanceInfos(self, instance_path, debug = False):
+ tagname = self.GetPouInstanceTagName(instance_path)
+ if tagname is not None:
+ return self.GetPouVariables(tagname, debug)
+ else:
+ pou_path, var_name = instance_path.rsplit(".", 1)
+ tagname = self.GetPouInstanceTagName(pou_path)
+ if tagname is not None:
+ pou_infos = self.GetPouVariables(tagname, debug)
+ for var_infos in pou_infos["variables"]:
+ if var_infos["name"] == var_name:
+ return var_infos
+ return None
+
# Return if data type given by name is used by another data type or pou
def DataTypeIsUsed(self, name, debug = False):
project = self.GetProject(debug)
@@ -667,6 +796,15 @@
self.Project.removepou(pou_name)
self.BufferProject()
+ # Return the name of the configuration if only one exist
+ def GetProjectMainConfigurationName(self):
+ if self.Project is not None:
+ # Found the configuration corresponding to old name and change its name to new name
+ configurations = self.Project.getconfigurations()
+ if len(configurations) == 1:
+ return configurations[0].getname()
+ return None
+
# Add a configuration to Project
def ProjectAddConfiguration(self, config_name):
if self.Project is not None:
@@ -1129,7 +1267,7 @@
return tree, []
datatype = project.getdataType(typename)
if datatype is None:
- datatype = self.GetPluginDataType(typename)
+ datatype = self.GetConfNodeDataType(typename)
if datatype is not None:
tree = []
basetype_content = datatype.baseType.getcontent()
@@ -1251,28 +1389,28 @@
return returntype_content["name"]
return None
- # Function that add a new plugin to the plugin list
- def AddPluginTypesList(self, typeslist):
- self.PluginTypes.extend(typeslist)
+ # Function that add a new confnode to the confnode list
+ def AddConfNodeTypesList(self, typeslist):
+ self.ConfNodeTypes.extend(typeslist)
- # Function that clear the plugin list
- def ClearPluginTypes(self):
- for i in xrange(len(self.PluginTypes)):
- self.PluginTypes.pop(0)
-
- def GetPluginBlockTypes(self):
- return [{"name": _("%s POUs") % plugintypes["name"],
- "list": plugintypes["types"].GetCustomBlockTypes()}
- for plugintypes in self.PluginTypes]
+ # Function that clear the confnode list
+ def ClearConfNodeTypes(self):
+ for i in xrange(len(self.ConfNodeTypes)):
+ self.ConfNodeTypes.pop(0)
+
+ def GetConfNodeBlockTypes(self):
+ return [{"name": _("%s POUs") % confnodetypes["name"],
+ "list": confnodetypes["types"].GetCustomBlockTypes()}
+ for confnodetypes in self.ConfNodeTypes]
- def GetPluginDataTypes(self, exclude = ""):
- return [{"name": _("%s Data Types") % plugintypes["name"],
- "list": [datatype["name"] for datatype in plugintypes["types"].GetCustomDataTypes(exclude)]}
- for plugintypes in self.PluginTypes]
-
- def GetPluginDataType(self, type):
- for plugintype in self.PluginTypes:
- datatype = plugintype["types"].getdataType(type)
+ def GetConfNodeDataTypes(self, exclude = ""):
+ return [{"name": _("%s Data Types") % confnodetypes["name"],
+ "list": [datatype["name"] for datatype in confnodetypes["types"].GetCustomDataTypes(exclude)]}
+ for confnodetypes in self.ConfNodeTypes]
+
+ def GetConfNodeDataType(self, type):
+ for confnodetype in self.ConfNodeTypes:
+ datatype = confnodetype["types"].getdataType(type)
if datatype is not None:
return datatype
return None
@@ -1283,7 +1421,7 @@
# Function that returns the block definition associated to the block type given
def GetBlockType(self, type, inputs = None, debug = False):
result_blocktype = None
- for category in BlockTypes + self.GetPluginBlockTypes():
+ for category in BlockTypes + self.GetConfNodeBlockTypes():
for blocktype in category["list"]:
if blocktype["name"] == type:
if inputs is not None and inputs != "undefined":
@@ -1317,7 +1455,7 @@
type = self.GetPouType(name, debug)
if type == "function" or words[0] == "T":
blocktypes = []
- for category in BlockTypes + self.GetPluginBlockTypes():
+ for category in BlockTypes + self.GetConfNodeBlockTypes():
cat = {"name" : category["name"], "list" : []}
for block in category["list"]:
if block["type"] == "function":
@@ -1325,7 +1463,7 @@
if len(cat["list"]) > 0:
blocktypes.append(cat)
else:
- blocktypes = [category for category in BlockTypes + self.GetPluginBlockTypes()]
+ blocktypes = [category for category in BlockTypes + self.GetConfNodeBlockTypes()]
project = self.GetProject(debug)
if project is not None:
blocktypes.append({"name" : USER_DEFINED_POUS, "list": project.GetCustomBlockTypes(name, type == "function" or words[0] == "T")})
@@ -1334,7 +1472,7 @@
# Return Function Block types checking for recursion
def GetFunctionBlockTypes(self, tagname = "", debug = False):
blocktypes = []
- for category in BlockTypes + self.GetPluginBlockTypes():
+ for category in BlockTypes + self.GetConfNodeBlockTypes():
for block in category["list"]:
if block["type"] == "functionBlock":
blocktypes.append(block["name"])
@@ -1381,8 +1519,8 @@
result = project.GetBaseType(type)
if result is not None:
return result
- for plugintype in self.PluginTypes:
- result = plugintype["types"].GetBaseType(type)
+ for confnodetype in self.ConfNodeTypes:
+ result = confnodetype["types"].GetBaseType(type)
if result is not None:
return result
return None
@@ -1406,8 +1544,8 @@
project = self.GetProject(debug)
if project is not None and project.IsOfType(type, reference):
return True
- for plugintype in self.PluginTypes:
- if plugintype["types"].IsOfType(type, reference):
+ for confnodetype in self.ConfNodeTypes:
+ if confnodetype["types"].IsOfType(type, reference):
return True
return False
@@ -1423,7 +1561,7 @@
if project is not None:
datatype = project.getdataType(type)
if datatype is None:
- datatype = self.GetPluginDataType(type)
+ datatype = self.GetConfNodeDataType(type)
if datatype is not None:
return project.IsLocatableType(datatype)
return True
@@ -1433,7 +1571,7 @@
if project is not None:
datatype = project.getdataType(type)
if datatype is None:
- datatype = self.GetPluginDataType(type)
+ datatype = self.GetConfNodeDataType(type)
if datatype is not None:
basetype_content = datatype.baseType.getcontent()
return basetype_content["name"] == "enum"
@@ -1448,8 +1586,8 @@
result = project.GetDataTypeRange(type)
if result is not None:
return result
- for plugintype in self.PluginTypes:
- result = plugintype["types"].GetDataTypeRange(type)
+ for confnodetype in self.ConfNodeTypes:
+ result = confnodetype["types"].GetDataTypeRange(type)
if result is not None:
return result
return None
@@ -1460,8 +1598,8 @@
project = self.GetProject(debug)
if project is not None:
subrange_basetypes.extend(project.GetSubrangeBaseTypes(exclude))
- for plugintype in self.PluginTypes:
- subrange_basetypes.extend(plugintype["types"].GetSubrangeBaseTypes(exclude))
+ for confnodetype in self.ConfNodeTypes:
+ subrange_basetypes.extend(confnodetype["types"].GetSubrangeBaseTypes(exclude))
return DataTypeRange.keys() + subrange_basetypes
# Return Enumerated Values
@@ -1472,8 +1610,8 @@
values.extend(project.GetEnumeratedDataTypeValues(type))
if type is None and len(values) > 0:
return values
- for plugintype in self.PluginTypes:
- values.extend(plugintype["types"].GetEnumeratedDataTypeValues(type))
+ for confnodetype in self.ConfNodeTypes:
+ values.extend(confnodetype["types"].GetEnumeratedDataTypeValues(type))
if type is None and len(values) > 0:
return values
return values
@@ -2739,7 +2877,7 @@
for child in tree.childNodes:
if child.nodeType == tree.ELEMENT_NODE and child.nodeName == "project":
try:
- result = self.Project.loadXMLTree(child, ["xmlns", "xmlns:xhtml", "xmlns:xsi", "xsi:schemaLocation"])
+ result = self.Project.loadXMLTree(child)
except ValueError, e:
return _("Project file syntax error:\n\n") + str(e)
self.SetFilePath(filepath)
diff -r 188906a7368c -r ce605c1a6d04 PLCGenerator.py
--- a/PLCGenerator.py Tue May 15 05:19:13 2012 +0900
+++ b/PLCGenerator.py Mon May 21 10:02:54 2012 +0200
@@ -821,6 +821,7 @@
otherInstances["outVariables&coils"].append(instance)
orderedInstances.sort()
otherInstances["outVariables&coils"].sort(SortInstances)
+ otherInstances["blocks"].sort(SortInstances)
instances = [instance for (executionOrderId, instance) in orderedInstances]
instances.extend(otherInstances["connectors"] + otherInstances["outVariables&coils"] + otherInstances["blocks"])
for instance in instances:
diff -r 188906a7368c -r ce605c1a6d04 PLCOpenEditor.py
--- a/PLCOpenEditor.py Tue May 15 05:19:13 2012 +0900
+++ b/PLCOpenEditor.py Mon May 21 10:02:54 2012 +0200
@@ -24,20 +24,14 @@
from datetime import datetime
import wx, wx.grid
-
-if wx.VERSION >= (2, 8, 0):
- import wx.aui
- USE_AUI = True
-else:
- USE_AUI = False
-
+import wx.aui
import os, re, platform, sys, time, traceback, getopt
import cPickle
CWD = os.path.split(os.path.realpath(__file__))[0]
base_folder = os.path.split(CWD)[0]
sys.path.append(base_folder)
-from docutils import *
+from docutil import *
from types import TupleType
@@ -114,18 +108,18 @@
from DataTypeEditor import *
from PLCControler import *
from SearchResultPanel import SearchResultPanel
-from controls import CustomGrid, CustomTable, LibraryPanel
+from controls import CustomGrid, CustomTable, CustomTree, LibraryPanel, PouInstanceVariablesPanel
# Define PLCOpenEditor controls id
[ID_PLCOPENEDITOR, ID_PLCOPENEDITORLEFTNOTEBOOK,
ID_PLCOPENEDITORBOTTOMNOTEBOOK, ID_PLCOPENEDITORRIGHTNOTEBOOK,
- ID_PLCOPENEDITORTYPESTREE, ID_PLCOPENEDITORINSTANCESTREE,
- ID_PLCOPENEDITORMAINSPLITTER, ID_PLCOPENEDITORSECONDSPLITTER,
- ID_PLCOPENEDITORTHIRDSPLITTER, ID_PLCOPENEDITORLIBRARYPANEL,
- ID_PLCOPENEDITORLIBRARYSEARCHCTRL, ID_PLCOPENEDITORLIBRARYTREE,
- ID_PLCOPENEDITORLIBRARYCOMMENT, ID_PLCOPENEDITORTABSOPENED,
- ID_PLCOPENEDITORTABSOPENED, ID_PLCOPENEDITOREDITORMENUTOOLBAR,
- ID_PLCOPENEDITOREDITORTOOLBAR,
+ ID_PLCOPENEDITORPROJECTTREE, ID_PLCOPENEDITORMAINSPLITTER,
+ ID_PLCOPENEDITORSECONDSPLITTER, ID_PLCOPENEDITORTHIRDSPLITTER,
+ ID_PLCOPENEDITORLIBRARYPANEL, ID_PLCOPENEDITORLIBRARYSEARCHCTRL,
+ ID_PLCOPENEDITORLIBRARYTREE, ID_PLCOPENEDITORLIBRARYCOMMENT,
+ ID_PLCOPENEDITORTABSOPENED, ID_PLCOPENEDITORTABSOPENED,
+ ID_PLCOPENEDITOREDITORMENUTOOLBAR, ID_PLCOPENEDITOREDITORTOOLBAR,
+ ID_PLCOPENEDITORPROJECTPANEL,
] = [wx.NewId() for _init_ctrls in range(17)]
# Define PLCOpenEditor FileMenu extra items id
@@ -270,8 +264,8 @@
else:
parent.Append(helpString=help, id=id, kind=kind, item=text)
-[TITLE, EDITORTOOLBAR, FILEMENU, EDITMENU, DISPLAYMENU, TYPESTREE,
- INSTANCESTREE, LIBRARYTREE, SCALING, PAGETITLES
+[TITLE, EDITORTOOLBAR, FILEMENU, EDITMENU, DISPLAYMENU, PROJECTTREE,
+ POUINSTANCEVARIABLESPANEL, LIBRARYTREE, SCALING, PAGETITLES
] = range(10)
def GetShortcutKeyCallbackFunction(viewer_function):
@@ -285,20 +279,13 @@
control.ProcessEvent(event)
return ShortcutKeyFunction
-def GetParentName(tree, item, parent_type):
- parent_item = tree.GetItemParent(item)
- parent_item_type = tree.GetPyData(parent_item)
- while parent_item_type != parent_type:
- parent_item = tree.GetItemParent(parent_item)
- parent_item_type = tree.GetPyData(parent_item)
- return tree.GetItemText(parent_item)
-
def GetDeleteElementFunction(remove_function, parent_type=None, check_function=None):
def DeleteElementFunction(self, selected):
- name = self.TypesTree.GetItemText(selected)
+ name = self.ProjectTree.GetItemText(selected)
if check_function is None or not check_function(self.Controler, name):
if parent_type is not None:
- parent_name = GetParentName(self.TypesTree, selected, parent_type)
+ item_infos = self.ProjectTree.GetPyData(selected)
+ parent_name = item_infos["tagname"].split("::")[1]
remove_function(self.Controler, parent_name, name)
else:
remove_function(self.Controler, name)
@@ -412,6 +399,19 @@
def _init_coll_FileMenu_Items(self, parent):
pass
+ def _init_coll_AddMenu_Items(self, parent, add_config=True):
+ AppendMenu(parent, help='', id=ID_PLCOPENEDITOREDITMENUADDDATATYPE,
+ kind=wx.ITEM_NORMAL, text=_(u'&Data Type'))
+ AppendMenu(parent, help='', id=ID_PLCOPENEDITOREDITMENUADDFUNCTION,
+ kind=wx.ITEM_NORMAL, text=_(u'&Function'))
+ AppendMenu(parent, help='', id=ID_PLCOPENEDITOREDITMENUADDFUNCTIONBLOCK,
+ kind=wx.ITEM_NORMAL, text=_(u'Function &Block'))
+ AppendMenu(parent, help='', id=ID_PLCOPENEDITOREDITMENUADDPROGRAM,
+ kind=wx.ITEM_NORMAL, text=_(u'&Program'))
+ if add_config:
+ AppendMenu(parent, help='', id=ID_PLCOPENEDITOREDITMENUADDCONFIGURATION,
+ kind=wx.ITEM_NORMAL, text=_(u'&Configuration'))
+
def _init_coll_EditMenu_Items(self, parent):
AppendMenu(parent, help='', id=wx.ID_UNDO,
kind=wx.ITEM_NORMAL, text=_(u'Undo\tCTRL+Z'))
@@ -431,18 +431,9 @@
AppendMenu(parent, help='', id=ID_PLCOPENEDITOREDITMENUSEARCHINPROJECT,
kind=wx.ITEM_NORMAL, text=_(u'Search in Project\tCTRL+F'))
parent.AppendSeparator()
- addmenu = wx.Menu(title='')
- parent.AppendMenu(wx.ID_ADD, _(u"&Add Element"), addmenu)
- AppendMenu(addmenu, help='', id=ID_PLCOPENEDITOREDITMENUADDDATATYPE,
- kind=wx.ITEM_NORMAL, text=_(u'&Data Type'))
- AppendMenu(addmenu, help='', id=ID_PLCOPENEDITOREDITMENUADDFUNCTION,
- kind=wx.ITEM_NORMAL, text=_(u'&Function'))
- AppendMenu(addmenu, help='', id=ID_PLCOPENEDITOREDITMENUADDFUNCTIONBLOCK,
- kind=wx.ITEM_NORMAL, text=_(u'Function &Block'))
- AppendMenu(addmenu, help='', id=ID_PLCOPENEDITOREDITMENUADDPROGRAM,
- kind=wx.ITEM_NORMAL, text=_(u'&Program'))
- AppendMenu(addmenu, help='', id=ID_PLCOPENEDITOREDITMENUADDCONFIGURATION,
- kind=wx.ITEM_NORMAL, text=_(u'&Configuration'))
+ add_menu = wx.Menu(title='')
+ self._init_coll_AddMenu_Items(add_menu)
+ parent.AppendMenu(wx.ID_ADD, _(u"&Add Element"), add_menu)
AppendMenu(parent, help='', id=wx.ID_SELECTALL,
kind=wx.ITEM_NORMAL, text=_(u'Select All\tCTRL+A'))
AppendMenu(parent, help='', id=wx.ID_DELETE,
@@ -492,11 +483,10 @@
kind=wx.ITEM_RADIO, text=str(int(round(value * 100))) + "%")
self.Bind(wx.EVT_MENU, self.GenerateZoomFunction(idx), id=new_id)
- if USE_AUI:
- parent.AppendSeparator()
- AppendMenu(parent, help='', id=ID_PLCOPENEDITORDISPLAYMENURESETPERSPECTIVE,
- kind=wx.ITEM_NORMAL, text=_(u'Reset Perspective'))
- self.Bind(wx.EVT_MENU, self.OnResetPerspective, id=ID_PLCOPENEDITORDISPLAYMENURESETPERSPECTIVE)
+ parent.AppendSeparator()
+ AppendMenu(parent, help='', id=ID_PLCOPENEDITORDISPLAYMENURESETPERSPECTIVE,
+ kind=wx.ITEM_NORMAL, text=_(u'Reset Perspective'))
+ self.Bind(wx.EVT_MENU, self.OnResetPerspective, id=ID_PLCOPENEDITORDISPLAYMENURESETPERSPECTIVE)
self.Bind(wx.EVT_MENU, self.OnRefreshMenu, id=wx.ID_REFRESH)
if self.EnableDebug:
@@ -534,103 +524,52 @@
# Creating main structure
#-----------------------------------------------------------------------
- if USE_AUI:
- self.AUIManager = wx.aui.AuiManager(self)
- self.AUIManager.SetDockSizeConstraint(0.5, 0.5)
- self.Panes = {}
-
- self.LeftNoteBook = wx.aui.AuiNotebook(self, ID_PLCOPENEDITORLEFTNOTEBOOK,
- style=wx.aui.AUI_NB_TOP|wx.aui.AUI_NB_TAB_SPLIT|wx.aui.AUI_NB_TAB_MOVE|
- wx.aui.AUI_NB_SCROLL_BUTTONS|wx.aui.AUI_NB_TAB_EXTERNAL_MOVE)
- self.LeftNoteBook.Bind(wx.aui.EVT_AUINOTEBOOK_ALLOW_DND,
- self.OnAllowNotebookDnD)
- self.AUIManager.AddPane(self.LeftNoteBook,
- wx.aui.AuiPaneInfo().Name("ProjectPane").
- Caption(_("Project")).Left().Layer(1).
- BestSize(wx.Size(300, 500)).CloseButton(False))
-
- self.BottomNoteBook = wx.aui.AuiNotebook(self, ID_PLCOPENEDITORBOTTOMNOTEBOOK,
- style=wx.aui.AUI_NB_TOP|wx.aui.AUI_NB_TAB_SPLIT|wx.aui.AUI_NB_TAB_MOVE|
- wx.aui.AUI_NB_SCROLL_BUTTONS|wx.aui.AUI_NB_TAB_EXTERNAL_MOVE)
- self.BottomNoteBook.Bind(wx.aui.EVT_AUINOTEBOOK_ALLOW_DND,
- self.OnAllowNotebookDnD)
- self.AUIManager.AddPane(self.BottomNoteBook,
- wx.aui.AuiPaneInfo().Name("ResultPane").
- Bottom().Layer(0).
- BestSize(wx.Size(800, 300)).CloseButton(False))
-
- self.RightNoteBook = wx.aui.AuiNotebook(self, ID_PLCOPENEDITORRIGHTNOTEBOOK,
- style=wx.aui.AUI_NB_TOP|wx.aui.AUI_NB_TAB_SPLIT|wx.aui.AUI_NB_TAB_MOVE|
- wx.aui.AUI_NB_SCROLL_BUTTONS|wx.aui.AUI_NB_TAB_EXTERNAL_MOVE)
- self.RightNoteBook.Bind(wx.aui.EVT_AUINOTEBOOK_ALLOW_DND,
- self.OnAllowNotebookDnD)
- self.AUIManager.AddPane(self.RightNoteBook,
- wx.aui.AuiPaneInfo().Name("LibraryPane").
- Right().Layer(0).
- BestSize(wx.Size(250, 400)).CloseButton(False))
-
- self.TabsOpened = wx.aui.AuiNotebook(self, ID_PLCOPENEDITORTABSOPENED,
- style=wx.aui.AUI_NB_DEFAULT_STYLE|wx.aui.AUI_NB_WINDOWLIST_BUTTON)
- self.TabsOpened.Bind(wx.aui.EVT_AUINOTEBOOK_PAGE_CHANGING,
- self.OnPouSelectedChanging)
- self.TabsOpened.Bind(wx.aui.EVT_AUINOTEBOOK_PAGE_CHANGED,
- self.OnPouSelectedChanged)
- self.TabsOpened.Bind(wx.aui.EVT_AUINOTEBOOK_PAGE_CLOSE,
- self.OnPageClose)
- self.TabsOpened.Bind(wx.aui.EVT_AUINOTEBOOK_END_DRAG,
- self.OnPageDragged)
- self.AUIManager.AddPane(self.TabsOpened,
- wx.aui.AuiPaneInfo().CentrePane().Name("TabsPane"))
-
- else:
- self.MainSplitter = wx.SplitterWindow(id=ID_PLCOPENEDITORMAINSPLITTER,
- name='MainSplitter', parent=self, point=wx.Point(0, 0),
- size=wx.Size(0, 0), style=wx.SP_3D)
- self.MainSplitter.SetNeedUpdating(True)
- self.MainSplitter.SetMinimumPaneSize(1)
-
- self.LeftNoteBook = wx.Notebook(id=ID_PLCOPENEDITORLEFTNOTEBOOK,
- name='LeftNoteBook', parent=self.MainSplitter, pos=wx.Point(0,
- 0), size=wx.Size(0, 0), style=0)
-
- self.SecondSplitter = wx.SplitterWindow(id=ID_PLCOPENEDITORSECONDSPLITTER,
- name='SecondSplitter', parent=self.MainSplitter, point=wx.Point(0, 0),
- size=wx.Size(0, 0), style=wx.SP_3D)
- self.SecondSplitter.SetMinimumPaneSize(1)
-
- self.MainSplitter.SplitVertically(self.LeftNoteBook, self.SecondSplitter, 200)
-
- self.ThirdSplitter = wx.SplitterWindow(id=ID_PLCOPENEDITORTHIRDSPLITTER,
- name='ThirdSplitter', parent=self.SecondSplitter, point=wx.Point(0, 0),
- size=wx.Size(0, 0), style=wx.SP_3D)
- self.ThirdSplitter.SetMinimumPaneSize(1)
-
- self.BottomNoteBook = wx.Notebook(id=ID_PLCOPENEDITORBOTTOMNOTEBOOK,
- name='BottomNoteBook', parent=self.SecondSplitter, pos=wx.Point(0,
- 0), size=wx.Size(0, 0), style=0)
-
- self.SecondSplitter.SplitHorizontally(self.ThirdSplitter, self.BottomNoteBook, -200)
-
- self.TabsOpened = wx.Notebook(id=ID_PLCOPENEDITORTABSOPENED,
- name='TabsOpened', parent=self.ThirdSplitter, pos=wx.Point(0,
- 0), size=wx.Size(0, 0), style=0)
- self.TabsOpened.SetImageList(self.TabsImageList)
- if wx.VERSION >= (2, 6, 0):
- self.TabsOpened.Bind(wx.EVT_NOTEBOOK_PAGE_CHANGING,
- self.OnPouSelectedChanging, id=ID_PLCOPENEDITORTABSOPENED)
- self.TabsOpened.Bind(wx.EVT_NOTEBOOK_PAGE_CHANGED,
- self.OnPouSelectedChanged, id=ID_PLCOPENEDITORTABSOPENED)
- else:
- wx.EVT_NOTEBOOK_PAGE_CHANGING(self.TabsOpened, ID_PLCOPENEDITORTABSOPENED,
- self.OnPouSelectedChanging)
- wx.EVT_NOTEBOOK_PAGE_CHANGED(self.TabsOpened, ID_PLCOPENEDITORTABSOPENED,
- self.OnPouSelectedChanged)
-
- self.RightNoteBook = wx.Notebook(id=ID_PLCOPENEDITORRIGHTNOTEBOOK,
- name='RightNoteBook', parent=self.ThirdSplitter, pos=wx.Point(0,
- 0), size=wx.Size(0, 0), style=0)
-
- self.ThirdSplitter.SplitVertically(self.TabsOpened, self.RightNoteBook, -250)
+ self.AUIManager = wx.aui.AuiManager(self)
+ self.AUIManager.SetDockSizeConstraint(0.5, 0.5)
+ self.Panes = {}
+
+ self.LeftNoteBook = wx.aui.AuiNotebook(self, ID_PLCOPENEDITORLEFTNOTEBOOK,
+ style=wx.aui.AUI_NB_TOP|wx.aui.AUI_NB_TAB_SPLIT|wx.aui.AUI_NB_TAB_MOVE|
+ wx.aui.AUI_NB_SCROLL_BUTTONS|wx.aui.AUI_NB_TAB_EXTERNAL_MOVE)
+ self.LeftNoteBook.Bind(wx.aui.EVT_AUINOTEBOOK_ALLOW_DND,
+ self.OnAllowNotebookDnD)
+ self.AUIManager.AddPane(self.LeftNoteBook,
+ wx.aui.AuiPaneInfo().Name("ProjectPane").
+ Left().Layer(1).
+ BestSize(wx.Size(300, 500)).CloseButton(False))
+
+ self.BottomNoteBook = wx.aui.AuiNotebook(self, ID_PLCOPENEDITORBOTTOMNOTEBOOK,
+ style=wx.aui.AUI_NB_TOP|wx.aui.AUI_NB_TAB_SPLIT|wx.aui.AUI_NB_TAB_MOVE|
+ wx.aui.AUI_NB_SCROLL_BUTTONS|wx.aui.AUI_NB_TAB_EXTERNAL_MOVE)
+ self.BottomNoteBook.Bind(wx.aui.EVT_AUINOTEBOOK_ALLOW_DND,
+ self.OnAllowNotebookDnD)
+ self.AUIManager.AddPane(self.BottomNoteBook,
+ wx.aui.AuiPaneInfo().Name("ResultPane").
+ Bottom().Layer(0).
+ BestSize(wx.Size(800, 300)).CloseButton(False))
+
+ self.RightNoteBook = wx.aui.AuiNotebook(self, ID_PLCOPENEDITORRIGHTNOTEBOOK,
+ style=wx.aui.AUI_NB_TOP|wx.aui.AUI_NB_TAB_SPLIT|wx.aui.AUI_NB_TAB_MOVE|
+ wx.aui.AUI_NB_SCROLL_BUTTONS|wx.aui.AUI_NB_TAB_EXTERNAL_MOVE)
+ self.RightNoteBook.Bind(wx.aui.EVT_AUINOTEBOOK_ALLOW_DND,
+ self.OnAllowNotebookDnD)
+ self.AUIManager.AddPane(self.RightNoteBook,
+ wx.aui.AuiPaneInfo().Name("LibraryPane").
+ Right().Layer(0).
+ BestSize(wx.Size(250, 400)).CloseButton(False))
+
+ self.TabsOpened = wx.aui.AuiNotebook(self, ID_PLCOPENEDITORTABSOPENED,
+ style=wx.aui.AUI_NB_DEFAULT_STYLE|wx.aui.AUI_NB_WINDOWLIST_BUTTON)
+ self.TabsOpened.Bind(wx.aui.EVT_AUINOTEBOOK_PAGE_CHANGING,
+ self.OnPouSelectedChanging)
+ self.TabsOpened.Bind(wx.aui.EVT_AUINOTEBOOK_PAGE_CHANGED,
+ self.OnPouSelectedChanged)
+ self.TabsOpened.Bind(wx.aui.EVT_AUINOTEBOOK_PAGE_CLOSE,
+ self.OnPageClose)
+ self.TabsOpened.Bind(wx.aui.EVT_AUINOTEBOOK_END_DRAG,
+ self.OnPageDragged)
+ self.AUIManager.AddPane(self.TabsOpened,
+ wx.aui.AuiPaneInfo().CentrePane().Name("TabsPane"))
#-----------------------------------------------------------------------
# Creating PLCopen Project Types Tree
@@ -638,91 +577,78 @@
self.MainTabs = {}
- self.TypesTree = wx.TreeCtrl(id=ID_PLCOPENEDITORTYPESTREE,
- name='TypesTree', parent=self.LeftNoteBook,
+ self.ProjectPanel = wx.SplitterWindow(id=ID_PLCOPENEDITORPROJECTPANEL,
+ name='ProjectPanel', parent=self.LeftNoteBook, point=wx.Point(0, 0),
+ size=wx.Size(0, 0), style=wx.SP_3D)
+
+ self.ProjectTree = CustomTree(id=ID_PLCOPENEDITORPROJECTTREE,
+ name='ProjectTree', parent=self.ProjectPanel,
pos=wx.Point(0, 0), size=wx.Size(0, 0),
style=wx.TR_HAS_BUTTONS|wx.TR_SINGLE|wx.SUNKEN_BORDER|wx.TR_EDIT_LABELS)
+ self.ProjectTree.SetBackgroundBitmap(wx.Bitmap(os.path.join(CWD, 'Images', 'custom_tree_background.png')),
+ wx.ALIGN_RIGHT|wx.ALIGN_BOTTOM)
+ add_menu = wx.Menu()
+ self._init_coll_AddMenu_Items(add_menu)
+ self.ProjectTree.SetAddMenu(add_menu)
if wx.Platform == '__WXMSW__':
- self.Bind(wx.EVT_TREE_ITEM_RIGHT_CLICK, self.OnTypesTreeRightUp,
- id=ID_PLCOPENEDITORTYPESTREE)
- self.Bind(wx.EVT_TREE_SEL_CHANGED, self.OnTypesTreeItemSelected,
- id=ID_PLCOPENEDITORTYPESTREE)
+ self.Bind(wx.EVT_TREE_ITEM_RIGHT_CLICK, self.OnProjectTreeRightUp,
+ id=ID_PLCOPENEDITORPROJECTTREE)
+ self.Bind(wx.EVT_TREE_SEL_CHANGED, self.OnProjectTreeItemSelected,
+ id=ID_PLCOPENEDITORPROJECTTREE)
else:
if wx.VERSION >= (2, 6, 0):
- self.TypesTree.Bind(wx.EVT_RIGHT_UP, self.OnTypesTreeRightUp)
- self.TypesTree.Bind(wx.EVT_LEFT_UP, self.OnTypesTreeLeftUp)
+ self.ProjectTree.Bind(wx.EVT_RIGHT_UP, self.OnProjectTreeRightUp)
+ self.ProjectTree.Bind(wx.EVT_LEFT_UP, self.OnProjectTreeLeftUp)
else:
- wx.EVT_RIGHT_UP(self.TypesTree, self.OnTypesTreeRightUp)
- wx.EVT_LEFT_UP(self.TypesTree, self.OnTypesTreeLeftUp)
- self.Bind(wx.EVT_TREE_SEL_CHANGING, self.OnTypesTreeItemChanging,
- id=ID_PLCOPENEDITORTYPESTREE)
- self.Bind(wx.EVT_TREE_BEGIN_DRAG, self.OnTypesTreeBeginDrag,
- id=ID_PLCOPENEDITORTYPESTREE)
- self.Bind(wx.EVT_TREE_BEGIN_LABEL_EDIT, self.OnTypesTreeItemBeginEdit,
- id=ID_PLCOPENEDITORTYPESTREE)
- self.Bind(wx.EVT_TREE_END_LABEL_EDIT, self.OnTypesTreeItemEndEdit,
- id=ID_PLCOPENEDITORTYPESTREE)
- self.Bind(wx.EVT_TREE_ITEM_ACTIVATED, self.OnTypesTreeItemActivated,
- id=ID_PLCOPENEDITORTYPESTREE)
-
- self.MainTabs["TypesTree"] = (self.TypesTree, _("Types"))
- self.LeftNoteBook.AddPage(*self.MainTabs["TypesTree"])
+ wx.EVT_RIGHT_UP(self.ProjectTree, self.OnProjectTreeRightUp)
+ wx.EVT_LEFT_UP(self.ProjectTree, self.OnProjectTreeLeftUp)
+ self.Bind(wx.EVT_TREE_SEL_CHANGING, self.OnProjectTreeItemChanging,
+ id=ID_PLCOPENEDITORPROJECTTREE)
+ self.Bind(wx.EVT_TREE_BEGIN_DRAG, self.OnProjectTreeBeginDrag,
+ id=ID_PLCOPENEDITORPROJECTTREE)
+ self.Bind(wx.EVT_TREE_BEGIN_LABEL_EDIT, self.OnProjectTreeItemBeginEdit,
+ id=ID_PLCOPENEDITORPROJECTTREE)
+ self.Bind(wx.EVT_TREE_END_LABEL_EDIT, self.OnProjectTreeItemEndEdit,
+ id=ID_PLCOPENEDITORPROJECTTREE)
+ self.Bind(wx.EVT_TREE_ITEM_ACTIVATED, self.OnProjectTreeItemActivated,
+ id=ID_PLCOPENEDITORPROJECTTREE)
#-----------------------------------------------------------------------
- # Creating PLCopen Project Instances Tree
+ # Creating PLCopen Project POU Instance Variables Panel
#-----------------------------------------------------------------------
- self.InstancesTree = wx.TreeCtrl(id=ID_PLCOPENEDITORINSTANCESTREE,
- name='InstancesTree', parent=self.LeftNoteBook,
- pos=wx.Point(0, 0), size=wx.Size(0, 0),
- style=wx.TR_HAS_BUTTONS|wx.TR_SINGLE|wx.SUNKEN_BORDER)
- if self.EnableDebug:
- if wx.VERSION >= (2, 6, 0):
- self.InstancesTree.Bind(wx.EVT_RIGHT_UP, self.OnInstancesTreeRightUp)
- else:
- wx.EVT_RIGHT_UP(self.InstancesTree, self.OnInstancesTreeRightUp)
- self.Bind(wx.EVT_TREE_BEGIN_DRAG, self.OnInstancesTreeBeginDrag,
- id=ID_PLCOPENEDITORINSTANCESTREE)
- self.Bind(wx.EVT_TREE_ITEM_ACTIVATED, self.OnInstancesTreeItemActivated,
- id=ID_PLCOPENEDITORINSTANCESTREE)
-
- self.MainTabs["InstancesTree"] = (self.InstancesTree, _("Instances"))
- self.LeftNoteBook.AddPage(*self.MainTabs["InstancesTree"])
+ self.PouInstanceVariablesPanel = PouInstanceVariablesPanel(self.ProjectPanel, self, self.Controler, self.EnableDebug)
+
+ self.MainTabs["ProjectPanel"] = (self.ProjectPanel, _("Project"))
+ self.LeftNoteBook.AddPage(*self.MainTabs["ProjectPanel"])
+
+ self.ProjectPanel.SplitHorizontally(self.ProjectTree, self.PouInstanceVariablesPanel, 300)
#-----------------------------------------------------------------------
# Creating Tool Bar
#-----------------------------------------------------------------------
- if USE_AUI:
- MenuToolBar = wx.ToolBar(self, ID_PLCOPENEDITOREDITORMENUTOOLBAR, wx.DefaultPosition, wx.DefaultSize,
- wx.TB_FLAT | wx.TB_NODIVIDER | wx.NO_BORDER)
- MenuToolBar.SetToolBitmapSize(wx.Size(25, 25))
- MenuToolBar.Realize()
- self.Panes["MenuToolBar"] = MenuToolBar
- self.AUIManager.AddPane(MenuToolBar, wx.aui.AuiPaneInfo().
- Name("MenuToolBar").Caption(_("Menu ToolBar")).
- ToolbarPane().Top().
- LeftDockable(False).RightDockable(False))
-
- EditorToolBar = wx.ToolBar(self, ID_PLCOPENEDITOREDITORTOOLBAR, wx.DefaultPosition, wx.DefaultSize,
- wx.TB_FLAT | wx.TB_NODIVIDER | wx.NO_BORDER)
- EditorToolBar.SetToolBitmapSize(wx.Size(25, 25))
- EditorToolBar.AddRadioTool(ID_PLCOPENEDITOREDITORTOOLBARSELECTION,
- wx.Bitmap(os.path.join(CWD, 'Images', 'select.png')), wx.NullBitmap, _("Select an object"))
- EditorToolBar.Realize()
- self.Panes["EditorToolBar"] = EditorToolBar
- self.AUIManager.AddPane(EditorToolBar, wx.aui.AuiPaneInfo().
- Name("EditorToolBar").Caption(_("Editor ToolBar")).
- ToolbarPane().Top().Position(1).
- LeftDockable(False).RightDockable(False))
-
- else:
- self.EditorToolBar = self.CreateToolBar(wx.TB_HORIZONTAL|wx.TB_FLAT|wx.NO_BORDER,
- ID_PLCOPENEDITOREDITORTOOLBAR, 'EditorToolBar')
- self.EditorToolBar.SetToolBitmapSize(wx.Size(25, 25))
- self.EditorToolBar.AddRadioTool(ID_PLCOPENEDITOREDITORTOOLBARSELECTION,
- wx.Bitmap(os.path.join(CWD, 'Images', 'select.png')), wx.NullBitmap, _("Select an object"))
- self.EditorToolBar.Realize()
+ MenuToolBar = wx.ToolBar(self, ID_PLCOPENEDITOREDITORMENUTOOLBAR, wx.DefaultPosition, wx.DefaultSize,
+ wx.TB_FLAT | wx.TB_NODIVIDER | wx.NO_BORDER)
+ MenuToolBar.SetToolBitmapSize(wx.Size(25, 25))
+ MenuToolBar.Realize()
+ self.Panes["MenuToolBar"] = MenuToolBar
+ self.AUIManager.AddPane(MenuToolBar, wx.aui.AuiPaneInfo().
+ Name("MenuToolBar").Caption(_("Menu ToolBar")).
+ ToolbarPane().Top().
+ LeftDockable(False).RightDockable(False))
+
+ EditorToolBar = wx.ToolBar(self, ID_PLCOPENEDITOREDITORTOOLBAR, wx.DefaultPosition, wx.DefaultSize,
+ wx.TB_FLAT | wx.TB_NODIVIDER | wx.NO_BORDER)
+ EditorToolBar.SetToolBitmapSize(wx.Size(25, 25))
+ EditorToolBar.AddRadioTool(ID_PLCOPENEDITOREDITORTOOLBARSELECTION,
+ wx.Bitmap(os.path.join(CWD, 'Images', 'select.png')), wx.NullBitmap, _("Select an object"))
+ EditorToolBar.Realize()
+ self.Panes["EditorToolBar"] = EditorToolBar
+ self.AUIManager.AddPane(EditorToolBar, wx.aui.AuiPaneInfo().
+ Name("EditorToolBar").Caption(_("Editor ToolBar")).
+ ToolbarPane().Top().Position(1).
+ LeftDockable(False).RightDockable(False))
self.Bind(wx.EVT_MENU, self.OnSelectionTool,
id=ID_PLCOPENEDITOREDITORTOOLBARSELECTION)
@@ -751,8 +677,7 @@
self.MainTabs["DebugVariablePanel"] = (self.DebugVariablePanel, _("Debugger"))
self.RightNoteBook.AddPage(*self.MainTabs["DebugVariablePanel"])
- if USE_AUI:
- self.AUIManager.Update()
+ self.AUIManager.Update()
## Constructor of the PLCOpenEditor class.
# @param parent The parent window.
@@ -805,8 +730,8 @@
self.TreeImageDict[itemtype]=self.TreeImageList.Add(wx.Bitmap(os.path.join(CWD, 'Images', '%s.png'%imgname)))
# Assign icon list to TreeCtrls
- self.TypesTree.SetImageList(self.TreeImageList)
- self.InstancesTree.SetImageList(self.TreeImageList)
+ self.ProjectTree.SetImageList(self.TreeImageList)
+ self.PouInstanceVariablesPanel.SetTreeImageList(self.TreeImageList)
self.CurrentEditorToolBar = []
self.CurrentMenu = None
@@ -814,8 +739,7 @@
self.Highlights = {}
self.DrawingMode = FREEDRAWING_MODE
#self.DrawingMode = DRIVENDRAWING_MODE
- if USE_AUI:
- self.AuiTabCtrl = []
+ self.AuiTabCtrl = []
self.DefaultPerspective = None
# Initialize Printing configuring elements
@@ -924,17 +848,14 @@
elif page_infos[0] == "editor":
tagname = page_infos[1]
page_ref = self.EditProjectElement(self.Controler.GetElementType(tagname), tagname)
- page_ref.RefreshView()
- return notebook.GetPageIndex(page_ref)
+ if page_ref is not None:
+ page_ref.RefreshView()
+ return notebook.GetPageIndex(page_ref)
elif page_infos[0] == "debug":
instance_path = page_infos[1]
- item = self.GetInstancesTreeItem(self.InstancesTree.GetRootItem(), instance_path)
- item_infos = self.InstancesTree.GetPyData(item)
- if item_infos[1] is not None:
- instance_type = item_infos[1]
- else:
- instance_type = self.InstancesTree.GetItemText(item).split(" (")[1].split(")")[0]
- return notebook.GetPageIndex(self.OpenDebugViewer(item_infos[0], instance_path, instance_type))
+ instance_infos = self.Controler.GetInstanceInfos(instance_path, self.EnableDebug)
+ if instance_infos is not None:
+ return notebook.GetPageIndex(self.OpenDebugViewer(instance_infos["class"], instance_path, instance_infos["type"]))
return None
def LoadTabOrganization(self, notebook, tabs, mode="all", first_index=None):
@@ -967,7 +888,7 @@
wx.CallAfter(notebook.SetSelection, selected)
def ResetPerspective(self):
- if USE_AUI and self.DefaultPerspective is not None:
+ if self.DefaultPerspective is not None:
self.AUIManager.LoadPerspective(self.DefaultPerspective["perspective"])
for notebook in [self.LeftNoteBook, self.BottomNoteBook, self.RightNoteBook]:
@@ -992,36 +913,35 @@
self.SetClientSize(frame_size)
def RestoreLastOrganization(self):
- if USE_AUI:
- notebooks = {}
- for notebook, entry_name in [(self.LeftNoteBook, "leftnotebook"),
- (self.BottomNoteBook, "bottomnotebook"),
- (self.RightNoteBook, "rightnotebook")]:
- notebooks[entry_name] = self.SaveTabOrganization(notebook)
- self.DefaultPerspective = {
- "perspective": self.AUIManager.SavePerspective(),
- "notebooks": notebooks,
- }
-
- try:
- if self.Config.HasEntry("perspective"):
- self.AUIManager.LoadPerspective(str(self.Config.Read("perspective")))
-
- if self.Config.HasEntry("notebooks"):
- notebooks = cPickle.loads(str(self.Config.Read("notebooks")))
-
- for notebook in [self.LeftNoteBook, self.BottomNoteBook, self.RightNoteBook]:
- for idx in xrange(notebook.GetPageCount()):
- notebook.RemovePage(0)
-
- for notebook, entry_name in [(self.LeftNoteBook, "leftnotebook"),
- (self.BottomNoteBook, "bottomnotebook"),
- (self.RightNoteBook, "rightnotebook")]:
- self.LoadTabOrganization(notebook, notebooks.get(entry_name))
- except:
- self.ResetPerspective()
-
- self.LoadProjectOrganization()
+ notebooks = {}
+ for notebook, entry_name in [(self.LeftNoteBook, "leftnotebook"),
+ (self.BottomNoteBook, "bottomnotebook"),
+ (self.RightNoteBook, "rightnotebook")]:
+ notebooks[entry_name] = self.SaveTabOrganization(notebook)
+ self.DefaultPerspective = {
+ "perspective": self.AUIManager.SavePerspective(),
+ "notebooks": notebooks,
+ }
+
+ try:
+ if self.Config.HasEntry("perspective"):
+ self.AUIManager.LoadPerspective(str(self.Config.Read("perspective")))
+
+ if self.Config.HasEntry("notebooks"):
+ notebooks = cPickle.loads(str(self.Config.Read("notebooks")))
+
+ for notebook in [self.LeftNoteBook, self.BottomNoteBook, self.RightNoteBook]:
+ for idx in xrange(notebook.GetPageCount()):
+ notebook.RemovePage(0)
+
+ for notebook, entry_name in [(self.LeftNoteBook, "leftnotebook"),
+ (self.BottomNoteBook, "bottomnotebook"),
+ (self.RightNoteBook, "rightnotebook")]:
+ self.LoadTabOrganization(notebook, notebooks.get(entry_name))
+ except:
+ self.ResetPerspective()
+
+ self.LoadProjectOrganization()
def SaveLastState(self):
if not self.IsMaximized():
@@ -1029,17 +949,16 @@
elif self.Config.HasEntry("framesize"):
self.Config.DeleteEntry("framesize")
- if USE_AUI:
- notebooks = {}
- for notebook, entry_name in [(self.LeftNoteBook, "leftnotebook"),
- (self.BottomNoteBook, "bottomnotebook"),
- (self.RightNoteBook, "rightnotebook")]:
- notebooks[entry_name] = self.SaveTabOrganization(notebook)
- self.Config.Write("notebooks", cPickle.dumps(notebooks))
-
- self.Config.Write("perspective", self.AUIManager.SavePerspective())
-
- self.SaveProjectOrganization()
+ notebooks = {}
+ for notebook, entry_name in [(self.LeftNoteBook, "leftnotebook"),
+ (self.BottomNoteBook, "bottomnotebook"),
+ (self.RightNoteBook, "rightnotebook")]:
+ notebooks[entry_name] = self.SaveTabOrganization(notebook)
+ self.Config.Write("notebooks", cPickle.dumps(notebooks))
+
+ self.Config.Write("perspective", self.AUIManager.SavePerspective())
+
+ self.SaveProjectOrganization()
for i in xrange(self.TabsOpened.GetPageCount()):
self.SavePageState(self.TabsOpened.GetPage(i))
@@ -1047,7 +966,7 @@
self.Config.Flush()
def SaveProjectOrganization(self):
- if USE_AUI and self.Controler is not None:
+ if self.Controler is not None:
tabs = []
projects = {}
@@ -1066,7 +985,7 @@
self.Config.Flush()
def LoadProjectOrganization(self):
- if USE_AUI and self.Controler is not None:
+ if self.Controler is not None:
project = self.GetProjectConfiguration()
try:
@@ -1093,8 +1012,8 @@
FILEMENU : self.RefreshFileMenu,
EDITMENU : self.RefreshEditMenu,
DISPLAYMENU : self.RefreshDisplayMenu,
- TYPESTREE : self.RefreshTypesTree,
- INSTANCESTREE : self.RefreshInstancesTree,
+ PROJECTTREE : self.RefreshProjectTree,
+ POUINSTANCEVARIABLESPANEL : self.RefreshPouInstanceVariablesPanel,
LIBRARYTREE : self.RefreshLibraryPanel,
SCALING : self.RefreshScaling,
PAGETITLES: self.RefreshPageTitles}
@@ -1102,8 +1021,12 @@
## Call PLCOpenEditor refresh functions.
# @param elements List of elements to refresh.
def _Refresh(self, *elements):
- for element in elements:
- self.RefreshFunctions[element]()
+ try:
+ for element in elements:
+ self.RefreshFunctions[element]()
+ except wx.PyDeadObjectError:
+ # ignore exceptions caused by refresh while quitting
+ pass
## Callback function when AUINotebook Page closed with CloseButton
# @param event AUINotebook Event.
@@ -1145,7 +1068,7 @@
editor = self.TabsOpened.GetPage(i)
editor.RefreshScaling()
- def ShowProperties(self):
+ def EditProjectSettings(self):
old_values = self.Controler.GetProjectProperties()
dialog = ProjectDialog(self)
dialog.SetValues(old_values)
@@ -1155,7 +1078,7 @@
if new_values != old_values:
self.Controler.SetProjectProperties(None, new_values)
self._Refresh(TITLE, EDITORTOOLBAR, FILEMENU, EDITMENU, DISPLAYMENU,
- TYPESTREE, INSTANCESTREE, SCALING)
+ PROJECTTREE, POUINSTANCEVARIABLESPANEL, SCALING)
dialog.Destroy()
#-------------------------------------------------------------------------------
@@ -1171,10 +1094,7 @@
index = self.TabsImageListIndexes.get((icon1_name, icon2_name), None)
# Return index or bitmap if found
if index is not None:
- if USE_AUI:
- return self.TabsImageList.GetBitmap(index)
- else:
- return index
+ return self.TabsImageList.GetBitmap(index)
if icon2_name is None:
# Bitmap with only one icon
bitmap = wx.Bitmap(os.path.join(CWD, 'Images', '%s.png'%icon1_name))
@@ -1199,10 +1119,7 @@
index = self.TabsImageList.Add(bitmap)
# Save bitmap index in ImageList in dictionary
self.TabsImageListIndexes[(icon1_name, icon2_name)] = index
- if USE_AUI:
- return bitmap
- else:
- return index
+ return bitmap
## Function that add a tab in Notebook, calling refresh for tab DClick event
# for wx.aui.AUINotebook.
@@ -1226,11 +1143,8 @@
## Function that fix difference in deleting all tabs between
# wx.Notebook and wx.aui.AUINotebook.
def DeleteAllPages(self):
- if USE_AUI:
- for idx in xrange(self.TabsOpened.GetPageCount()):
- self.TabsOpened.DeletePage(0)
- else:
- self.TabsOpened.DeleteAllPages()
+ for idx in xrange(self.TabsOpened.GetPageCount()):
+ self.TabsOpened.DeletePage(0)
self.RefreshTabCtrlEvent()
## Function that fix difference in setting picture on tab between
@@ -1239,10 +1153,7 @@
# @param bitmap wx.Bitmap to define on tab.
# @return True if operation succeeded
def SetPageBitmap(self, idx, bitmap):
- if USE_AUI:
- return self.TabsOpened.SetPageBitmap(idx, bitmap)
- else:
- return self.TabsOpened.SetPageImage(idx, bitmap)
+ return self.TabsOpened.SetPageBitmap(idx, bitmap)
#-------------------------------------------------------------------------------
# Dialog Message Functions
@@ -1277,8 +1188,9 @@
def ResetView(self):
self.DeleteAllPages()
- self.TypesTree.DeleteAllItems()
- self.InstancesTree.DeleteAllItems()
+ self.ProjectTree.DeleteAllItems()
+ self.ProjectTree.Enable(False)
+ self.PouInstanceVariablesPanel.ResetView()
self.LibraryPanel.ResetTree()
self.LibraryPanel.SetControler(None)
self.Controler = None
@@ -1425,7 +1337,7 @@
window.Undo()
else:
self.Controler.LoadPrevious()
- self._Refresh(TITLE, FILEMENU, EDITMENU, TYPESTREE, INSTANCESTREE, LIBRARYTREE,
+ self._Refresh(TITLE, FILEMENU, EDITMENU, PROJECTTREE, POUINSTANCEVARIABLESPANEL, LIBRARYTREE,
SCALING, PAGETITLES)
def OnRedoMenu(self, event):
@@ -1435,7 +1347,7 @@
window.Redo()
else:
self.Controler.LoadNext()
- self._Refresh(TITLE, FILEMENU, EDITMENU, TYPESTREE, INSTANCESTREE, LIBRARYTREE,
+ self._Refresh(TITLE, FILEMENU, EDITMENU, PROJECTTREE, POUINSTANCEVARIABLESPANEL, LIBRARYTREE,
SCALING, PAGETITLES)
def OnEnableUndoRedoMenu(self, event):
@@ -1468,16 +1380,15 @@
def OnDeleteMenu(self, event):
window = self.FindFocus()
- if window == self.TypesTree or window is None:
- selected = self.TypesTree.GetSelection()
+ if window == self.ProjectTree or window is None:
+ selected = self.ProjectTree.GetSelection()
if selected.IsOk():
- type = self.TypesTree.GetPyData(selected)
- function = self.DeleteFunctions.get(type, None)
+ function = self.DeleteFunctions.get(self.ProjectTree.GetPyData(selected)["type"], None)
if function is not None:
function(self, selected)
self.CloseTabsWithoutModel()
- self._Refresh(TITLE, EDITORTOOLBAR, FILEMENU, EDITMENU, TYPESTREE,
- INSTANCESTREE, LIBRARYTREE)
+ self._Refresh(TITLE, EDITORTOOLBAR, FILEMENU, EDITMENU, PROJECTTREE,
+ POUINSTANCEVARIABLESPANEL, LIBRARYTREE)
elif isinstance(window, (Viewer, TextViewer)):
event = wx.KeyEvent(wx.EVT_CHAR._getEvtType())
event.m_keyCode = wx.WXK_DELETE
@@ -1555,19 +1466,22 @@
event.Allow()
def RefreshTabCtrlEvent(self):
- if USE_AUI:
- auitabctrl = []
- for child in self.TabsOpened.GetChildren():
- if isinstance(child, wx.aui.AuiTabCtrl):
- auitabctrl.append(child)
- if child not in self.AuiTabCtrl:
- child.Bind(wx.EVT_LEFT_DCLICK, self.GetTabsOpenedDClickFunction(child))
- self.AuiTabCtrl = auitabctrl
- if self.TabsOpened.GetPageCount() == 0:
- pane = self.AUIManager.GetPane(self.TabsOpened)
- if pane.IsMaximized():
- self.AUIManager.RestorePane(pane)
- self.AUIManager.Update()
+ auitabctrl = []
+ for child in self.TabsOpened.GetChildren():
+ if isinstance(child, wx.aui.AuiTabCtrl):
+ auitabctrl.append(child)
+ if child not in self.AuiTabCtrl:
+ child.Bind(wx.EVT_LEFT_DCLICK, self.GetTabsOpenedDClickFunction(child))
+ self.AuiTabCtrl = auitabctrl
+ if self.TabsOpened.GetPageCount() == 0:
+ pane = self.AUIManager.GetPane(self.TabsOpened)
+ if pane.IsMaximized():
+ self.AUIManager.RestorePane(pane)
+ self.AUIManager.Update()
+
+ def EnsureTabVisible(self, tab):
+ notebook = tab.GetParent()
+ notebook.SetSelection(notebook.GetPageIndex(tab))
def OnPouSelectedChanging(self, event):
if not self.Starting:
@@ -1583,11 +1497,19 @@
selected = self.TabsOpened.GetSelection()
if selected >= 0:
window = self.TabsOpened.GetPage(selected)
+ tagname = window.GetTagName()
if not window.IsDebugging():
- wx.CallAfter(self.SelectTypesTreeItem, window.GetTagName())
+ wx.CallAfter(self.SelectProjectTreeItem, tagname)
+ wx.CallAfter(self.PouInstanceVariablesPanel.SetPouType, tagname)
window.RefreshView()
+ self.EnsureTabVisible(self.LibraryPanel)
else:
- wx.CallAfter(self.SelectInstancesTreeItem, window.GetInstancePath())
+ instance_path = window.GetInstancePath()
+ if tagname == "":
+ instance_path = instance_path.rsplit(".", 1)[0]
+ tagname = self.Controler.GetPouInstanceTagName(instance_path, self.EnableDebug)
+ self.EnsureTabVisible(self.DebugVariablePanel)
+ wx.CallAfter(self.PouInstanceVariablesPanel.SetPouType, tagname, instance_path)
wx.CallAfter(self._Refresh, FILEMENU, EDITMENU, DISPLAYMENU, EDITORTOOLBAR)
event.Skip()
@@ -1596,18 +1518,15 @@
if selected >= 0:
window = self.TabsOpened.GetPage(selected)
if not window.IsDebugging():
- self.SelectTypesTreeItem(window.GetTagName())
+ self.SelectProjectTreeItem(window.GetTagName())
else:
- self.SelectInstancesTreeItem(window.GetInstancePath())
- if USE_AUI:
- for child in self.TabsOpened.GetChildren():
- if isinstance(child, wx.aui.AuiTabCtrl):
- active_page = child.GetActivePage()
- if active_page >= 0:
- window = child.GetWindowFromIdx(active_page)
- window.RefreshView()
- else:
- window.RefreshView()
+ self.PouInstanceVariablesPanel.SetPouType(window.GetTagName(), window.GetInstancePath())
+ for child in self.TabsOpened.GetChildren():
+ if isinstance(child, wx.aui.AuiTabCtrl):
+ active_page = child.GetActivePage()
+ if active_page >= 0:
+ window = child.GetWindowFromIdx(active_page)
+ window.RefreshView()
self._Refresh(FILEMENU, EDITMENU, DISPLAYMENU, EDITORTOOLBAR)
def RefreshEditorNames(self, old_tagname, new_tagname):
@@ -1647,109 +1566,118 @@
# Types Tree Management Functions
#-------------------------------------------------------------------------------
- def RefreshTypesTree(self):
+ def RefreshProjectTree(self):
infos = self.Controler.GetProjectInfos()
- root = self.TypesTree.GetRootItem()
+ root = self.ProjectTree.GetRootItem()
if not root.IsOk():
- root = self.TypesTree.AddRoot(infos["name"])
- self.GenerateTypesTreeBranch(root, infos)
- self.TypesTree.Expand(root)
+ root = self.ProjectTree.AddRoot(infos["name"])
+ self.GenerateProjectTreeBranch(root, infos)
+ self.ProjectTree.Expand(root)
def ResetSelectedItem(self):
self.SelectedItem = None
- def GenerateTypesTreeBranch(self, root, infos, topology=False):
+ def GenerateProjectTreeBranch(self, root, infos):
to_delete = []
item_name = infos["name"]
if infos["type"] in ITEMS_UNEDITABLE:
- item_name = _(item_name)
- self.TypesTree.SetItemText(root, item_name)
- self.TypesTree.SetPyData(root, infos["type"])
+ if len(infos["values"]) == 1:
+ return self.GenerateProjectTreeBranch(root, infos["values"][0])
+ item_name = _(item_name)
+ self.ProjectTree.SetItemText(root, item_name)
+ self.ProjectTree.SetPyData(root, infos)
highlight_colours = self.Highlights.get(infos.get("tagname", None), (wx.WHITE, wx.BLACK))
- self.TypesTree.SetItemBackgroundColour(root, highlight_colours[0])
- self.TypesTree.SetItemTextColour(root, highlight_colours[1])
+ self.ProjectTree.SetItemBackgroundColour(root, highlight_colours[0])
+ self.ProjectTree.SetItemTextColour(root, highlight_colours[1])
if infos["type"] == ITEM_POU:
- self.TypesTree.SetItemImage(root, self.TreeImageDict[self.Controler.GetPouBodyType(infos["name"])])
+ self.ProjectTree.SetItemImage(root, self.TreeImageDict[self.Controler.GetPouBodyType(infos["name"])])
+ elif infos.has_key("icon") and infos["icon"] is not None:
+ icon_path = infos["icon"]
+ if not self.TreeImageDict.has_key(icon_path):
+ self.TreeImageDict[icon_path] = self.TreeImageList.Add(wx.Bitmap(icon_path))
+ self.ProjectTree.SetItemImage(root, self.TreeImageDict[icon_path])
+ elif self.TreeImageDict.has_key(infos["type"]):
+ self.ProjectTree.SetItemImage(root, self.TreeImageDict[infos["type"]])
+
+ if wx.VERSION >= (2, 6, 0):
+ item, root_cookie = self.ProjectTree.GetFirstChild(root)
else:
- self.TypesTree.SetItemImage(root, self.TreeImageDict[infos["type"]])
-
- if wx.VERSION >= (2, 6, 0):
- item, root_cookie = self.TypesTree.GetFirstChild(root)
- else:
- item, root_cookie = self.TypesTree.GetFirstChild(root, 0)
+ item, root_cookie = self.ProjectTree.GetFirstChild(root, 0)
for values in infos["values"]:
- if not item.IsOk():
- item = self.TypesTree.AppendItem(root, "")
- if wx.Platform != '__WXMSW__':
- item, root_cookie = self.TypesTree.GetNextChild(root, root_cookie)
- self.GenerateTypesTreeBranch(item, values)
- item, root_cookie = self.TypesTree.GetNextChild(root, root_cookie)
+ if values["type"] not in ITEMS_UNEDITABLE or len(values["values"]) > 0:
+ if not item.IsOk():
+ item = self.ProjectTree.AppendItem(root, "")
+ if wx.Platform != '__WXMSW__':
+ item, root_cookie = self.ProjectTree.GetNextChild(root, root_cookie)
+ self.GenerateProjectTreeBranch(item, values)
+ item, root_cookie = self.ProjectTree.GetNextChild(root, root_cookie)
while item.IsOk():
to_delete.append(item)
- item, root_cookie = self.TypesTree.GetNextChild(root, root_cookie)
+ item, root_cookie = self.ProjectTree.GetNextChild(root, root_cookie)
for item in to_delete:
- self.TypesTree.Delete(item)
-
- def SelectTypesTreeItem(self, tagname):
- if self.TypesTree is not None:
- root = self.TypesTree.GetRootItem()
+ self.ProjectTree.Delete(item)
+
+ def SelectProjectTreeItem(self, tagname):
+ if self.ProjectTree is not None:
+ root = self.ProjectTree.GetRootItem()
if root.IsOk():
words = tagname.split("::")
if words[0] == "D":
- return self.RecursiveTypesTreeItemSelection(root, [(words[1], ITEM_DATATYPE)])
+ return self.RecursiveProjectTreeItemSelection(root, [(words[1], ITEM_DATATYPE)])
elif words[0] == "P":
- return self.RecursiveTypesTreeItemSelection(root, [(words[1], ITEM_POU)])
+ return self.RecursiveProjectTreeItemSelection(root, [(words[1], ITEM_POU)])
elif words[0] == "T":
- return self.RecursiveTypesTreeItemSelection(root, [(words[1], ITEM_POU), (words[2], ITEM_TRANSITION)])
+ return self.RecursiveProjectTreeItemSelection(root, [(words[1], ITEM_POU), (words[2], ITEM_TRANSITION)])
elif words[0] == "A":
- return self.RecursiveTypesTreeItemSelection(root, [(words[1], ITEM_POU), (words[2], ITEM_ACTION)])
+ return self.RecursiveProjectTreeItemSelection(root, [(words[1], ITEM_POU), (words[2], ITEM_ACTION)])
elif words[0] == "C":
- return self.RecursiveTypesTreeItemSelection(root, [(words[1], ITEM_CONFIGURATION)])
+ return self.RecursiveProjectTreeItemSelection(root, [(words[1], ITEM_CONFIGURATION)])
elif words[0] == "R":
- return self.RecursiveTypesTreeItemSelection(root, [(words[1], ITEM_CONFIGURATION), (words[2], ITEM_RESOURCE)])
+ return self.RecursiveProjectTreeItemSelection(root, [(words[1], ITEM_CONFIGURATION), (words[2], ITEM_RESOURCE)])
return False
- def RecursiveTypesTreeItemSelection(self, root, items):
+ def RecursiveProjectTreeItemSelection(self, root, items):
found = False
if wx.VERSION >= (2, 6, 0):
- item, root_cookie = self.TypesTree.GetFirstChild(root)
+ item, root_cookie = self.ProjectTree.GetFirstChild(root)
else:
- item, root_cookie = self.TypesTree.GetFirstChild(root, 0)
+ item, root_cookie = self.ProjectTree.GetFirstChild(root, 0)
while item.IsOk() and not found:
- if (self.TypesTree.GetItemText(item), self.TypesTree.GetPyData(item)) == items[0]:
+ item_infos = self.ProjectTree.GetPyData(item)
+ if (item_infos["name"].split(":")[-1].strip(), item_infos["type"]) == items[0]:
if len(items) == 1:
self.SelectedItem = item
- self.TypesTree.SelectItem(item)
+ self.ProjectTree.SelectItem(item)
wx.CallAfter(self.ResetSelectedItem)
return True
else:
- found = self.RecursiveTypesTreeItemSelection(item, items[1:])
+ found = self.RecursiveProjectTreeItemSelection(item, items[1:])
else:
- found = self.RecursiveTypesTreeItemSelection(item, items)
- item, root_cookie = self.TypesTree.GetNextChild(root, root_cookie)
+ found = self.RecursiveProjectTreeItemSelection(item, items)
+ item, root_cookie = self.ProjectTree.GetNextChild(root, root_cookie)
return found
- def OnTypesTreeBeginDrag(self, event):
+ def OnProjectTreeBeginDrag(self, event):
if wx.Platform == '__WXMSW__':
self.SelectedItem = event.GetItem()
- if self.SelectedItem is not None and self.TypesTree.GetPyData(self.SelectedItem) == ITEM_POU:
- block_name = self.TypesTree.GetItemText(self.SelectedItem)
+ if self.SelectedItem is not None and self.ProjectTree.GetPyData(self.SelectedItem)["type"] == ITEM_POU:
+ block_name = self.ProjectTree.GetItemText(self.SelectedItem)
block_type = self.Controler.GetPouType(block_name)
if block_type != "program":
data = wx.TextDataObject(str((block_name, block_type, "")))
- dragSource = wx.DropSource(self.TypesTree)
+ dragSource = wx.DropSource(self.ProjectTree)
dragSource.SetData(data)
dragSource.DoDragDrop()
self.ResetSelectedItem()
- def OnTypesTreeItemBeginEdit(self, event):
+ def OnProjectTreeItemBeginEdit(self, event):
selected = event.GetItem()
- if self.TypesTree.GetPyData(selected) in ITEMS_UNEDITABLE:
+ if self.ProjectTree.GetPyData(selected)["type"] in ITEMS_UNEDITABLE:
event.Veto()
else:
event.Skip()
- def OnTypesTreeItemEndEdit(self, event):
+ def OnProjectTreeItemEndEdit(self, event):
message = None
abort = False
new_name = event.GetLabel()
@@ -1760,11 +1688,11 @@
message = _("\"%s\" is a keyword. It can't be used!")%new_name
else:
item = event.GetItem()
- old_name = self.TypesTree.GetItemText(item)
- itemtype = self.TypesTree.GetPyData(item)
- if itemtype == ITEM_PROJECT:
+ old_name = self.ProjectTree.GetItemText(item)
+ item_infos = self.ProjectTree.GetPyData(item)
+ if item_infos["type"] == ITEM_PROJECT:
self.Controler.SetProjectProperties(name = new_name)
- elif itemtype == ITEM_DATATYPE:
+ elif item_infos["type"] == ITEM_DATATYPE:
if new_name.upper() in [name.upper() for name in self.Controler.GetProjectDataTypeNames() if name != old_name]:
message = _("\"%s\" data type already exists!")%new_name
abort = True
@@ -1773,7 +1701,7 @@
self.RefreshEditorNames(self.Controler.ComputeDataTypeName(old_name),
self.Controler.ComputeDataTypeName(new_name))
self.RefreshPageTitles()
- elif itemtype == ITEM_POU:
+ elif item_infos["type"] == ITEM_POU:
if new_name.upper() in [name.upper() for name in self.Controler.GetProjectPouNames() if name != old_name]:
message = _("\"%s\" pou already exists!")%new_name
abort = True
@@ -1788,29 +1716,29 @@
self.Controler.ComputePouName(new_name))
self.RefreshLibraryPanel()
self.RefreshPageTitles()
- elif itemtype == ITEM_TRANSITION:
- pou_name = GetParentName(self.TypesTree, item, ITEM_POU)
+ elif item_infos["type"] == ITEM_TRANSITION:
if new_name.upper() in [name.upper() for name in self.Controler.GetProjectPouNames()]:
message = _("A POU named \"%s\" already exists!")%new_name
elif new_name.upper() in [name.upper() for name in self.Controler.GetProjectPouVariables(pou_name) if name != old_name]:
message = _("A variable with \"%s\" as name already exists in this pou!")%new_name
else:
- self.Controler.ChangePouTransitionName(pou_name, old_name, new_name)
- self.RefreshEditorNames(self.Controler.ComputePouTransitionName(pou_name, old_name),
- self.Controler.ComputePouTransitionName(pou_name, new_name))
+ words = item_infos["tagname"].split("::")
+ self.Controler.ChangePouTransitionName(words[1], old_name, new_name)
+ self.RefreshEditorNames(self.Controler.ComputePouTransitionName(words[1], old_name),
+ self.Controler.ComputePouTransitionName(words[1], new_name))
self.RefreshPageTitles()
- elif itemtype == ITEM_ACTION:
- pou_name = GetParentName(self.TypesTree, item, ITEM_POU)
+ elif item_infos["type"] == ITEM_ACTION:
if new_name.upper() in [name.upper() for name in self.Controler.GetProjectPouNames()]:
message = _("A POU named \"%s\" already exists!")%new_name
elif new_name.upper() in [name.upper() for name in self.Controler.GetProjectPouVariables(pou_name) if name != old_name]:
message = _("A variable with \"%s\" as name already exists in this pou!")%new_name
else:
- self.Controler.ChangePouActionName(pou_name, old_name, new_name)
- self.RefreshEditorNames(self.Controler.ComputePouActionName(pou_name, old_name),
- self.Controler.ComputePouActionName(pou_name, new_name))
+ words = item_infos["tagname"].split("::")
+ self.Controler.ChangePouActionName(words[1], old_name, new_name)
+ self.RefreshEditorNames(self.Controler.ComputePouActionName(words[1], old_name),
+ self.Controler.ComputePouActionName(words[1], new_name))
self.RefreshPageTitles()
- elif itemtype == ITEM_CONFIGURATION:
+ elif item_infos["type"] == ITEM_CONFIGURATION:
if new_name.upper() in [name.upper() for name in self.Controler.GetProjectConfigNames() if name != old_name]:
message = _("\"%s\" config already exists!")%new_name
abort = True
@@ -1829,8 +1757,7 @@
self.RefreshEditorNames(self.Controler.ComputeConfigurationName(old_name),
self.Controler.ComputeConfigurationName(new_name))
self.RefreshPageTitles()
- elif itemtype == ITEM_RESOURCE:
- config_name = GetParentName(self.TypesTree, item, ITEM_CONFIGURATION)
+ elif item_infos["type"] == ITEM_RESOURCE:
if new_name.upper() in [name.upper() for name in self.Controler.GetProjectConfigNames()]:
message = _("\"%s\" config already exists!")%new_name
abort = True
@@ -1845,79 +1772,57 @@
abort = True
messageDialog.Destroy()
if not abort:
- self.Controler.ChangeConfigurationResourceName(config_name, old_name, new_name)
- self.RefreshEditorNames(self.Controler.ComputeConfigurationResourceName(config_name, old_name),
- self.Controler.ComputeConfigurationResourceName(config_name, new_name))
+ words = item_infos["tagname"].split("::")
+ self.Controler.ChangeConfigurationResourceName(words[1], old_name, new_name)
+ self.RefreshEditorNames(self.Controler.ComputeConfigurationResourceName(words[1], old_name),
+ self.Controler.ComputeConfigurationResourceName(words[1], new_name))
self.RefreshPageTitles()
if message or abort:
if message:
self.ShowErrorMessage(message)
item = event.GetItem()
- wx.CallAfter(self.TypesTree.EditLabel, item)
+ wx.CallAfter(self.ProjectTree.EditLabel, item)
event.Veto()
else:
- wx.CallAfter(self.RefreshTypesTree)
+ wx.CallAfter(self.RefreshProjectTree)
self.RefreshEditor()
self._Refresh(TITLE, FILEMENU, EDITMENU)
event.Skip()
- def OnTypesTreeItemActivated(self, event):
+ def OnProjectTreeItemActivated(self, event):
selected = event.GetItem()
- name = self.TypesTree.GetItemText(selected)
- data = self.TypesTree.GetPyData(selected)
- if UNEDITABLE_NAMES_DICT.get(name, name) == "Properties":
- self.ShowProperties()
- if data == ITEM_DATATYPE:
- self.EditProjectElement(data, self.Controler.ComputeDataTypeName(name))
- elif data == ITEM_POU:
- self.EditProjectElement(data, self.Controler.ComputePouName(name))
- elif data == ITEM_CONFIGURATION:
- self.EditProjectElement(data, self.Controler.ComputeConfigurationName(name))
- elif data == ITEM_RESOURCE:
- config_name = GetParentName(self.TypesTree, selected, ITEM_CONFIGURATION)
- self.EditProjectElement(data, self.Controler.ComputeConfigurationResourceName(config_name, name))
- elif data in [ITEM_TRANSITION, ITEM_ACTION]:
- pou_name = GetParentName(self.TypesTree, selected, ITEM_POU)
- if data == ITEM_TRANSITION:
- tagname = self.Controler.ComputePouTransitionName(pou_name, name)
- elif data == ITEM_ACTION:
- tagname = self.Controler.ComputePouActionName(pou_name, name)
- self.EditProjectElement(data, tagname)
+ name = self.ProjectTree.GetItemText(selected)
+ item_infos = self.ProjectTree.GetPyData(selected)
+ if item_infos["type"] == ITEM_PROJECT:
+ self.EditProjectSettings()
+ elif item_infos["type"] in [ITEM_DATATYPE, ITEM_POU,
+ ITEM_CONFIGURATION, ITEM_RESOURCE,
+ ITEM_TRANSITION, ITEM_ACTION]:
+ self.EditProjectElement(item_infos["type"], item_infos["tagname"])
event.Skip()
- def TypesTreeItemSelect(self, select_item):
- name = self.TypesTree.GetItemText(select_item)
- data = self.TypesTree.GetPyData(select_item)
- if data == ITEM_DATATYPE:
- self.EditProjectElement(data, self.Controler.ComputeDataTypeName(name), True)
- elif data == ITEM_POU:
- self.EditProjectElement(data, self.Controler.ComputePouName(name), True)
- elif data == ITEM_CONFIGURATION:
- self.EditProjectElement(data, self.Controler.ComputeConfigurationName(name), True)
- elif data == ITEM_RESOURCE:
- config_name = GetParentName(self.TypesTree, select_item, ITEM_CONFIGURATION)
- self.EditProjectElement(data, self.Controler.ComputeConfigurationResourceName(config_name, name), True)
- elif data in [ITEM_TRANSITION, ITEM_ACTION]:
- pou_name = GetParentName(self.TypesTree, select_item, ITEM_POU)
- if data == ITEM_TRANSITION:
- tagname = self.Controler.ComputePouTransitionName(pou_name, name)
- elif data == ITEM_ACTION:
- tagname = self.Controler.ComputePouActionName(pou_name, name)
- self.EditProjectElement(data, tagname, True)
-
- def OnTypesTreeLeftUp(self, event):
+ def ProjectTreeItemSelect(self, select_item):
+ name = self.ProjectTree.GetItemText(select_item)
+ item_infos = self.ProjectTree.GetPyData(select_item)
+ if item_infos["type"] in [ITEM_DATATYPE, ITEM_POU,
+ ITEM_CONFIGURATION, ITEM_RESOURCE,
+ ITEM_TRANSITION, ITEM_ACTION]:
+ self.EditProjectElement(item_infos["type"], item_infos["tagname"], True)
+ self.PouInstanceVariablesPanel.SetPouType(item_infos["tagname"])
+
+ def OnProjectTreeLeftUp(self, event):
if self.SelectedItem is not None:
- self.TypesTree.SelectItem(self.SelectedItem)
- self.TypesTreeItemSelect(self.SelectedItem)
+ self.ProjectTree.SelectItem(self.SelectedItem)
+ self.ProjectTreeItemSelect(self.SelectedItem)
wx.CallAfter(self.ResetSelectedItem)
event.Skip()
- def OnTypesTreeItemSelected(self, event):
- self.TypesTreeItemSelect(event.GetItem())
+ def OnProjectTreeItemSelected(self, event):
+ self.ProjectTreeItemSelect(event.GetItem())
event.Skip()
- def OnTypesTreeItemChanging(self, event):
- if self.TypesTree.GetPyData(event.GetItem()) not in ITEMS_UNEDITABLE and self.SelectedItem is None:
+ def OnProjectTreeItemChanging(self, event):
+ if self.ProjectTree.GetPyData(event.GetItem())["type"] not in ITEMS_UNEDITABLE and self.SelectedItem is None:
self.SelectedItem = event.GetItem()
event.Veto()
else:
@@ -1996,18 +1901,18 @@
self.RefreshPageTitles()
return new_window
- def OnTypesTreeRightUp(self, event):
+ def OnProjectTreeRightUp(self, event):
if wx.Platform == '__WXMSW__':
item = event.GetItem()
else:
- item, flags = self.TypesTree.HitTest(wx.Point(event.GetX(), event.GetY()))
- self.TypesTree.SelectItem(item)
- self.TypesTreeItemSelect(item)
- name = self.TypesTree.GetItemText(item)
- type = self.TypesTree.GetPyData(item)
+ item, flags = self.ProjectTree.HitTest(wx.Point(event.GetX(), event.GetY()))
+ self.ProjectTree.SelectItem(item)
+ self.ProjectTreeItemSelect(item)
+ name = self.ProjectTree.GetItemText(item)
+ item_infos = self.ProjectTree.GetPyData(item)
menu = None
- if type in ITEMS_UNEDITABLE:
+ if item_infos["type"] in ITEMS_UNEDITABLE:
name = UNEDITABLE_NAMES_DICT[name]
if name == "Data Types":
@@ -2039,37 +1944,41 @@
menu = wx.Menu(title='')
new_id = wx.NewId()
AppendMenu(menu, help='', id=new_id, kind=wx.ITEM_NORMAL, text=_("Add Transition"))
- parent = self.TypesTree.GetItemParent(item)
- parent_type = self.TypesTree.GetPyData(parent)
+ parent = self.ProjectTree.GetItemParent(item)["type"]
+ parent_type = self.ProjectTree.GetPyData(parent)
while parent_type != ITEM_POU:
- parent = self.TypesTree.GetItemParent(parent)
- parent_type = self.TypesTree.GetPyData(parent)
- self.Bind(wx.EVT_MENU, self.GenerateAddTransitionFunction(self.TypesTree.GetItemText(parent)), id=new_id)
+ parent = self.ProjectTree.GetItemParent(parent)
+ parent_type = self.ProjectTree.GetPyData(parent)["type"]
+ self.Bind(wx.EVT_MENU, self.GenerateAddTransitionFunction(self.ProjectTree.GetItemText(parent)), id=new_id)
elif name == "Actions":
menu = wx.Menu(title='')
new_id = wx.NewId()
AppendMenu(menu, help='', id=new_id, kind=wx.ITEM_NORMAL, text=_("Add Action"))
- parent = self.TypesTree.GetItemParent(item)
- parent_type = self.TypesTree.GetPyData(parent)
+ parent = self.ProjectTree.GetItemParent(item)
+ parent_type = self.ProjectTree.GetPyData(parent)["type"]
while parent_type != ITEM_POU:
- parent = self.TypesTree.GetItemParent(parent)
- parent_type = self.TypesTree.GetPyData(parent)
- self.Bind(wx.EVT_MENU, self.GenerateAddActionFunction(self.TypesTree.GetItemText(parent)), id=new_id)
+ parent = self.ProjectTree.GetItemParent(parent)
+ parent_type = self.ProjectTree.GetPyData(parent)["type"]
+ self.Bind(wx.EVT_MENU, self.GenerateAddActionFunction(self.ProjectTree.GetItemText(parent)), id=new_id)
elif name == "Resources":
menu = wx.Menu(title='')
new_id = wx.NewId()
AppendMenu(menu, help='', id=new_id, kind=wx.ITEM_NORMAL, text=_("Add Resource"))
- parent = self.TypesTree.GetItemParent(item)
- parent_type = self.TypesTree.GetPyData(parent)
- while parent_type != ITEM_CONFIGURATION:
- parent = self.TypesTree.GetItemParent(parent)
- parent_type = self.TypesTree.GetPyData(parent)
- self.Bind(wx.EVT_MENU, self.GenerateAddResourceFunction(self.TypesTree.GetItemText(parent)), id=new_id)
+ parent = self.ProjectTree.GetItemParent(item)
+ parent_type = self.ProjectTree.GetPyData(parent)["type"]
+ while parent_type not in [ITEM_CONFIGURATION, ITEM_PROJECT]:
+ parent = self.ProjectTree.GetItemParent(parent)
+ parent_type = self.ProjectTree.GetPyData(parent)["type"]
+ if parent_type == ITEM_PROJECT:
+ parent_name = None
+ else:
+ parent_name = self.ProjectTree.GetItemText(parent)
+ self.Bind(wx.EVT_MENU, self.GenerateAddResourceFunction(parent_name), id=new_id)
else:
- if type == ITEM_POU:
+ if item_infos["type"] == ITEM_POU:
menu = wx.Menu(title='')
if self.Controler.GetPouBodyType(name) == "SFC":
new_id = wx.NewId()
@@ -2099,13 +2008,13 @@
AppendMenu(menu, help='', id=new_id, kind=wx.ITEM_NORMAL, text=_("Rename"))
self.Bind(wx.EVT_MENU, self.OnRenamePouMenu, id=new_id)
- elif type == ITEM_CONFIGURATION:
+ elif item_infos["type"] == ITEM_CONFIGURATION:
menu = wx.Menu(title='')
new_id = wx.NewId()
AppendMenu(menu, help='', id=new_id, kind=wx.ITEM_NORMAL, text=_("Add Resource"))
self.Bind(wx.EVT_MENU, self.GenerateAddResourceFunction(name), id=new_id)
- elif type in [ITEM_DATATYPE, ITEM_TRANSITION, ITEM_ACTION, ITEM_RESOURCE]:
+ elif item_infos["type"] in [ITEM_DATATYPE, ITEM_TRANSITION, ITEM_ACTION, ITEM_RESOURCE]:
menu = wx.Menu(title='')
if menu is not None:
@@ -2124,83 +2033,11 @@
# Instances Tree Management Functions
#-------------------------------------------------------------------------------
- def RefreshInstancesTree(self):
- infos = self.Controler.GetProjectTopology(self.EnableDebug)
- root = self.InstancesTree.GetRootItem()
- if not root.IsOk():
- root = self.InstancesTree.AddRoot(infos["name"])
- self.GenerateInstancesTreeBranch(root, infos)
- self.InstancesTree.Expand(root)
-
- def GenerateInstancesTreeBranch(self, root, infos):
- to_delete = []
- if infos.get("elmt_type", None) is not None:
- self.InstancesTree.SetItemText(root, "%s (%s)"%(infos["name"], infos["elmt_type"]))
- else:
- self.InstancesTree.SetItemText(root, infos["name"])
- self.InstancesTree.SetPyData(root, (infos["type"], infos.get("tagname", None)))
- self.InstancesTree.SetItemImage(root, self.TreeImageDict[infos["type"]])
-
- if wx.VERSION >= (2, 6, 0):
- item, root_cookie = self.InstancesTree.GetFirstChild(root)
- else:
- item, root_cookie = self.InstancesTree.GetFirstChild(root, 0)
- for values in infos["values"]:
- if not item.IsOk():
- item = self.InstancesTree.AppendItem(root, "")
- if wx.Platform != '__WXMSW__':
- item, root_cookie = self.InstancesTree.GetNextChild(root, root_cookie)
- self.GenerateInstancesTreeBranch(item, values)
- item, root_cookie = self.InstancesTree.GetNextChild(root, root_cookie)
- while item.IsOk():
- to_delete.append(item)
- item, root_cookie = self.InstancesTree.GetNextChild(root, root_cookie)
- for item in to_delete:
- self.InstancesTree.Delete(item)
- if infos["type"] in [ITEM_CONFIGURATION, ITEM_RESOURCE]:
- self.InstancesTree.Expand(root)
-
- def OnInstancesTreeBeginDrag(self, event):
- if self.Controler.DebugAvailable():
- selected_item = event.GetItem()
- selected_infos = self.InstancesTree.GetPyData(selected_item)
- if selected_item is not None and selected_infos[0] in ITEMS_VARIABLE:
- var_path = self.InstancesTree.GetItemText(selected_item).split(" (")[0]
- parent_item = self.InstancesTree.GetItemParent(selected_item)
- while self.InstancesTree.GetPyData(parent_item)[0] != ITEM_PROJECT:
- parent_name = self.InstancesTree.GetItemText(parent_item).split(" (")[0]
- var_path = "%s.%s"%(parent_name, var_path)
- parent_item = self.InstancesTree.GetItemParent(parent_item)
- data = wx.TextDataObject(str((var_path, "debug")))
- dragSource = wx.DropSource(self.InstancesTree)
- dragSource.SetData(data)
- dragSource.DoDragDrop()
- event.Skip()
- else:
- event.Veto()
-
- def OnInstancesTreeItemActivated(self, event):
- if self.Controler.DebugAvailable():
- selected_item = event.GetItem()
- selected_infos = self.InstancesTree.GetPyData(selected_item)
- if selected_item is not None and (
- selected_infos[0] in [ITEM_FUNCTIONBLOCK, ITEM_PROGRAM, ITEM_TRANSITION, ITEM_ACTION] or
- selected_infos[0] in ITEMS_VARIABLE):
-
- instance_path, var_type = self.InstancesTree.GetItemText(selected_item).split(" (")
- if selected_infos[1] is not None:
- instance_type = selected_infos[1]
- else:
- instance_type = var_type.split(")")[0]
- parent_item = self.InstancesTree.GetItemParent(selected_item)
- while self.InstancesTree.GetPyData(parent_item)[0] != ITEM_PROJECT:
- parent_name = self.InstancesTree.GetItemText(parent_item).split(" (")[0]
- instance_path = "%s.%s"%(parent_name, instance_path)
- parent_item = self.InstancesTree.GetItemParent(parent_item)
-
- self.OpenDebugViewer(selected_infos[0], instance_path, instance_type)
-
- event.Skip()
+ def GetTreeImage(self, var_class):
+ return self.TreeImageDict[var_class]
+
+ def RefreshPouInstanceVariablesPanel(self):
+ self.PouInstanceVariablesPanel.RefreshView()
def OpenDebugViewer(self, instance_category, instance_path, instance_type):
openedidx = self.IsOpened(instance_path)
@@ -2267,66 +2104,6 @@
self.RefreshPageTitles()
return new_window
- def OnInstancesTreeRightUp(self, event):
- if self.Controler.DebugAvailable():
- if wx.Platform == '__WXMSW__':
- selected_item = event.GetItem()
- else:
- selected_item = self.InstancesTree.GetSelection()
- selected_infos = self.InstancesTree.GetPyData(selected_item)
- if selected_item is not None and selected_infos[0] in ITEMS_VARIABLE:
- var_path, var_type = self.InstancesTree.GetItemText(selected_item).split(" (")
- var_type = var_type.split(")")[0]
-
- if self.Controler.IsOfType(var_type, "ANY_NUM", True) or\
- self.Controler.IsOfType(var_type, "ANY_BIT", True):
- parent_item = self.InstancesTree.GetItemParent(selected_item)
- while self.InstancesTree.GetPyData(parent_item)[0] != ITEM_PROJECT:
- parent_name = self.InstancesTree.GetItemText(parent_item).split(" (")[0]
- var_path = "%s.%s"%(parent_name, var_path)
- parent_item = self.InstancesTree.GetItemParent(parent_item)
-
- menu = wx.Menu(title='')
- new_id = wx.NewId()
- AppendMenu(menu, help='', id=new_id, kind=wx.ITEM_NORMAL, text=_("Graphic Panel"))
- self.Bind(wx.EVT_MENU, self.AddVariableGraphicFunction(var_path), id=new_id)
- new_id = wx.NewId()
- AppendMenu(menu, help='', id=new_id, kind=wx.ITEM_NORMAL, text=_("CSV Log"))
- self.PopupMenu(menu)
- event.Skip()
-
- def AddVariableGraphicFunction(self, iec_path):
- def AddVariableGraphic(event):
- self.OpenGraphicViewer(iec_path)
- event.Skip()
- return AddVariableGraphic
-
- def GetInstancesTreeItem(self, root, instancepath):
- paths = instancepath.split(".", 1)
- if wx.VERSION >= (2, 6, 0):
- item, root_cookie = self.InstancesTree.GetFirstChild(root)
- else:
- item, root_cookie = self.InstancesTree.GetFirstChild(root, 0)
- while item.IsOk():
- name = self.InstancesTree.GetItemText(item).split(" (")[0]
- if name == paths[0]:
- if len(paths) == 1:
- return item
- else:
- return self.GetInstancesTreeItem(item, paths[1])
- item, root_cookie = self.InstancesTree.GetNextChild(root, root_cookie)
- return None
-
- def SelectInstancesTreeItem(self, instancepath):
- if self.InstancesTree is not None:
- root = self.InstancesTree.GetRootItem()
- if root.IsOk():
- item = self.GetInstancesTreeItem(root, instancepath)
- if item is not None:
- self.InstancesTree.SelectItem(item)
- return True
- return False
-
def ResetGraphicViewers(self):
for i in xrange(self.TabsOpened.GetPageCount()):
editor = self.TabsOpened.GetPage(i)
@@ -2337,18 +2114,11 @@
if self.EnableDebug:
idxs = range(self.TabsOpened.GetPageCount())
idxs.reverse()
- root = None
- if self.InstancesTree is not None:
- root = self.InstancesTree.GetRootItem()
- if not root.IsOk():
- root = None
for idx in idxs:
editor = self.TabsOpened.GetPage(idx)
if editor.IsDebugging():
- item = None
- if root is not None:
- item = self.GetInstancesTreeItem(root, editor.GetInstancePath())
- if item is None:
+ instance_infos = self.Controler.GetInstanceInfos(editor.GetInstancePath(), self.EnableDebug)
+ if instance_infos is None:
self.TabsOpened.DeletePage(idx)
elif isinstance(editor, GraphicViewer):
editor.ResetView(True)
@@ -2356,9 +2126,10 @@
editor.RefreshView()
self.DebugVariablePanel.UnregisterObsoleteData()
- def AddDebugVariable(self, iec_path):
+ def AddDebugVariable(self, iec_path, force=False):
if self.EnableDebug:
- self.DebugVariablePanel.InsertValue(iec_path)
+ self.DebugVariablePanel.InsertValue(iec_path, force=force)
+ self.EnsureTabVisible(self.DebugVariablePanel)
#-------------------------------------------------------------------------------
# Library Panel Management Function
@@ -2384,14 +2155,10 @@
if callback is not None:
self.Bind(wx.EVT_TOOL, callback, id=id)
MenuToolBar.Realize()
- if USE_AUI:
- self.AUIManager.GetPane("MenuToolBar").BestSize(MenuToolBar.GetBestSize())
+ self.AUIManager.GetPane("MenuToolBar").BestSize(MenuToolBar.GetBestSize())
def ResetEditorToolBar(self):
- if USE_AUI:
- EditorToolBar = self.Panes["EditorToolBar"]
- else:
- EditorToolBar = self.EditorToolBar
+ EditorToolBar = self.Panes["EditorToolBar"]
for item in self.CurrentEditorToolBar:
if wx.VERSION >= (2, 6, 0):
@@ -2404,9 +2171,8 @@
if EditorToolBar:
EditorToolBar.Realize()
- if USE_AUI:
- self.AUIManager.GetPane("EditorToolBar").BestSize(EditorToolBar.GetBestSize())
- self.AUIManager.Update()
+ self.AUIManager.GetPane("EditorToolBar").BestSize(EditorToolBar.GetBestSize())
+ self.AUIManager.Update()
def RefreshEditorToolBar(self):
selected = self.TabsOpened.GetSelection()
@@ -2421,10 +2187,7 @@
self.ResetEditorToolBar()
self.CurrentMenu = menu
self.CurrentEditorToolBar = []
- if USE_AUI:
- EditorToolBar = self.Panes["EditorToolBar"]
- else:
- EditorToolBar = self.EditorToolBar
+ EditorToolBar = self.Panes["EditorToolBar"]
if EditorToolBar:
for radio, modes, id, method, picture, help in EditorToolBarItems[menu]:
if modes & self.DrawingMode:
@@ -2435,9 +2198,8 @@
self.Bind(wx.EVT_MENU, getattr(self, method), id=id)
self.CurrentEditorToolBar.append(id)
EditorToolBar.Realize()
- if USE_AUI:
- self.AUIManager.GetPane("EditorToolBar").BestSize(EditorToolBar.GetBestSize())
- self.AUIManager.Update()
+ self.AUIManager.GetPane("EditorToolBar").BestSize(EditorToolBar.GetBestSize())
+ self.AUIManager.Update()
elif not menu:
self.ResetEditorToolBar()
self.CurrentMenu = menu
@@ -2453,19 +2215,13 @@
if selected != -1:
window = self.TabsOpened.GetPage(selected)
window.SetMode(MODE_SELECTION)
- if USE_AUI:
- EditorToolBar = self.Panes["EditorToolBar"]
- else:
- EditorToolBar = self.EditorToolBar
+ EditorToolBar = self.Panes["EditorToolBar"]
if EditorToolBar:
EditorToolBar.ToggleTool(ID_PLCOPENEDITOREDITORTOOLBARSELECTION, False)
EditorToolBar.ToggleTool(ID_PLCOPENEDITOREDITORTOOLBARSELECTION, True)
def ResetToolToggle(self, id):
- if USE_AUI:
- tool = self.Panes["EditorToolBar"].FindById(id)
- else:
- tool = self.EditorToolBar.FindById(id)
+ tool = self.Panes["EditorToolBar"].FindById(id)
tool.SetToggle(False)
def OnSelectionTool(self, event):
@@ -2599,7 +2355,7 @@
if dialog.ShowModal() == wx.ID_OK:
tagname = self.Controler.ProjectAddDataType(dialog.GetValue())
if tagname is not None:
- self._Refresh(TITLE, FILEMENU, EDITMENU, TYPESTREE)
+ self._Refresh(TITLE, FILEMENU, EDITMENU, PROJECTTREE)
self.EditProjectElement(ITEM_DATATYPE, tagname)
dialog.Destroy()
@@ -2612,7 +2368,7 @@
values = dialog.GetValues()
tagname = self.Controler.ProjectAddPou(values["pouName"], values["pouType"], values["language"])
if tagname is not None:
- self._Refresh(TITLE, FILEMENU, EDITMENU, TYPESTREE, LIBRARYTREE)
+ self._Refresh(TITLE, FILEMENU, EDITMENU, PROJECTTREE, LIBRARYTREE)
self.EditProjectElement(ITEM_POU, tagname)
dialog.Destroy()
return OnAddPouMenu
@@ -2626,7 +2382,7 @@
values = dialog.GetValues()
tagname = self.Controler.ProjectAddPouTransition(pou_name, values["transitionName"], values["language"])
if tagname is not None:
- self._Refresh(TITLE, FILEMENU, EDITMENU, TYPESTREE)
+ self._Refresh(TITLE, FILEMENU, EDITMENU, PROJECTTREE)
self.EditProjectElement(ITEM_TRANSITION, tagname)
dialog.Destroy()
return OnAddTransitionMenu
@@ -2640,7 +2396,7 @@
values = dialog.GetValues()
tagname = self.Controler.ProjectAddPouAction(pou_name, values["actionName"], values["language"])
if tagname is not None:
- self._Refresh(TITLE, FILEMENU, EDITMENU, TYPESTREE)
+ self._Refresh(TITLE, FILEMENU, EDITMENU, PROJECTTREE)
self.EditProjectElement(ITEM_ACTION, tagname)
dialog.Destroy()
return OnAddActionMenu
@@ -2653,7 +2409,7 @@
value = dialog.GetValue()
tagname = self.Controler.ProjectAddConfiguration(value)
if tagname is not None:
- self._Refresh(TITLE, FILEMENU, EDITMENU, TYPESTREE, INSTANCESTREE)
+ self._Refresh(TITLE, FILEMENU, EDITMENU, PROJECTTREE, POUINSTANCEVARIABLESPANEL)
self.EditProjectElement(ITEM_CONFIGURATION, tagname)
dialog.Destroy()
@@ -2666,22 +2422,22 @@
value = dialog.GetValue()
tagname = self.Controler.ProjectAddConfigurationResource(config_name, value)
if tagname is not None:
- self._Refresh(TITLE, FILEMENU, EDITMENU, TYPESTREE, INSTANCESTREE)
+ self._Refresh(TITLE, FILEMENU, EDITMENU, PROJECTTREE, POUINSTANCEVARIABLESPANEL)
self.EditProjectElement(ITEM_RESOURCE, tagname)
dialog.Destroy()
return OnAddResourceMenu
def GenerateChangePouTypeFunction(self, name, new_type):
def OnChangePouTypeMenu(event):
- selected = self.TypesTree.GetSelection()
- if self.TypesTree.GetPyData(selected) == ITEM_POU:
+ selected = self.ProjectTree.GetSelection()
+ if self.ProjectTree.GetPyData(selected)["type"] == ITEM_POU:
self.Controler.ProjectChangePouType(name, new_type)
- self._Refresh(TITLE, EDITORTOOLBAR, FILEMENU, EDITMENU, TYPESTREE, LIBRARYTREE)
+ self._Refresh(TITLE, EDITORTOOLBAR, FILEMENU, EDITMENU, PROJECTTREE, LIBRARYTREE)
return OnChangePouTypeMenu
def OnCopyPou(self, event):
- selected = self.TypesTree.GetSelection()
- pou_name = self.TypesTree.GetItemText(selected)
+ selected = self.ProjectTree.GetSelection()
+ pou_name = self.ProjectTree.GetItemText(selected)
pou_xml = self.Controler.GetPouXml(pou_name)
if pou_xml is not None:
@@ -2689,9 +2445,9 @@
self._Refresh(EDITMENU)
def OnPastePou(self, event):
- selected = self.TypesTree.GetSelection()
-
- pou_type = self.TypesTree.GetItemText(selected)
+ selected = self.ProjectTree.GetSelection()
+
+ pou_type = self.ProjectTree.GetItemText(selected)
pou_type = UNEDITABLE_NAMES_DICT[pou_type] # one of 'Functions', 'Function Blocks' or 'Programs'
pou_type = {'Functions': 'function', 'Function Blocks': 'functionBlock', 'Programs': 'program'}[pou_type]
@@ -2704,106 +2460,94 @@
message.ShowModal()
message.Destroy()
else:
- self._Refresh(TITLE, EDITORTOOLBAR, FILEMENU, EDITMENU, TYPESTREE, LIBRARYTREE)
+ self._Refresh(TITLE, EDITORTOOLBAR, FILEMENU, EDITMENU, PROJECTTREE, LIBRARYTREE)
#-------------------------------------------------------------------------------
# Remove Project Elements Functions
#-------------------------------------------------------------------------------
def OnRemoveDataTypeMenu(self, event):
- selected = self.TypesTree.GetSelection()
- if self.TypesTree.GetPyData(selected) == ITEM_DATATYPE:
- name = self.TypesTree.GetItemText(selected)
+ selected = self.ProjectTree.GetSelection()
+ if self.ProjectTree.GetPyData(selected)["type"] == ITEM_DATATYPE:
+ name = self.ProjectTree.GetItemText(selected)
if not self.Controler.DataTypeIsUsed(name):
self.Controler.ProjectRemoveDataType(name)
tagname = self.Controler.ComputeDataTypeName(name)
idx = self.IsOpened(tagname)
if idx is not None:
self.TabsOpened.DeletePage(idx)
- self._Refresh(TITLE, EDITORTOOLBAR, FILEMENU, EDITMENU, TYPESTREE)
+ self._Refresh(TITLE, EDITORTOOLBAR, FILEMENU, EDITMENU, PROJECTTREE)
else:
self.ShowErrorMessage(_("\"%s\" is used by one or more POUs. It can't be removed!"))
def OnRenamePouMenu(self, event):
- selected = self.TypesTree.GetSelection()
- if self.TypesTree.GetPyData(selected) == ITEM_POU:
- wx.CallAfter(self.TypesTree.EditLabel, selected)
+ selected = self.ProjectTree.GetSelection()
+ if self.ProjectTree.GetPyData(selected)["type"] == ITEM_POU:
+ wx.CallAfter(self.ProjectTree.EditLabel, selected)
def OnRemovePouMenu(self, event):
- selected = self.TypesTree.GetSelection()
- if self.TypesTree.GetPyData(selected) == ITEM_POU:
- name = self.TypesTree.GetItemText(selected)
+ selected = self.ProjectTree.GetSelection()
+ if self.ProjectTree.GetPyData(selected)["type"] == ITEM_POU:
+ name = self.ProjectTree.GetItemText(selected)
if not self.Controler.PouIsUsed(name):
self.Controler.ProjectRemovePou(name)
tagname = self.Controler.ComputePouName(name)
idx = self.IsOpened(tagname)
if idx is not None:
self.TabsOpened.DeletePage(idx)
- self._Refresh(TITLE, EDITORTOOLBAR, FILEMENU, EDITMENU, TYPESTREE, INSTANCESTREE, LIBRARYTREE)
+ self._Refresh(TITLE, EDITORTOOLBAR, FILEMENU, EDITMENU, PROJECTTREE, POUINSTANCEVARIABLESPANEL, LIBRARYTREE)
else:
self.ShowErrorMessage(_("\"%s\" is used by one or more POUs. It can't be removed!"))
def OnRemoveTransitionMenu(self, event):
- selected = self.TypesTree.GetSelection()
- if self.TypesTree.GetPyData(selected) == ITEM_TRANSITION:
- transition = self.TypesTree.GetItemText(selected)
- item = self.TypesTree.GetItemParent(selected)
- item_type = self.TypesTree.GetPyData(item)
- while item_type != ITEM_POU:
- item = self.TypesTree.GetItemParent(item)
- item_type = self.TypesTree.GetPyData(item)
- pou_name = self.TypesTree.GetItemText(item)
+ selected = self.ProjectTree.GetSelection()
+ item_infos = self.ProjectTree.GetPyData(selected)
+ if item_infos["type"] == ITEM_TRANSITION:
+ transition = self.ProjectTree.GetItemText(selected)
+ pou_name = item_infos["tagname"].split("::")[1]
self.Controler.ProjectRemovePouTransition(pou_name, transition)
tagname = self.Controler.ComputePouTransitionName(pou_name, transition)
idx = self.IsOpened(tagname)
if idx is not None:
self.TabsOpened.DeletePage(idx)
- self._Refresh(TITLE, FILEMENU, EDITMENU, TYPESTREE)
+ self._Refresh(TITLE, FILEMENU, EDITMENU, PROJECTTREE)
def OnRemoveActionMenu(self, event):
- selected = self.TypesTree.GetSelection()
- if self.TypesTree.GetPyData(selected) == ITEM_ACTION:
- action = self.TypesTree.GetItemText(selected)
- item = self.TypesTree.GetItemParent(selected)
- item_type = self.TypesTree.GetPyData(item)
- while item_type != ITEM_POU:
- item = self.TypesTree.GetItemParent(item)
- item_type = self.TypesTree.GetPyData(item)
- pou_name = self.TypesTree.GetItemText(item)
+ selected = self.ProjectTree.GetSelection()
+ item_infos = self.ProjectTree.GetPyData(selected)
+ if item_infos["type"] == ITEM_ACTION:
+ action = self.ProjectTree.GetItemText(selected)
+ pou_name = item_infos["tagname"].split("::")[1]
self.Controler.ProjectRemovePouAction(pou_name, action)
tagname = self.Controler.ComputePouActionName(pou_name, action)
idx = self.IsOpened(tagname)
if idx is not None:
self.TabsOpened.DeletePage(idx)
- self._Refresh(TITLE, FILEMENU, EDITMENU, TYPESTREE)
+ self._Refresh(TITLE, FILEMENU, EDITMENU, PROJECTTREE)
def OnRemoveConfigurationMenu(self, event):
- selected = self.TypesTree.GetSelection()
- if self.TypesTree.GetPyData(selected) == ITEM_CONFIGURATION:
- name = self.TypesTree.GetItemText(selected)
+ selected = self.ProjectTree.GetSelection()
+ if self.ProjectTree.GetPyData(selected)["type"] == ITEM_CONFIGURATION:
+ name = self.ProjectTree.GetItemText(selected)
self.Controler.ProjectRemoveConfiguration(name)
tagname = self.Controler.ComputeConfigurationName(name)
idx = self.IsOpened(tagname)
if idx is not None:
self.TabsOpened.DeletePage(idx)
- self._Refresh(TITLE, FILEMENU, EDITMENU, TYPESTREE, INSTANCESTREE)
+ self._Refresh(TITLE, FILEMENU, EDITMENU, PROJECTTREE, POUINSTANCEVARIABLESPANEL)
def OnRemoveResourceMenu(self, event):
- selected = self.TypesTree.GetSelection()
- if self.TypesTree.GetPyData(selected) == ITEM_RESOURCE:
- resource = self.TypesTree.GetItemText(selected)
- item = self.TypesTree.GetItemParent(selected)
- item_type = self.TypesTree.GetPyData(item)
- while item_type != ITEM_CONFIGURATION:
- item = self.TypesTree.GetItemParent(item)
- item_type = self.TypesTree.GetPyData(item)
- config_name = self.TypesTree.GetItemText(item)
+ selected = self.ProjectTree.GetSelection()
+ item_infos = self.ProjectTree.GetPyData(selected)
+ if item_infos["type"] == ITEM_RESOURCE:
+ resource = self.ProjectTree.GetItemText(selected)
+ config_name = item_infos["tagname"].split("::")[1]
self.Controler.ProjectRemoveConfigurationResource(config_name, resource)
tagname = self.Controler.ComputeConfigurationResourceName(config_name, selected)
idx = self.IsOpened(tagname)
if idx is not None:
self.TabsOpened.DeletePage(idx)
- self._Refresh(TITLE, FILEMENU, EDITMENU, TYPESTREE, INSTANCESTREE)
+ self._Refresh(TITLE, FILEMENU, EDITMENU, PROJECTTREE, POUINSTANCEVARIABLESPANEL)
def OnPLCOpenEditorMenu(self, event):
wx.MessageBox(_("No documentation available.\nComing soon."))
@@ -2820,11 +2564,11 @@
#-------------------------------------------------------------------------------
def ShowHighlight(self, infos, start, end, highlight_type):
- self.SelectTypesTreeItem(infos[0])
+ self.SelectProjectTreeItem(infos[0])
if infos[1] == "name":
self.Highlights[infos[0]] = highlight_type
- self.RefreshTypesTree()
- self.TypesTree.Unselect()
+ self.RefreshProjectTree()
+ self.ProjectTree.Unselect()
else:
self.EditProjectElement(self.Controler.GetElementType(infos[0]), infos[0])
selected = self.TabsOpened.GetSelection()
@@ -2843,7 +2587,7 @@
self.Highlights = {}
else:
self.Highlights = dict([(name, highlight) for name, highlight in self.Highlights.iteritems() if highlight != highlight_type])
- self.RefreshTypesTree()
+ self.RefreshProjectTree()
for i in xrange(self.TabsOpened.GetPageCount()):
viewer = self.TabsOpened.GetPage(i)
viewer.ClearHighlights(highlight_type)
@@ -2944,11 +2688,14 @@
# Open the filepath if defined
if fileOpen is not None and os.path.isfile(fileOpen):
# Create a new controller
- self.Controler = PLCControler()
- result = self.Controler.OpenXMLFile(fileOpen)
+ controler = PLCControler()
+ result = controler.OpenXMLFile(fileOpen)
if result is None:
- self.LibraryPanel.SetControler(self.Controler)
- self._Refresh(TYPESTREE, INSTANCESTREE, LIBRARYTREE)
+ self.Controler = controler
+ self.LibraryPanel.SetControler(controler)
+ self.ProjectTree.Enable(True)
+ self.PouInstanceVariablesPanel.SetController(controler)
+ self._Refresh(PROJECTTREE, POUINSTANCEVARIABLESPANEL, LIBRARYTREE)
# Define PLCOpenEditor icon
self.SetIcon(wx.Icon(os.path.join(CWD,"Images", "poe.ico"),wx.BITMAP_TYPE_ICO))
@@ -2962,8 +2709,7 @@
def OnCloseFrame(self, event):
if self.Controler is None or self.CheckSaveBeforeClosing(_("Close Application")):
- if USE_AUI:
- self.AUIManager.UnInit()
+ self.AUIManager.UnInit()
self.SaveLastState()
@@ -3038,7 +2784,7 @@
self.Controler = PLCControler()
self.Controler.CreateNewProject(properties)
self.LibraryPanel.SetControler(self.Controler)
- self._Refresh(TITLE, FILEMENU, EDITMENU, TYPESTREE, INSTANCESTREE,
+ self._Refresh(TITLE, FILEMENU, EDITMENU, PROJECTTREE, POUINSTANCEVARIABLESPANEL,
LIBRARYTREE)
def OnOpenProjectMenu(self, event):
@@ -3059,12 +2805,15 @@
filepath = dialog.GetPath()
if os.path.isfile(filepath):
self.ResetView()
- self.Controler = PLCControler()
- result = self.Controler.OpenXMLFile(filepath)
+ controler = PLCControler()
+ result = controler.OpenXMLFile(filepath)
if result is None:
- self.LibraryPanel.SetControler(self.Controler)
+ self.Controler = controler
+ self.LibraryPanel.SetControler(controler)
+ self.ProjectTree.Enable(True)
+ self.PouInstanceVariablesPanel.SetController(controler)
self.LoadProjectOrganization()
- self._Refresh(TYPESTREE, INSTANCESTREE, LIBRARYTREE)
+ self._Refresh(PROJECTTREE, LIBRARYTREE)
self._Refresh(TITLE, EDITORTOOLBAR, FILEMENU, EDITMENU)
dialog.Destroy()
diff -r 188906a7368c -r ce605c1a6d04 RessourceEditor.py
--- a/RessourceEditor.py Tue May 15 05:19:13 2012 +0900
+++ b/RessourceEditor.py Mon May 21 10:02:54 2012 +0200
@@ -502,7 +502,7 @@
def OnInstancesGridCellChange(self, event):
self.RefreshModel()
- self.ParentWindow.RefreshInstancesTree()
+ self.ParentWindow.RefreshPouInstanceVariablesPanel()
self.InstancesGrid.RefreshButtons()
event.Skip()
diff -r 188906a7368c -r ce605c1a6d04 TextViewer.py
--- a/TextViewer.py Tue May 15 05:19:13 2012 +0900
+++ b/TextViewer.py Mon May 21 10:02:54 2012 +0200
@@ -247,7 +247,8 @@
return {"cursor_pos": self.Editor.GetCurrentPos()}
def SetState(self, state):
- self.Editor.GotoPos(state["cursor_pos"])
+ if self:
+ self.Editor.GotoPos(state.get("cursor_pos", 0))
def OnModification(self, event):
if not self.DisableEvents:
diff -r 188906a7368c -r ce605c1a6d04 Viewer.py
--- a/Viewer.py Tue May 15 05:19:13 2012 +0900
+++ b/Viewer.py Mon May 21 10:02:54 2012 +0200
@@ -691,9 +691,10 @@
"zoom": self.CurrentScale}
def SetState(self, state):
- self.SetScale(state["zoom"])
- self.Scroll(*state["position"])
- self.RefreshVisibleElements()
+ if self:
+ self.SetScale(state["zoom"])
+ self.Scroll(*state["position"])
+ self.RefreshVisibleElements()
def GetLogicalDC(self, buffered=False):
if buffered:
@@ -1966,7 +1967,7 @@
self.RefreshScrollBars()
self.RefreshVisibleElements()
self.RefreshVariablePanel()
- self.ParentWindow.RefreshInstancesTree()
+ self.ParentWindow.RefreshPouInstanceVariablesPanel()
block.Refresh()
dialog.Destroy()
@@ -2277,7 +2278,7 @@
self.RefreshScrollBars()
self.RefreshVisibleElements()
self.RefreshVariablePanel()
- self.ParentWindow.RefreshInstancesTree()
+ self.ParentWindow.RefreshPouInstanceVariablesPanel()
if old_values["executionOrder"] != new_values["executionOrder"]:
self.RefreshView()
else:
@@ -2690,7 +2691,7 @@
for element in elements:
element.RefreshModel()
wx.CallAfter(self.RefreshVariablePanel)
- wx.CallAfter(self.ParentWindow.RefreshInstancesTree)
+ wx.CallAfter(self.ParentWindow.RefreshPouInstanceVariablesPanel)
def DeleteVariable(self, variable):
connectors = variable.GetConnectors()
@@ -2828,7 +2829,7 @@
self.RefreshBuffer()
self.RefreshScrollBars()
self.RefreshVariablePanel()
- self.ParentWindow.RefreshInstancesTree()
+ self.ParentWindow.RefreshPouInstanceVariablesPanel()
self.RefreshRect(self.GetScrolledRect(rect), False)
def Copy(self):
@@ -2856,7 +2857,7 @@
self.RefreshBuffer()
self.RefreshView(selection=result)
self.RefreshVariablePanel()
- self.ParentWindow.RefreshInstancesTree()
+ self.ParentWindow.RefreshPouInstanceVariablesPanel()
else:
message = wx.MessageDialog(self.Editor, result, "Error", wx.OK|wx.ICON_ERROR)
message.ShowModal()
diff -r 188906a7368c -r ce605c1a6d04 controls/CustomTable.py
--- a/controls/CustomTable.py Tue May 15 05:19:13 2012 +0900
+++ b/controls/CustomTable.py Mon May 21 10:02:54 2012 +0200
@@ -1,3 +1,6 @@
+#!/usr/bin/env python
+# -*- coding: utf-8 -*-
+
#This library is free software; you can redistribute it and/or
#modify it under the terms of the GNU General Public
#License as published by the Free Software Foundation; either
diff -r 188906a7368c -r ce605c1a6d04 controls/CustomTree.py
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/controls/CustomTree.py Mon May 21 10:02:54 2012 +0200
@@ -0,0 +1,105 @@
+#!/usr/bin/env python
+# -*- coding: utf-8 -*-
+
+#This library is free software; you can redistribute it and/or
+#modify it under the terms of the GNU General Public
+#License as published by the Free Software Foundation; either
+#version 2.1 of the License, or (at your option) any later version.
+#
+#This library is distributed in the hope that it will be useful,
+#but WITHOUT ANY WARRANTY; without even the implied warranty of
+#MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+#General Public License for more details.
+#
+#You should have received a copy of the GNU General Public
+#License along with this library; if not, write to the Free Software
+#Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+
+import wx
+
+class CustomTree(wx.TreeCtrl):
+
+ def __init__(self, *args, **kwargs):
+ wx.TreeCtrl.__init__(self, *args, **kwargs)
+ self.SetBackgroundStyle(wx.BG_STYLE_CUSTOM)
+
+ self.BackgroundBitmap = None
+ self.BackgroundAlign = wx.ALIGN_LEFT|wx.ALIGN_TOP
+
+ self.AddMenu = None
+ self.Enabled = False
+
+ if wx.Platform == '__WXMSW__':
+ self.Bind(wx.EVT_ERASE_BACKGROUND, self.OnEraseBackground)
+ else:
+ self.Bind(wx.EVT_PAINT, self.OnPaint)
+ self.Bind(wx.EVT_SIZE, self.OnResize)
+ self.Bind(wx.EVT_SCROLL, self.OnScroll)
+ self.Bind(wx.EVT_LEFT_UP, self.OnLeftUp)
+
+ def SetBackgroundBitmap(self, bitmap, align):
+ self.BackgroundBitmap = bitmap
+ self.BackgroundAlign = align
+
+ def SetAddMenu(self, add_menu):
+ self.AddMenu = add_menu
+
+ def Enable(self, enabled):
+ self.Enabled = enabled
+
+ def GetBitmapRect(self):
+ client_size = self.GetClientSize()
+ bitmap_size = self.BackgroundBitmap.GetSize()
+
+ if self.BackgroundAlign & wx.ALIGN_RIGHT:
+ x = client_size[0] - bitmap_size[0]
+ elif self.BackgroundAlign & wx.ALIGN_CENTER_HORIZONTAL:
+ x = (client_size[0] - bitmap_size[0]) / 2
+ else:
+ x = 0
+
+ if self.BackgroundAlign & wx.ALIGN_BOTTOM:
+ y = client_size[1] - bitmap_size[1]
+ elif self.BackgroundAlign & wx.ALIGN_CENTER_VERTICAL:
+ y = (client_size[1] - bitmap_size[1]) / 2
+ else:
+ y = 0
+
+ return wx.Rect(x, y, bitmap_size[0], bitmap_size[1])
+
+ def RefreshBackground(self, refresh_base=False):
+ dc = wx.ClientDC(self)
+ dc.Clear()
+
+ bitmap_rect = self.GetBitmapRect()
+ dc.DrawBitmap(self.BackgroundBitmap, bitmap_rect.x, bitmap_rect.y)
+
+ if refresh_base:
+ self.Refresh(False)
+
+ def OnEraseBackground(self, event):
+ self.RefreshBackground(True)
+
+ def OnLeftUp(self, event):
+ if self.Enabled:
+ pos = event.GetPosition()
+ item, flags = self.HitTest(pos)
+
+ bitmap_rect = self.GetBitmapRect()
+ if (bitmap_rect.InsideXY(pos.x, pos.y) or
+ flags & wx.TREE_HITTEST_NOWHERE) and self.AddMenu is not None:
+ self.PopupMenuXY(self.AddMenu, pos.x, pos.y)
+ event.Skip()
+
+ def OnScroll(self, event):
+ print "scroll event"
+ self.RefreshBackground(True)
+ event.Skip()
+
+ def OnResize(self, event):
+ self.RefreshBackground(True)
+ event.Skip()
+
+ def OnPaint(self, event):
+ self.RefreshBackground()
+ event.Skip()
\ No newline at end of file
diff -r 188906a7368c -r ce605c1a6d04 controls/EditorPanel.py
--- a/controls/EditorPanel.py Tue May 15 05:19:13 2012 +0900
+++ b/controls/EditorPanel.py Mon May 21 10:02:54 2012 +0200
@@ -65,7 +65,7 @@
elif self.VariableEditor is not None:
self.Initialize(self.VariableEditor)
elif self.Editor is not None:
- self.Initialize(self.Editor)
+ self.Initialize(self.Editor)
def __init__(self, parent, tagname, window, controler, debug=False):
self.ParentWindow = window
@@ -137,10 +137,10 @@
if self.VariableEditor is not None:
self.VariableEditor.RefreshView()
- def GetPluginMenuItems(self):
+ def GetConfNodeMenuItems(self):
return self.MenuItems
- def RefreshPluginMenu(self, plugin_menu):
+ def RefreshConfNodeMenu(self, confnode_menu):
pass
def _Refresh(self, *args):
diff -r 188906a7368c -r ce605c1a6d04 controls/PouInstanceVariablesPanel.py
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/controls/PouInstanceVariablesPanel.py Mon May 21 10:02:54 2012 +0200
@@ -0,0 +1,318 @@
+#!/usr/bin/env python
+# -*- coding: utf-8 -*-
+
+#This file is part of PLCOpenEditor, a library implementing an IEC 61131-3 editor
+#based on the plcopen standard.
+#
+#Copyright (C) 2012: Edouard TISSERANT and Laurent BESSARD
+#
+#See COPYING file for copyrights details.
+#
+#This library is free software; you can redistribute it and/or
+#modify it under the terms of the GNU General Public
+#License as published by the Free Software Foundation; either
+#version 2.1 of the License, or (at your option) any later version.
+#
+#This library is distributed in the hope that it will be useful,
+#but WITHOUT ANY WARRANTY; without even the implied warranty of
+#MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+#General Public License for more details.
+#
+#You should have received a copy of the GNU General Public
+#License along with this library; if not, write to the Free Software
+#Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+
+import wx
+import wx.lib.buttons
+import wx.lib.agw.customtreectrl as CT
+
+from PLCControler import ITEMS_VARIABLE, ITEM_CONFIGURATION, ITEM_RESOURCE, ITEM_POU
+
+class PouInstanceVariablesPanel(wx.Panel):
+
+ def __init__(self, parent, window, controller, debug):
+ wx.Panel.__init__(self, name='PouInstanceTreePanel',
+ parent=parent, pos=wx.Point(0, 0),
+ size=wx.Size(0, 0), style=wx.TAB_TRAVERSAL)
+
+ self.ParentButton = wx.lib.buttons.GenBitmapButton(
+ name='ParentButton', parent=self,
+ bitmap=window.GenerateBitmap("up"),
+ pos=wx.Point(0, 0), size=wx.Size(28, 28),
+ style=wx.NO_BORDER)
+ self.Bind(wx.EVT_BUTTON, self.OnParentButtonClick,
+ self.ParentButton)
+
+ self.InstanceChoice = wx.ComboBox(name='InstanceChoice',
+ parent=self, pos=wx.Point(0, 0),
+ size=wx.Size(0, 28), style=wx.CB_READONLY)
+ self.Bind(wx.EVT_COMBOBOX, self.OnInstanceChoiceChanged,
+ self.InstanceChoice)
+ self.InstanceChoice.Bind(wx.EVT_LEFT_DOWN, self.OnInstanceChoiceLeftDown)
+
+ self.DebugButton = wx.lib.buttons.GenBitmapButton(
+ name='DebugButton', parent=self,
+ bitmap=window.GenerateBitmap("debug"),
+ pos=wx.Point(0, 0), size=wx.Size(28, 28),
+ style=wx.NO_BORDER)
+ self.Bind(wx.EVT_BUTTON, self.OnDebugButtonClick,
+ self.DebugButton)
+
+ self.VariablesList = CT.CustomTreeCtrl(
+ name='VariablesList', parent=self,
+ pos=wx.Point(0, 0), size=wx.Size(0, 0),
+ style=wx.SUNKEN_BORDER,
+ agwStyle=CT.TR_NO_BUTTONS|
+ CT.TR_SINGLE|
+ CT.TR_HAS_VARIABLE_ROW_HEIGHT|
+ CT.TR_HIDE_ROOT|
+ CT.TR_NO_LINES|
+ getattr(CT, "TR_ALIGN_WINDOWS_RIGHT", CT.TR_ALIGN_WINDOWS))
+ self.VariablesList.SetIndent(0)
+ self.VariablesList.SetSpacing(5)
+ self.VariablesList.DoSelectItem = lambda *x,**y:True
+ self.VariablesList.Bind(CT.EVT_TREE_ITEM_ACTIVATED,
+ self.OnVariablesListItemActivated)
+ self.VariablesList.Bind(wx.EVT_LEFT_DOWN, self.OnVariablesListLeftDown)
+
+ buttons_sizer = wx.FlexGridSizer(cols=3, hgap=0, rows=1, vgap=0)
+ buttons_sizer.AddWindow(self.ParentButton, 0, border=0, flag=0)
+ buttons_sizer.AddWindow(self.InstanceChoice, 0, border=0, flag=wx.GROW)
+ buttons_sizer.AddWindow(self.DebugButton, 0, border=0, flag=0)
+ buttons_sizer.AddGrowableCol(1)
+ buttons_sizer.AddGrowableRow(0)
+
+ main_sizer = wx.FlexGridSizer(cols=1, hgap=0, rows=2, vgap=0)
+ main_sizer.AddSizer(buttons_sizer, 0, border=0, flag=wx.GROW)
+ main_sizer.AddWindow(self.VariablesList, 0, border=0, flag=wx.GROW)
+ main_sizer.AddGrowableCol(0)
+ main_sizer.AddGrowableRow(1)
+
+ self.SetSizer(main_sizer)
+
+ self.ParentWindow = window
+ self.Controller = controller
+ self.Debug = debug
+ if not self.Debug:
+ self.DebugButton.Hide()
+
+ self.PouTagName = None
+ self.PouInfos = None
+ self.PouInstance = None
+
+ def __del__(self):
+ self.Controller = None
+
+ def SetTreeImageList(self, tree_image_list):
+ self.VariablesList.SetImageList(tree_image_list)
+
+ def SetController(self, controller):
+ self.Controller = controller
+
+ self.RefreshView()
+
+ def SetPouType(self, tagname, pou_instance=None):
+ self.PouTagName = tagname
+ if pou_instance is not None:
+ self.PouInstance = pou_instance
+
+ self.RefreshView()
+
+ def ResetView(self):
+ self.Controller = None
+
+ self.PouTagName = None
+ self.PouInfos = None
+ self.PouInstance = None
+
+ self.RefreshView()
+
+ def RefreshView(self):
+ self.VariablesList.DeleteAllItems()
+ self.InstanceChoice.Clear()
+ self.InstanceChoice.SetValue("")
+
+ if self.PouTagName is not None:
+ self.PouInfos = self.Controller.GetPouVariables(self.PouTagName, self.Debug)
+ else:
+ self.PouInfos = None
+ if self.PouInfos is not None:
+ root = self.VariablesList.AddRoot("")
+ for var_infos in self.PouInfos["variables"]:
+ if var_infos.get("type", None) is not None:
+ text = "%(name)s (%(type)s)" % var_infos
+ else:
+ text = var_infos["name"]
+
+ panel = wx.Panel(self.VariablesList)
+
+ buttons = []
+ if var_infos["class"] in ITEMS_VARIABLE:
+ if (var_infos["debug"] and self.Debug and
+ (self.Controller.IsOfType(var_infos["type"], "ANY_NUM", True) or
+ self.Controller.IsOfType(var_infos["type"], "ANY_BIT", True))):
+ graph_button = wx.lib.buttons.GenBitmapButton(name="graph",
+ parent=panel, bitmap=self.ParentWindow.GenerateBitmap("graph"),
+ pos=wx.Point(0, 0), size=wx.Size(28, 28), style=wx.NO_BORDER)
+ self.Bind(wx.EVT_BUTTON, self.GenGraphButtonCallback(var_infos), graph_button)
+ buttons.append(graph_button)
+ elif var_infos["edit"]:
+ edit_button = wx.lib.buttons.GenBitmapButton(name="edit",
+ parent=panel, bitmap=self.ParentWindow.GenerateBitmap("edit"),
+ pos=wx.Point(0, 0), size=wx.Size(28, 28), style=wx.NO_BORDER)
+ self.Bind(wx.EVT_BUTTON, self.GenEditButtonCallback(var_infos), edit_button)
+ buttons.append(edit_button)
+
+ if var_infos["debug"] and self.Debug:
+ debug_button = wx.lib.buttons.GenBitmapButton(name="debug",
+ parent=panel, bitmap=self.ParentWindow.GenerateBitmap("debug"),
+ pos=wx.Point(0, 0), size=wx.Size(28, 28), style=wx.NO_BORDER)
+ self.Bind(wx.EVT_BUTTON, self.GenDebugButtonCallback(var_infos), debug_button)
+ buttons.append(debug_button)
+
+ button_num = len(buttons)
+ if button_num > 0:
+ panel.SetSize(wx.Size(button_num * 32, 28))
+ panel.SetBackgroundColour(self.VariablesList.GetBackgroundColour())
+ panel_sizer = wx.BoxSizer(wx.HORIZONTAL)
+ panel.SetSizer(panel_sizer)
+
+ for button in buttons:
+ panel_sizer.AddWindow(button, 0, border=4, flag=wx.LEFT)
+ else:
+ panel.Destroy()
+ panel = None
+
+ item = self.VariablesList.AppendItem(root, text, wnd=panel)
+ self.VariablesList.SetItemImage(item, self.ParentWindow.GetTreeImage(var_infos["class"]))
+ self.VariablesList.SetPyData(item, var_infos)
+
+ instances = self.Controller.SearchPouInstances(self.PouTagName, self.Debug)
+ for instance in instances:
+ self.InstanceChoice.Append(instance)
+ if len(instances) == 1:
+ self.PouInstance = instances[0]
+ if self.PouInfos["class"] in [ITEM_CONFIGURATION, ITEM_RESOURCE]:
+ self.PouInstance = None
+ self.InstanceChoice.SetSelection(0)
+ elif self.PouInstance in instances:
+ self.InstanceChoice.SetStringSelection(self.PouInstance)
+ else:
+ self.PouInstance = None
+ self.InstanceChoice.SetValue(_("Select an instance"))
+
+ self.RefreshButtons()
+
+ def RefreshButtons(self):
+ enabled = self.InstanceChoice.GetSelection() != -1
+ self.ParentButton.Enable(enabled and self.PouInfos["class"] != ITEM_CONFIGURATION)
+ self.DebugButton.Enable(enabled and self.PouInfos["debug"] and self.Debug)
+
+ root = self.VariablesList.GetRootItem()
+ if root is not None and root.IsOk():
+ item, item_cookie = self.VariablesList.GetFirstChild(root)
+ while item is not None and item.IsOk():
+ panel = self.VariablesList.GetItemWindow(item)
+ if panel is not None:
+ for child in panel.GetChildren():
+ if child.GetName() != "edit":
+ child.Enable(enabled)
+ item, item_cookie = self.VariablesList.GetNextChild(root, item_cookie)
+
+ def GenEditButtonCallback(self, infos):
+ def EditButtonCallback(event):
+ var_class = infos["class"]
+ if var_class == ITEM_RESOURCE:
+ tagname = self.Controller.ComputeConfigurationResourceName(
+ self.InstanceChoice.GetStringSelection(),
+ infos["name"])
+ else:
+ var_class = ITEM_POU
+ tagname = self.Controller.ComputePouName(infos["type"])
+ self.ParentWindow.EditProjectElement(var_class, tagname)
+ event.Skip()
+ return EditButtonCallback
+
+ def GenDebugButtonCallback(self, infos):
+ def DebugButtonCallback(event):
+ if self.InstanceChoice.GetSelection() != -1:
+ var_class = infos["class"]
+ var_path = "%s.%s" % (self.InstanceChoice.GetStringSelection(),
+ infos["name"])
+ if var_class in ITEMS_VARIABLE:
+ self.ParentWindow.AddDebugVariable(var_path, force=True)
+ else:
+ self.ParentWindow.OpenDebugViewer(
+ infos["class"],
+ var_path,
+ self.Controller.ComputePouName(infos["type"]))
+ event.Skip()
+ return DebugButtonCallback
+
+ def GenGraphButtonCallback(self, infos):
+ def GraphButtonCallback(event):
+ if self.InstanceChoice.GetSelection() != -1:
+ if infos["class"] in ITEMS_VARIABLE:
+ var_path = "%s.%s" % (self.InstanceChoice.GetStringSelection(),
+ infos["name"])
+ self.ParentWindow.OpenGraphicViewer(var_path)
+ event.Skip()
+ return GraphButtonCallback
+
+ def ShowInstanceChoicePopup(self):
+ self.InstanceChoice.SetFocusFromKbd()
+ size = self.InstanceChoice.GetSize()
+ event = wx.MouseEvent(wx.EVT_LEFT_DOWN._getEvtType())
+ event.m_x = size.width / 2
+ event.m_y = size.height / 2
+ event.SetEventObject(self.InstanceChoice)
+ #event = wx.KeyEvent(wx.EVT_KEY_DOWN._getEvtType())
+ #event.m_keyCode = wx.WXK_SPACE
+ self.InstanceChoice.GetEventHandler().ProcessEvent(event)
+
+ def OnParentButtonClick(self, event):
+ if self.InstanceChoice.GetSelection() != -1:
+ parent_path = self.InstanceChoice.GetStringSelection().rsplit(".", 1)[0]
+ tagname = self.Controller.GetPouInstanceTagName(parent_path, self.Debug)
+ if tagname is not None:
+ wx.CallAfter(self.SetPouType, tagname, parent_path)
+ wx.CallAfter(self.ParentWindow.SelectProjectTreeItem, tagname)
+ event.Skip()
+
+ def OnInstanceChoiceChanged(self, event):
+ self.RefreshButtons()
+ event.Skip()
+
+ def OnDebugButtonClick(self, event):
+ if self.InstanceChoice.GetSelection() != -1:
+ self.ParentWindow.OpenDebugViewer(
+ self.PouInfos["class"],
+ self.InstanceChoice.GetStringSelection(),
+ self.PouTagName)
+ event.Skip()
+
+ def OnVariablesListItemActivated(self, event):
+ if self.InstanceChoice.GetSelection() != -1:
+ instance_path = self.InstanceChoice.GetStringSelection()
+ selected_item = event.GetItem()
+ if selected_item is not None and selected_item.IsOk():
+ item_infos = self.VariablesList.GetPyData(selected_item)
+ if item_infos is not None and item_infos["class"] not in ITEMS_VARIABLE:
+ if item_infos["class"] == ITEM_RESOURCE:
+ tagname = self.Controller.ComputeConfigurationResourceName(
+ instance_path,
+ item_infos["name"])
+ else:
+ tagname = self.Controller.ComputePouName(item_infos["type"])
+ item_path = "%s.%s" % (instance_path, item_infos["name"])
+ wx.CallAfter(self.SetPouType, tagname, item_path)
+ wx.CallAfter(self.ParentWindow.SelectProjectTreeItem, tagname)
+ event.Skip()
+
+ def OnVariablesListLeftDown(self, event):
+ if self.InstanceChoice.GetSelection() == -1:
+ wx.CallAfter(self.ShowInstanceChoicePopup)
+ event.Skip()
+
+ def OnInstanceChoiceLeftDown(self, event):
+ event.Skip()
diff -r 188906a7368c -r ce605c1a6d04 controls/VariablePanel.py
--- a/controls/VariablePanel.py Tue May 15 05:19:13 2012 +0900
+++ b/controls/VariablePanel.py Mon May 21 10:02:54 2012 +0200
@@ -43,7 +43,7 @@
parent.Append(helpString=help, id=id, kind=kind, item=text)
[TITLE, TOOLBAR, FILEMENU, EDITMENU, DISPLAYMENU, TYPESTREE,
- INSTANCESTREE, LIBRARYTREE, SCALING
+ POUINSTANCEVARIABLESPANEL, LIBRARYTREE, SCALING
] = range(9)
#-------------------------------------------------------------------------------
@@ -644,7 +644,7 @@
self.Controler.SetPouInterfaceReturnType(words[1], self.ReturnType.GetStringSelection())
self.Controler.BufferProject()
self.ParentWindow.RefreshView(variablepanel = False)
- self.ParentWindow._Refresh(TITLE, FILEMENU, EDITMENU, INSTANCESTREE, LIBRARYTREE)
+ self.ParentWindow._Refresh(TITLE, FILEMENU, EDITMENU, POUINSTANCEVARIABLESPANEL, LIBRARYTREE)
event.Skip()
def OnDescriptionChanged(self, event):
@@ -653,7 +653,7 @@
new_description = self.Description.GetValue()
if new_description != old_description:
self.Controler.SetPouDescription(words[1], new_description)
- self.ParentWindow._Refresh(TITLE, FILEMENU, EDITMENU, INSTANCESTREE, LIBRARYTREE)
+ self.ParentWindow._Refresh(TITLE, FILEMENU, EDITMENU, POUINSTANCEVARIABLESPANEL, LIBRARYTREE)
event.Skip()
def OnClassFilter(self, event):
@@ -695,7 +695,7 @@
self.Controler.UpdateEditedElementUsedVariable(self.TagName, old_value, value)
self.Controler.BufferProject()
self.ParentWindow.RefreshView(variablepanel = False)
- self.ParentWindow._Refresh(TITLE, FILEMENU, EDITMENU, INSTANCESTREE, LIBRARYTREE)
+ self.ParentWindow._Refresh(TITLE, FILEMENU, EDITMENU, POUINSTANCEVARIABLESPANEL, LIBRARYTREE)
event.Skip()
else:
self.SaveValues()
@@ -738,17 +738,17 @@
type_menu.AppendMenu(wx.NewId(), _("User Data Types"), datatype_menu)
- for category in self.Controler.GetPluginDataTypes():
+ for category in self.Controler.GetConfNodeDataTypes():
if len(category["list"]) > 0:
- # build a submenu containing plugin types
- plugin_datatype_menu = wx.Menu(title='')
+ # build a submenu containing confnode types
+ confnode_datatype_menu = wx.Menu(title='')
for datatype in category["list"]:
new_id = wx.NewId()
- AppendMenu(plugin_datatype_menu, help='', id=new_id, kind=wx.ITEM_NORMAL, text=datatype)
+ AppendMenu(confnode_datatype_menu, help='', id=new_id, kind=wx.ITEM_NORMAL, text=datatype)
self.Bind(wx.EVT_MENU, self.GetVariableTypeFunction(datatype), id=new_id)
- type_menu.AppendMenu(wx.NewId(), category["name"], plugin_datatype_menu)
+ type_menu.AppendMenu(wx.NewId(), category["name"], confnode_datatype_menu)
# build a submenu containing function block types
bodytype = self.Controler.GetEditedElementBodyType(self.TagName)
@@ -789,7 +789,7 @@
self.SaveValues(False)
self.ParentWindow.RefreshView(variablepanel = False)
self.Controler.BufferProject()
- self.ParentWindow._Refresh(TITLE, FILEMENU, EDITMENU, INSTANCESTREE, LIBRARYTREE)
+ self.ParentWindow._Refresh(TITLE, FILEMENU, EDITMENU, POUINSTANCEVARIABLESPANEL, LIBRARYTREE)
return VariableTypeFunction
def VariableArrayTypeFunction(self, event):
@@ -803,7 +803,7 @@
self.SaveValues(False)
self.ParentWindow.RefreshView(variablepanel = False)
self.Controler.BufferProject()
- self.ParentWindow._Refresh(TITLE, FILEMENU, EDITMENU, INSTANCESTREE, LIBRARYTREE)
+ self.ParentWindow._Refresh(TITLE, FILEMENU, EDITMENU, POUINSTANCEVARIABLESPANEL, LIBRARYTREE)
dialog.Destroy()
def OnVariablesGridCellLeftClick(self, event):
@@ -840,7 +840,7 @@
self.Controler.SetPouInterfaceVars(words[1], self.Values)
if buffer:
self.Controler.BufferProject()
- self.ParentWindow._Refresh(TITLE, FILEMENU, EDITMENU, INSTANCESTREE, LIBRARYTREE)
+ self.ParentWindow._Refresh(TITLE, FILEMENU, EDITMENU, POUINSTANCEVARIABLESPANEL, LIBRARYTREE)
#-------------------------------------------------------------------------------
# Highlights showing functions
diff -r 188906a7368c -r ce605c1a6d04 controls/__init__.py
--- a/controls/__init__.py Tue May 15 05:19:13 2012 +0900
+++ b/controls/__init__.py Mon May 21 10:02:54 2012 +0200
@@ -32,3 +32,5 @@
from LocationCellEditor import LocationCellEditor
from VariablePanel import VariablePanel
from LibraryPanel import LibraryPanel
+from PouInstanceVariablesPanel import PouInstanceVariablesPanel
+from CustomTree import CustomTree
diff -r 188906a7368c -r ce605c1a6d04 dialogs/BrowseLocationsDialog.py
--- a/dialogs/BrowseLocationsDialog.py Tue May 15 05:19:13 2012 +0900
+++ b/dialogs/BrowseLocationsDialog.py Mon May 21 10:02:54 2012 +0200
@@ -22,7 +22,7 @@
import wx
from plcopen.structures import LOCATIONDATATYPES
-from PLCControler import LOCATION_PLUGIN, LOCATION_MODULE, LOCATION_GROUP, LOCATION_VAR_INPUT, LOCATION_VAR_OUTPUT, LOCATION_VAR_MEMORY
+from PLCControler import LOCATION_CONFNODE, LOCATION_MODULE, LOCATION_GROUP, LOCATION_VAR_INPUT, LOCATION_VAR_OUTPUT, LOCATION_VAR_MEMORY
CWD = os.path.split(os.path.split(os.path.realpath(__file__))[0])[0]
@@ -131,7 +131,7 @@
# Icons for items
for imgname, itemtype in [
- ("CONFIGURATION", LOCATION_PLUGIN),
+ ("CONFIGURATION", LOCATION_CONFNODE),
("RESOURCE", LOCATION_MODULE),
("PROGRAM", LOCATION_GROUP),
("VAR_INPUT", LOCATION_VAR_INPUT),
@@ -157,7 +157,7 @@
root = self.LocationsTree.GetRootItem()
if not root.IsOk():
if wx.Platform == '__WXMSW__':
- root = self.LocationsTree.AddRoot(_('Plugins'))
+ root = self.LocationsTree.AddRoot(_('ConfNodes'))
else:
root = self.LocationsTree.AddRoot("")
self.GenerateLocationsTreeBranch(root, self.Locations)
@@ -171,7 +171,7 @@
item, root_cookie = self.LocationsTree.GetFirstChild(root, 0)
for loc_infos in locations:
infos = loc_infos.copy()
- if infos["type"] in [LOCATION_PLUGIN, LOCATION_MODULE, LOCATION_GROUP] or\
+ if infos["type"] in [LOCATION_CONFNODE, LOCATION_MODULE, LOCATION_GROUP] or\
infos["type"] in self.Filter and (infos["IEC_type"] == self.VarType or
infos["IEC_type"] is None and LOCATION_SIZES[self.VarType] == infos["size"]):
children = [child for child in infos.pop("children")]
@@ -193,7 +193,7 @@
def OnLocationsTreeItemActivated(self, event):
infos = self.LocationsTree.GetPyData(event.GetItem())
- if infos["type"] not in [LOCATION_PLUGIN, LOCATION_MODULE, LOCATION_GROUP]:
+ if infos["type"] not in [LOCATION_CONFNODE, LOCATION_MODULE, LOCATION_GROUP]:
wx.CallAfter(self.EndModal, wx.ID_OK)
event.Skip()
@@ -210,7 +210,7 @@
var_infos = None
if selected.IsOk():
var_infos = self.LocationsTree.GetPyData(selected)
- if var_infos is None or var_infos["type"] in [LOCATION_PLUGIN, LOCATION_MODULE, LOCATION_GROUP]:
+ if var_infos is None or var_infos["type"] in [LOCATION_CONFNODE, LOCATION_MODULE, LOCATION_GROUP]:
message = wx.MessageDialog(self, _("A location must be selected!"), _("Error"), wx.OK|wx.ICON_ERROR)
message.ShowModal()
message.Destroy()
diff -r 188906a7368c -r ce605c1a6d04 docutil/__init__.py
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/docutil/__init__.py Mon May 21 10:02:54 2012 +0200
@@ -0,0 +1,27 @@
+#!/usr/bin/env python
+# -*- coding: utf-8 -*-
+
+#This file is part of PLCOpenEditor, a library implementing an IEC 61131-3 editor
+#based on the plcopen standard.
+#
+#Copyright (C) 2007: Edouard TISSERANT and Laurent BESSARD
+#
+#See COPYING file for copyrights details.
+#
+#This library is free software; you can redistribute it and/or
+#modify it under the terms of the GNU General Public
+#License as published by the Free Software Foundation; either
+#version 2.1 of the License, or (at your option) any later version.
+#
+#This library is distributed in the hope that it will be useful,
+#but WITHOUT ANY WARRANTY; without even the implied warranty of
+#MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+#General Public License for more details.
+#
+#You should have received a copy of the GNU General Public
+#License along with this library; if not, write to the Free Software
+#Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+
+from dochtml import *
+from docpdf import *
+from docsvg import *
\ No newline at end of file
diff -r 188906a7368c -r ce605c1a6d04 docutil/dochtml.py
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/docutil/dochtml.py Mon May 21 10:02:54 2012 +0200
@@ -0,0 +1,96 @@
+#!/usr/bin/env python
+# -*- coding: utf-8 -*-
+
+#This file is part of PLCOpenEditor, a library implementing an IEC 61131-3 editor
+#based on the plcopen standard.
+#
+#Copyright (C) 2007: Edouard TISSERANT and Laurent BESSARD
+#
+#See COPYING file for copyrights details.
+#
+#This library is free software; you can redistribute it and/or
+#modify it under the terms of the GNU General Public
+#License as published by the Free Software Foundation; either
+#version 2.1 of the License, or (at your option) any later version.
+#
+#This library is distributed in the hope that it will be useful,
+#but WITHOUT ANY WARRANTY; without even the implied warranty of
+#MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+#General Public License for more details.
+#
+#You should have received a copy of the GNU General Public
+#License along with this library; if not, write to the Free Software
+#Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+
+import wx, os, wx.html, subprocess
+
+HtmlFrameOpened = []
+
+def OpenHtmlFrame(self, title, file, size):
+ if title not in HtmlFrameOpened:
+ HtmlFrameOpened.append(title)
+ window = HtmlFrame(self, HtmlFrameOpened)
+ window.SetTitle(title)
+ window.SetHtmlPage(file)
+ window.SetClientSize(size)
+ window.Show()
+
+[ID_HTMLFRAME, ID_HTMLFRAMEHTMLCONTENT] = [wx.NewId() for _init_ctrls in range(2)]
+EVT_HTML_URL_CLICK = wx.NewId()
+
+class HtmlWindowUrlClick(wx.PyEvent):
+ def __init__(self, linkinfo):
+ wx.PyEvent.__init__(self)
+ self.SetEventType(EVT_HTML_URL_CLICK)
+ self.linkinfo = (linkinfo.GetHref(), linkinfo.GetTarget())
+
+class UrlClickHtmlWindow(wx.html.HtmlWindow):
+ """ HTML window that generates and OnLinkClicked event.
+
+ Use this to avoid having to override HTMLWindow
+ """
+ def OnLinkClicked(self, linkinfo):
+ wx.PostEvent(self, HtmlWindowUrlClick(linkinfo))
+
+ def Bind(self, event, handler, source=None, id=wx.ID_ANY, id2=wx.ID_ANY):
+ if event == HtmlWindowUrlClick:
+ self.Connect(-1, -1, EVT_HTML_URL_CLICK, handler)
+ else:
+ wx.html.HtmlWindow.Bind(event, handler, source=source, id=id, id2=id2)
+
+class HtmlFrame(wx.Frame):
+ def _init_ctrls(self, prnt):
+ wx.Frame.__init__(self, id=ID_HTMLFRAME, name='HtmlFrame',
+ parent=prnt, pos=wx.Point(320, 231), size=wx.Size(853, 616),
+ style=wx.DEFAULT_FRAME_STYLE, title='')
+ self.Bind(wx.EVT_CLOSE, self.OnCloseFrame)
+
+ self.HtmlContent = UrlClickHtmlWindow(id=ID_HTMLFRAMEHTMLCONTENT,
+ name='HtmlContent', parent=self, pos=wx.Point(0, 0),
+ size=wx.Size(-1, -1), style=wx.html.HW_SCROLLBAR_AUTO|wx.html.HW_NO_SELECTION)
+ self.HtmlContent.Bind(HtmlWindowUrlClick, self.OnLinkClick)
+
+ def __init__(self, parent, opened):
+ self._init_ctrls(parent)
+ self.HtmlFrameOpened = opened
+
+ def SetHtmlCode(self, htmlcode):
+ self.HtmlContent.SetPage(htmlcode)
+
+ def SetHtmlPage(self, htmlpage):
+ self.HtmlContent.LoadPage(htmlpage)
+
+ def OnCloseFrame(self, event):
+ self.HtmlFrameOpened.remove(self.GetTitle())
+ event.Skip()
+
+ def OnLinkClick(self, event):
+ url = event.linkinfo[0]
+ try:
+ if wx.Platform == '__WXMSW__':
+ import webbrowser
+ webbrowser.open(url)
+ elif subprocess.call("firefox %s"%url, shell=True) != 0:
+ wx.MessageBox("""Firefox browser not found.\nPlease point your browser at :\n%s""" % url)
+ except ImportError:
+ wx.MessageBox('Please point your browser at: %s' % url)
\ No newline at end of file
diff -r 188906a7368c -r ce605c1a6d04 docutil/docpdf.py
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/docutil/docpdf.py Mon May 21 10:02:54 2012 +0200
@@ -0,0 +1,78 @@
+#!/usr/bin/env python
+# -*- coding: utf-8 -*-
+
+#This file is part of PLCOpenEditor, a library implementing an IEC 61131-3 editor
+#based on the plcopen standard.
+#
+#Copyright (C) 2007: Edouard TISSERANT and Laurent BESSARD
+#
+#See COPYING file for copyrights details.
+#
+#This library is free software; you can redistribute it and/or
+#modify it under the terms of the GNU General Public
+#License as published by the Free Software Foundation; either
+#version 2.1 of the License, or (at your option) any later version.
+#
+#This library is distributed in the hope that it will be useful,
+#but WITHOUT ANY WARRANTY; without even the implied warranty of
+#MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+#General Public License for more details.
+#
+#You should have received a copy of the GNU General Public
+#License along with this library; if not, write to the Free Software
+#Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+
+import wx, os
+
+readerexepath = None
+
+def get_acroversion():
+ " Return version of Adobe Acrobat executable or None"
+ import _winreg
+ adobesoft = _winreg.OpenKey(_winreg.HKEY_LOCAL_MACHINE, r'Software\Adobe')
+ for index in range(_winreg.QueryInfoKey(adobesoft)[0]):
+ key = _winreg.EnumKey(adobesoft, index)
+ if "acrobat" in key.lower():
+ acrokey = _winreg.OpenKey(_winreg.HKEY_LOCAL_MACHINE, 'Software\\Adobe\\%s' % key)
+ for index in range(_winreg.QueryInfoKey(acrokey)[0]):
+ numver = _winreg.EnumKey(acrokey, index)
+ try:
+ res = _winreg.QueryValue(_winreg.HKEY_LOCAL_MACHINE, 'Software\\Adobe\\%s\\%s\\InstallPath' % (key, numver))
+ return res
+ except:
+ pass
+ return None
+
+def open_win_pdf(readerexepath, pdffile, pagenum = None):
+ if pagenum != None :
+ os.spawnl(os.P_DETACH, readerexepath, "AcroRd32.exe", "/A", "page=%d=OpenActions" % pagenum, '"%s"'%pdffile)
+ else:
+ os.spawnl(os.P_DETACH, readerexepath, "AcroRd32.exe", '"%s"'%pdffile)
+
+def open_lin_pdf(readerexepath, pdffile, pagenum = None):
+ if pagenum == None :
+ os.system("%s -remote DS301 %s &"%(readerexepath, pdffile))
+ else:
+ print "Open pdf %s at page %d"%(pdffile, pagenum)
+ os.system("%s -remote DS301 %s %d &"%(readerexepath, pdffile, pagenum))
+
+def open_pdf(pdffile, pagenum = None):
+ if wx.Platform == '__WXMSW__' :
+ try:
+ readerpath = get_acroversion()
+ except:
+ wx.MessageBox("Acrobat Reader is not found or installed !")
+ return None
+
+ readerexepath = os.path.join(readerpath, "AcroRd32.exe")
+ if(os.path.isfile(readerexepath)):
+ open_win_pdf(readerexepath, pdffile, pagenum)
+ else:
+ return None
+ else:
+ readerexepath = os.path.join("/usr/bin","xpdf")
+ if(os.path.isfile(readerexepath)):
+ open_lin_pdf(readerexepath, pdffile, pagenum)
+ else:
+ wx.MessageBox("xpdf is not found or installed !")
+ return None
diff -r 188906a7368c -r ce605c1a6d04 docutil/docsvg.py
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/docutil/docsvg.py Mon May 21 10:02:54 2012 +0200
@@ -0,0 +1,63 @@
+#!/usr/bin/env python
+# -*- coding: utf-8 -*-
+
+#This file is part of PLCOpenEditor, a library implementing an IEC 61131-3 editor
+#based on the plcopen standard.
+#
+#Copyright (C) 2007: Edouard TISSERANT and Laurent BESSARD
+#
+#See COPYING file for copyrights details.
+#
+#This library is free software; you can redistribute it and/or
+#modify it under the terms of the GNU General Public
+#License as published by the Free Software Foundation; either
+#version 2.1 of the License, or (at your option) any later version.
+#
+#This library is distributed in the hope that it will be useful,
+#but WITHOUT ANY WARRANTY; without even the implied warranty of
+#MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+#General Public License for more details.
+#
+#You should have received a copy of the GNU General Public
+#License along with this library; if not, write to the Free Software
+#Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+
+import wx, os, subprocess
+
+def get_inkscape_path():
+ """ Return the Inkscape path """
+ import _winreg
+ svgexepath = _winreg.QueryValue(_winreg.HKEY_LOCAL_MACHINE,
+ 'Software\\Classes\\svgfile\\shell\\Inkscape\\command')
+ svgexepath = svgexepath.replace('"%1"', '')
+ return svgexepath.replace('"', '')
+
+def open_win_svg(svgexepath, svgfile):
+ """ Open Inkscape on Windows platform """
+ popenargs = [svgexepath]
+ if svgfile is not None :
+ popenargs.append(svgfile)
+ subprocess.Popen(popenargs).pid
+
+def open_lin_svg(svgexepath, svgfile):
+ """ Open Inkscape on Linux platform """
+ if os.path.isfile("/usr/bin/inkscape"):
+ os.system("%s %s &"%(svgexepath , svgfile))
+
+def open_svg(svgfile):
+ """ Generic function to open SVG file """
+ if wx.Platform == '__WXMSW__' :
+ svgexepath = get_inkscape_path()
+ try:
+ open_win_svg(svgexepath , svgfile)
+ except:
+ wx.MessageBox("Inkscape is not found or installed !")
+ return None
+ else:
+ svgexepath = os.path.join("/usr/bin","inkscape")
+ if(os.path.isfile(svgexepath)):
+ open_lin_svg(svgexepath, svgfile)
+ else:
+ wx.MessageBox("Inkscape is not found or installed !")
+ return None
+
diff -r 188906a7368c -r ce605c1a6d04 docutils/__init__.py
--- a/docutils/__init__.py Tue May 15 05:19:13 2012 +0900
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,27 +0,0 @@
-#!/usr/bin/env python
-# -*- coding: utf-8 -*-
-
-#This file is part of PLCOpenEditor, a library implementing an IEC 61131-3 editor
-#based on the plcopen standard.
-#
-#Copyright (C) 2007: Edouard TISSERANT and Laurent BESSARD
-#
-#See COPYING file for copyrights details.
-#
-#This library is free software; you can redistribute it and/or
-#modify it under the terms of the GNU General Public
-#License as published by the Free Software Foundation; either
-#version 2.1 of the License, or (at your option) any later version.
-#
-#This library is distributed in the hope that it will be useful,
-#but WITHOUT ANY WARRANTY; without even the implied warranty of
-#MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-#General Public License for more details.
-#
-#You should have received a copy of the GNU General Public
-#License along with this library; if not, write to the Free Software
-#Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
-
-from dochtml import *
-from docpdf import *
-from docsvg import *
\ No newline at end of file
diff -r 188906a7368c -r ce605c1a6d04 docutils/dochtml.py
--- a/docutils/dochtml.py Tue May 15 05:19:13 2012 +0900
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,96 +0,0 @@
-#!/usr/bin/env python
-# -*- coding: utf-8 -*-
-
-#This file is part of PLCOpenEditor, a library implementing an IEC 61131-3 editor
-#based on the plcopen standard.
-#
-#Copyright (C) 2007: Edouard TISSERANT and Laurent BESSARD
-#
-#See COPYING file for copyrights details.
-#
-#This library is free software; you can redistribute it and/or
-#modify it under the terms of the GNU General Public
-#License as published by the Free Software Foundation; either
-#version 2.1 of the License, or (at your option) any later version.
-#
-#This library is distributed in the hope that it will be useful,
-#but WITHOUT ANY WARRANTY; without even the implied warranty of
-#MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-#General Public License for more details.
-#
-#You should have received a copy of the GNU General Public
-#License along with this library; if not, write to the Free Software
-#Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
-
-import wx, os, wx.html, subprocess
-
-HtmlFrameOpened = []
-
-def OpenHtmlFrame(self, title, file, size):
- if title not in HtmlFrameOpened:
- HtmlFrameOpened.append(title)
- window = HtmlFrame(self, HtmlFrameOpened)
- window.SetTitle(title)
- window.SetHtmlPage(file)
- window.SetClientSize(size)
- window.Show()
-
-[ID_HTMLFRAME, ID_HTMLFRAMEHTMLCONTENT] = [wx.NewId() for _init_ctrls in range(2)]
-EVT_HTML_URL_CLICK = wx.NewId()
-
-class HtmlWindowUrlClick(wx.PyEvent):
- def __init__(self, linkinfo):
- wx.PyEvent.__init__(self)
- self.SetEventType(EVT_HTML_URL_CLICK)
- self.linkinfo = (linkinfo.GetHref(), linkinfo.GetTarget())
-
-class UrlClickHtmlWindow(wx.html.HtmlWindow):
- """ HTML window that generates and OnLinkClicked event.
-
- Use this to avoid having to override HTMLWindow
- """
- def OnLinkClicked(self, linkinfo):
- wx.PostEvent(self, HtmlWindowUrlClick(linkinfo))
-
- def Bind(self, event, handler, source=None, id=wx.ID_ANY, id2=wx.ID_ANY):
- if event == HtmlWindowUrlClick:
- self.Connect(-1, -1, EVT_HTML_URL_CLICK, handler)
- else:
- wx.html.HtmlWindow.Bind(event, handler, source=source, id=id, id2=id2)
-
-class HtmlFrame(wx.Frame):
- def _init_ctrls(self, prnt):
- wx.Frame.__init__(self, id=ID_HTMLFRAME, name='HtmlFrame',
- parent=prnt, pos=wx.Point(320, 231), size=wx.Size(853, 616),
- style=wx.DEFAULT_FRAME_STYLE, title='')
- self.Bind(wx.EVT_CLOSE, self.OnCloseFrame)
-
- self.HtmlContent = UrlClickHtmlWindow(id=ID_HTMLFRAMEHTMLCONTENT,
- name='HtmlContent', parent=self, pos=wx.Point(0, 0),
- size=wx.Size(-1, -1), style=wx.html.HW_SCROLLBAR_AUTO|wx.html.HW_NO_SELECTION)
- self.HtmlContent.Bind(HtmlWindowUrlClick, self.OnLinkClick)
-
- def __init__(self, parent, opened):
- self._init_ctrls(parent)
- self.HtmlFrameOpened = opened
-
- def SetHtmlCode(self, htmlcode):
- self.HtmlContent.SetPage(htmlcode)
-
- def SetHtmlPage(self, htmlpage):
- self.HtmlContent.LoadPage(htmlpage)
-
- def OnCloseFrame(self, event):
- self.HtmlFrameOpened.remove(self.GetTitle())
- event.Skip()
-
- def OnLinkClick(self, event):
- url = event.linkinfo[0]
- try:
- if wx.Platform == '__WXMSW__':
- import webbrowser
- webbrowser.open(url)
- elif subprocess.call("firefox %s"%url, shell=True) != 0:
- wx.MessageBox("""Firefox browser not found.\nPlease point your browser at :\n%s""" % url)
- except ImportError:
- wx.MessageBox('Please point your browser at: %s' % url)
\ No newline at end of file
diff -r 188906a7368c -r ce605c1a6d04 docutils/docpdf.py
--- a/docutils/docpdf.py Tue May 15 05:19:13 2012 +0900
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,78 +0,0 @@
-#!/usr/bin/env python
-# -*- coding: utf-8 -*-
-
-#This file is part of PLCOpenEditor, a library implementing an IEC 61131-3 editor
-#based on the plcopen standard.
-#
-#Copyright (C) 2007: Edouard TISSERANT and Laurent BESSARD
-#
-#See COPYING file for copyrights details.
-#
-#This library is free software; you can redistribute it and/or
-#modify it under the terms of the GNU General Public
-#License as published by the Free Software Foundation; either
-#version 2.1 of the License, or (at your option) any later version.
-#
-#This library is distributed in the hope that it will be useful,
-#but WITHOUT ANY WARRANTY; without even the implied warranty of
-#MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-#General Public License for more details.
-#
-#You should have received a copy of the GNU General Public
-#License along with this library; if not, write to the Free Software
-#Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
-
-import wx, os
-
-readerexepath = None
-
-def get_acroversion():
- " Return version of Adobe Acrobat executable or None"
- import _winreg
- adobesoft = _winreg.OpenKey(_winreg.HKEY_LOCAL_MACHINE, r'Software\Adobe')
- for index in range(_winreg.QueryInfoKey(adobesoft)[0]):
- key = _winreg.EnumKey(adobesoft, index)
- if "acrobat" in key.lower():
- acrokey = _winreg.OpenKey(_winreg.HKEY_LOCAL_MACHINE, 'Software\\Adobe\\%s' % key)
- for index in range(_winreg.QueryInfoKey(acrokey)[0]):
- numver = _winreg.EnumKey(acrokey, index)
- try:
- res = _winreg.QueryValue(_winreg.HKEY_LOCAL_MACHINE, 'Software\\Adobe\\%s\\%s\\InstallPath' % (key, numver))
- return res
- except:
- pass
- return None
-
-def open_win_pdf(readerexepath, pdffile, pagenum = None):
- if pagenum != None :
- os.spawnl(os.P_DETACH, readerexepath, "AcroRd32.exe", "/A", "page=%d=OpenActions" % pagenum, '"%s"'%pdffile)
- else:
- os.spawnl(os.P_DETACH, readerexepath, "AcroRd32.exe", '"%s"'%pdffile)
-
-def open_lin_pdf(readerexepath, pdffile, pagenum = None):
- if pagenum == None :
- os.system("%s -remote DS301 %s &"%(readerexepath, pdffile))
- else:
- print "Open pdf %s at page %d"%(pdffile, pagenum)
- os.system("%s -remote DS301 %s %d &"%(readerexepath, pdffile, pagenum))
-
-def open_pdf(pdffile, pagenum = None):
- if wx.Platform == '__WXMSW__' :
- try:
- readerpath = get_acroversion()
- except:
- wx.MessageBox("Acrobat Reader is not found or installed !")
- return None
-
- readerexepath = os.path.join(readerpath, "AcroRd32.exe")
- if(os.path.isfile(readerexepath)):
- open_win_pdf(readerexepath, pdffile, pagenum)
- else:
- return None
- else:
- readerexepath = os.path.join("/usr/bin","xpdf")
- if(os.path.isfile(readerexepath)):
- open_lin_pdf(readerexepath, pdffile, pagenum)
- else:
- wx.MessageBox("xpdf is not found or installed !")
- return None
diff -r 188906a7368c -r ce605c1a6d04 docutils/docsvg.py
--- a/docutils/docsvg.py Tue May 15 05:19:13 2012 +0900
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,63 +0,0 @@
-#!/usr/bin/env python
-# -*- coding: utf-8 -*-
-
-#This file is part of PLCOpenEditor, a library implementing an IEC 61131-3 editor
-#based on the plcopen standard.
-#
-#Copyright (C) 2007: Edouard TISSERANT and Laurent BESSARD
-#
-#See COPYING file for copyrights details.
-#
-#This library is free software; you can redistribute it and/or
-#modify it under the terms of the GNU General Public
-#License as published by the Free Software Foundation; either
-#version 2.1 of the License, or (at your option) any later version.
-#
-#This library is distributed in the hope that it will be useful,
-#but WITHOUT ANY WARRANTY; without even the implied warranty of
-#MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-#General Public License for more details.
-#
-#You should have received a copy of the GNU General Public
-#License along with this library; if not, write to the Free Software
-#Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
-
-import wx, os, subprocess
-
-def get_inkscape_path():
- """ Return the Inkscape path """
- import _winreg
- svgexepath = _winreg.QueryValue(_winreg.HKEY_LOCAL_MACHINE,
- 'Software\\Classes\\svgfile\\shell\\Inkscape\\command')
- svgexepath = svgexepath.replace('"%1"', '')
- return svgexepath.replace('"', '')
-
-def open_win_svg(svgexepath, svgfile):
- """ Open Inkscape on Windows platform """
- popenargs = [svgexepath]
- if svgfile is not None :
- popenargs.append(svgfile)
- subprocess.Popen(popenargs).pid
-
-def open_lin_svg(svgexepath, svgfile):
- """ Open Inkscape on Linux platform """
- if os.path.isfile("/usr/bin/inkscape"):
- os.system("%s %s &"%(svgexepath , svgfile))
-
-def open_svg(svgfile):
- """ Generic function to open SVG file """
- if wx.Platform == '__WXMSW__' :
- svgexepath = get_inkscape_path()
- try:
- open_win_svg(svgexepath , svgfile)
- except:
- wx.MessageBox("Inkscape is not found or installed !")
- return None
- else:
- svgexepath = os.path.join("/usr/bin","inkscape")
- if(os.path.isfile(svgexepath)):
- open_lin_svg(svgexepath, svgfile)
- else:
- wx.MessageBox("Inkscape is not found or installed !")
- return None
-
diff -r 188906a7368c -r ce605c1a6d04 graphics/FBD_Objects.py
--- a/graphics/FBD_Objects.py Tue May 15 05:19:13 2012 +0900
+++ b/graphics/FBD_Objects.py Mon May 21 10:02:54 2012 +0200
@@ -263,6 +263,7 @@
self.Pen = MiterPen(self.Colour)
# Extract the inputs properties and create or modify the corresponding connector
+ idx = 0
for idx, (input_name, input_type, input_modifier) in enumerate(inputs):
if idx < len(self.Inputs):
connector = self.Inputs[idx]
@@ -280,6 +281,7 @@
self.Inputs = self.Inputs[:idx + 1]
# Extract the outputs properties and create or modify the corresponding connector
+ idx = 0
for idx, (output_name, output_type, output_modifier) in enumerate(outputs):
if idx < len(self.Outputs):
connector = self.Outputs[idx]
diff -r 188906a7368c -r ce605c1a6d04 plcopen/plcopen.py
--- a/plcopen/plcopen.py Tue May 15 05:19:13 2012 +0900
+++ b/plcopen/plcopen.py Mon May 21 10:02:54 2012 +0200
@@ -234,8 +234,10 @@
self.contentHeader.setauthor(contentheader["authorName"])
if contentheader.has_key("language"):
self.contentHeader.setlanguage(contentheader["language"])
- self.contentHeader.setpageSize(*contentheader["pageSize"])
- self.contentHeader.setscaling(contentheader["scaling"])
+ if contentheader.has_key("pageSize"):
+ self.contentHeader.setpageSize(*contentheader["pageSize"])
+ if contentheader.has_key("scaling"):
+ self.contentHeader.setscaling(contentheader["scaling"])
setattr(cls, "setcontentHeader", setcontentHeader)
def getdataTypes(self):
diff -r 188906a7368c -r ce605c1a6d04 xmlclass/xmlclass.py
--- a/xmlclass/xmlclass.py Tue May 15 05:19:13 2012 +0900
+++ b/xmlclass/xmlclass.py Mon May 21 10:02:54 2012 +0200
@@ -1238,15 +1238,16 @@
classmembers["setElementValue"] = generateSetElementValue(self, classinfos)
classmembers["singleLineAttributes"] = True
classmembers["compatibility"] = lambda x, y: None
+ classmembers["extraAttrs"] = {}
class_definition = classobj(str(classname), bases, classmembers)
setattr(class_definition, "__setattr__", generateSetattrMethod(self, class_definition, classinfos))
class_infos = {"type": COMPILEDCOMPLEXTYPE,
- "name": classname,
- "check": generateClassCheckFunction(class_definition),
- "initial": generateClassCreateFunction(class_definition),
- "extract": generateClassExtractFunction(class_definition),
- "generate": class_definition.generateXMLText}
+ "name": classname,
+ "check": generateClassCheckFunction(class_definition),
+ "initial": generateClassCreateFunction(class_definition),
+ "extract": generateClassExtractFunction(class_definition),
+ "generate": class_definition.generateXMLText}
if self.FileName is not None:
self.ComputedClasses[self.FileName][classname] = class_definition
@@ -1410,6 +1411,7 @@
elements = dict([(element["name"], element) for element in classinfos["elements"]])
def loadXMLTreeMethod(self, tree, extras=[], derived=False):
+ self.extraAttrs = {}
self.compatibility(tree)
if not derived:
children_structure = ""
@@ -1430,8 +1432,8 @@
if attributes.has_key(attrname):
attributes[attrname]["attr_type"] = FindTypeInfos(factory, attributes[attrname]["attr_type"])
object.__setattr__(self, attrname, attributes[attrname]["attr_type"]["extract"](attr))
- elif not classinfos.has_key("base") and attrname not in extras:
- raise ValueError("Invalid attribute \"%s\" for \"%s\" element!" % (attrname, tree.nodeName))
+ elif not classinfos.has_key("base") and not attrname in extras and not self.extraAttrs.has_key(attrname):
+ self.extraAttrs[attrname] = GetAttributeValue(attr)
required_attributes.pop(attrname, None)
if len(required_attributes) > 0:
raise ValueError("Required attributes %s missing for \"%s\" element!" % (", ".join(["\"%s\""%name for name in required_attributes]), tree.nodeName))
@@ -1489,8 +1491,10 @@
text = u''
first = True
+
if not classinfos.has_key("base"):
- for attr, value in extras.items():
+ extras.update(self.extraAttrs)
+ for attr, value in extras.iteritems():
if not first and not self.singleLineAttributes:
text += u'\n%s' % (ind2)
text += u' %s=%s' % (attr, quoteattr(value))
@@ -1643,7 +1647,7 @@
elif element["elmt_type"]["type"] == SIMPLETYPE:
children.append({"name": element_name, "require": element["minOccurs"] != 0,
"type": gettypeinfos(element["elmt_type"]["basename"],
- element["elmt_type"]["facets"]),
+ element["elmt_type"]["facets"]),
"value": getattr(self, element_name, None)})
else:
instance = getattr(self, element_name, None)
@@ -1677,6 +1681,9 @@
setattr(self, parts[0], elements[parts[0]]["elmt_type"]["extract"](value, False))
else:
instance = getattr(self, parts[0], None)
+ if instance is None and elements[parts[0]]["minOccurs"] == 0:
+ instance = elements[parts[0]]["elmt_type"]["initial"]()
+ setattr(self, parts[0], instance)
if instance != None:
if len(parts) > 1:
instance.setElementValue(parts[1], value)
@@ -1702,6 +1709,7 @@
"""
def generateInitMethod(factory, classinfos):
def initMethod(self):
+ self.extraAttrs = {}
if classinfos.has_key("base"):
classinfos["base"].__init__(self)
for attribute in classinfos["attributes"]:
@@ -1837,14 +1845,8 @@
"""
This function generate the classes from a class factory
"""
-def GenerateClasses(factory, declare=False):
+def GenerateClasses(factory):
ComputedClasses = factory.CreateClasses()
- #factory.PrintClasses()
- if declare:
- for ClassName, Class in pluginClasses.items():
- sys._getframe(1).f_locals[ClassName] = Class
- for TypeName, Type in pluginTypes.items():
- sys._getframe(1).f_locals[TypeName] = Type
if factory.FileName is not None and len(ComputedClasses) == 1:
globals().update(ComputedClasses[factory.FileName])
return ComputedClasses[factory.FileName]
diff -r 188906a7368c -r ce605c1a6d04 xmlclass/xsdschema.py
--- a/xmlclass/xsdschema.py Tue May 15 05:19:13 2012 +0900
+++ b/xmlclass/xsdschema.py Mon May 21 10:02:54 2012 +0200
@@ -1086,17 +1086,17 @@
"""
This function opens the xsd file and generate the classes from the xml tree
"""
-def GenerateClassesFromXSD(filepath, declare=False):
+def GenerateClassesFromXSD(filepath):
xsdfile = open(filepath, 'r')
factory = XSDClassFactory(minidom.parse(xsdfile), filepath)
xsdfile.close()
- return GenerateClasses(factory, declare)
+ return GenerateClasses(factory)
"""
This function generate the classes from the xsd given as a string
"""
-def GenerateClassesFromXSDstring(xsdstring, declare=False):
- return GenerateClasses(XSDClassFactory(minidom.parseString(xsdstring)), declare)
+def GenerateClassesFromXSDstring(xsdstring):
+ return GenerateClasses(XSDClassFactory(minidom.parseString(xsdstring)))
#-------------------------------------------------------------------------------