--- a/Beremiz.py Fri Aug 11 15:18:19 2017 +0300
+++ b/Beremiz.py Mon Aug 14 19:13:01 2017 +0300
@@ -60,14 +60,14 @@
def Usage(self):
print "Usage:"
- print "%s [Options] [Projectpath] [Buildpath]"%sys.argv[0]
+ print "%s [Options] [Projectpath] [Buildpath]"%sys.argv[0]
print ""
print "Supported options:"
print "-h --help Print this help"
print "-u --updatecheck URL Retrieve update information by checking URL"
print "-e --extend PathToExtension Extend IDE functionality by loading at start additional extensions"
print ""
- print ""
+ print ""
def SetCmdOptions(self):
self.shortCmdOpts = "hu:e:"
--- a/BeremizIDE.py Fri Aug 11 15:18:19 2017 +0300
+++ b/BeremizIDE.py Mon Aug 14 19:13:01 2017 +0300
@@ -276,9 +276,9 @@
wx.MessageBox(version.GetCommunityHelpMsg(), _(u'Community support'), wx.OK | wx.ICON_INFORMATION)
}
id = wx.NewId()
- parent.Append(help='', id=id, kind=wx.ITEM_NORMAL, text=_(u'Community support'))
+ parent.Append(help='', id=id, kind=wx.ITEM_NORMAL, text=_(u'Community support'))
self.Bind(wx.EVT_MENU, handler, id=id)
-
+
parent.Append(help='', id=wx.ID_ABOUT,
kind=wx.ITEM_NORMAL, text=_(u'About'))
self.Bind(wx.EVT_MENU, self.OnAboutMenu, id=wx.ID_ABOUT)
@@ -371,7 +371,7 @@
self.ConnectionStatusBar = esb.EnhancedStatusBar(self, style=wx.ST_SIZEGRIP)
self._init_coll_ConnectionStatusBar_Fields(self.ConnectionStatusBar)
self.ProgressStatusBar = wx.Gauge(self.ConnectionStatusBar, -1, range = 100)
- self.ConnectionStatusBar.AddWidget(self.ProgressStatusBar, esb.ESB_EXACT_FIT, esb.ESB_EXACT_FIT, 2)
+ self.ConnectionStatusBar.AddWidget(self.ProgressStatusBar, esb.ESB_EXACT_FIT, esb.ESB_EXACT_FIT, 2)
self.ProgressStatusBar.Hide()
self.SetStatusBar(self.ConnectionStatusBar)
@@ -383,13 +383,13 @@
# commands invoked by build process by default are
# found here.
os.environ["PATH"] = os.getcwd()+';'+os.environ["PATH"]
-
-
+
+
def __init__(self, parent, projectOpen=None, buildpath=None, ctr=None, debug=True):
# Add beremiz's icon in top left corner of the frame
self.icon = wx.Icon(Bpath("images", "brz.ico"), wx.BITMAP_TYPE_ICO)
self.__init_execute_path()
-
+
IDEFrame.__init__(self, parent, debug)
self.Log = LogPseudoFile(self.LogConsole,self.SelectTab)
@@ -932,7 +932,7 @@
self.Close()
def OnAboutMenu(self, event):
- info = version.GetAboutDialogInfo()
+ info = version.GetAboutDialogInfo()
ShowAboutDialog(self, info)
def OnProjectTreeItemBeginEdit(self, event):
--- a/Beremiz_service.py Fri Aug 11 15:18:19 2017 +0300
+++ b/Beremiz_service.py Mon Aug 14 19:13:01 2017 +0300
@@ -306,7 +306,7 @@
def OnTaskBarChangeInterface(self, evt):
ip_addr = self.pyroserver.ip_addr
ip_addr = '' if ip_addr is None else ip_addr
- dlg = ParamsEntryDialog(None, _("Enter the IP of the interface to bind"), defaultValue=ip_addr)
+ dlg = ParamsEntryDialog(None, _("Enter the IP of the interface to bind"), defaultValue=ip_addr)
dlg.SetTests([(re.compile('\d{1,3}(?:\.\d{1,3}){3}$').match, _("IP is not valid!")),
( lambda x :len([x for x in x.split(".") if 0 <= int(x) <= 255]) == 4, _("IP is not valid!"))
])
--- a/CodeFileTreeNode.py Fri Aug 11 15:18:19 2017 +0300
+++ b/CodeFileTreeNode.py Mon Aug 14 19:13:01 2017 +0300
@@ -81,10 +81,10 @@
SECTION_TAG_ELEMENT = "<xsd:element name=\"%s\" type=\"CodeText\"/>"
class CodeFile:
-
+
CODEFILE_NAME = "CodeFile"
SECTIONS_NAMES = []
-
+
def __init__(self):
sections_str = {"codefile_name": self.CODEFILE_NAME}
if "includes" in self.SECTIONS_NAMES:
@@ -94,26 +94,26 @@
sections_str["sections"] = "\n".join(
[SECTION_TAG_ELEMENT % name
for name in self.SECTIONS_NAMES if name != "includes"])
-
+
self.CodeFileParser = GenerateParserFromXSDstring(
CODEFILE_XSD % sections_str)
self.CodeFileVariables = etree.XPath("variables/variable")
-
+
filepath = self.CodeFileName()
-
+
if os.path.isfile(filepath):
xmlfile = open(filepath, 'r')
codefile_xml = xmlfile.read()
xmlfile.close()
-
+
codefile_xml = codefile_xml.replace(
- '<%s>' % self.CODEFILE_NAME,
+ '<%s>' % self.CODEFILE_NAME,
'<%s xmlns:xhtml="http://www.w3.org/1999/xhtml">' % self.CODEFILE_NAME)
for cre, repl in [
(re.compile("(?<!<xhtml:p>)(?:<!\[CDATA\[)"), "<xhtml:p><![CDATA["),
(re.compile("(?:]]>)(?!</xhtml:p>)"), "]]></xhtml:p>")]:
codefile_xml = cre.sub(repl, codefile_xml)
-
+
try:
self.CodeFile, error = self.CodeFileParser.LoadXMLString(codefile_xml)
if error is not None:
@@ -138,7 +138,7 @@
def GenerateNewName(self, format, start_idx):
return self.GetCTRoot().GenerateNewName(
None, None, format, start_idx,
- dict([(var.getname().upper(), True)
+ dict([(var.getname().upper(), True)
for var in self.CodeFile.variables.getvariable()]))
def SetVariables(self, variables):
@@ -152,12 +152,12 @@
variable.setonchange(var["OnChange"])
variable.setopts(var["Options"])
self.CodeFile.variables.appendvariable(variable)
-
+
def GetVariables(self):
datas = []
for var in self.CodeFileVariables(self.CodeFile):
- datas.append({"Name" : var.getname(),
- "Type" : var.gettype(),
+ datas.append({"Name" : var.getname(),
+ "Type" : var.gettype(),
"Initial" : var.getinitial(),
"Description" : var.getdesc(),
"OnChange" : var.getonchange(),
@@ -170,25 +170,25 @@
section_code = parts.get(section)
if section_code is not None:
getattr(self.CodeFile, section).setanyText(section_code)
-
+
def GetTextParts(self):
return dict([(section, getattr(self.CodeFile, section).getanyText())
for section in self.SECTIONS_NAMES])
-
+
def CTNTestModified(self):
- return self.ChangesToSave or not self.CodeFileIsSaved()
+ return self.ChangesToSave or not self.CodeFileIsSaved()
def OnCTNSave(self, from_project_path=None):
filepath = self.CodeFileName()
-
+
xmlfile = open(filepath,"w")
xmlfile.write(etree.tostring(
- self.CodeFile,
- pretty_print=True,
- xml_declaration=True,
+ self.CodeFile,
+ pretty_print=True,
+ xml_declaration=True,
encoding='utf-8'))
xmlfile.close()
-
+
self.MarkCodeFileAsSaved()
return True
@@ -196,7 +196,7 @@
variables = self.CodeFileVariables(self.CodeFile)
ret = [(variable.getname(),
variable.gettype(),
- variable.getinitial())
+ variable.getinitial())
for variable in variables]
ret.extend([("On"+variable.getname()+"Change", "python_poll", "")
for variable in variables
@@ -219,31 +219,30 @@
def BufferCodeFile(self):
self.CodeFileBuffer.Buffering(self.CodeFileParser.Dumps(self.CodeFile))
-
+
def StartBuffering(self):
self.Buffering = True
-
+
def EndBuffering(self):
if self.Buffering:
self.CodeFileBuffer.Buffering(self.CodeFileParser.Dumps(self.CodeFile))
self.Buffering = False
-
+
def MarkCodeFileAsSaved(self):
self.EndBuffering()
self.CodeFileBuffer.CurrentSaved()
-
+
def CodeFileIsSaved(self):
return self.CodeFileBuffer.IsCurrentSaved() and not self.Buffering
-
+
def LoadPrevious(self):
self.EndBuffering()
self.CodeFile = self.CodeFileParser.Loads(self.CodeFileBuffer.Previous())
-
+
def LoadNext(self):
self.CodeFile = self.CodeFileParser.Loads(self.CodeFileBuffer.Next())
-
+
def GetBufferState(self):
first = self.CodeFileBuffer.IsFirst() and not self.Buffering
last = self.CodeFileBuffer.IsLast()
return not first, not last
-
--- a/ConfigTreeNode.py Fri Aug 11 15:18:19 2017 +0300
+++ b/ConfigTreeNode.py Mon Aug 14 19:13:01 2017 +0300
@@ -67,7 +67,7 @@
LibraryControler = None
EditorType = ConfTreeNodeEditor
IconPath = None
-
+
def _AddParamsMembers(self):
self.CTNParams = None
if self.XSD:
@@ -78,7 +78,7 @@
setattr(self, name, obj)
def __init__(self):
- # Create BaseParam
+ # Create BaseParam
self.BaseParams = _BaseParamsParser.CreateRoot()
self.MandatoryParams = ("BaseParams", self.BaseParams)
self._AddParamsMembers()
@@ -86,10 +86,10 @@
self._View = None
# copy ConfNodeMethods so that it can be later customized
self.ConfNodeMethods = [dic.copy() for dic in self.ConfNodeMethods]
-
+
def ConfNodeBaseXmlFilePath(self, CTNName=None):
return os.path.join(self.CTNPath(CTNName), "baseconfnode.xml")
-
+
def ConfNodeXmlFilePath(self, CTNName=None):
return os.path.join(self.CTNPath(CTNName), "confnode.xml")
@@ -103,22 +103,22 @@
project_path = self.CTNParent.CTNPath()
return os.path.join(project_path,
CTNName + NameTypeSeparator + self.CTNType)
-
+
def CTNName(self):
return self.BaseParams.getName()
-
+
def CTNEnabled(self):
return self.BaseParams.getEnabled()
-
+
def CTNFullName(self):
parent = self.CTNParent.CTNFullName()
if parent != "":
return parent + "." + self.CTNName()
return self.BaseParams.getName()
-
+
def GetIconName(self):
return None
-
+
def CTNTestModified(self):
return self.ChangesToSave
@@ -134,10 +134,10 @@
return True
return False
-
+
def RemoteExec(self, script, **kwargs):
return self.CTNParent.RemoteExec(script, **kwargs)
-
+
def OnCTNSave(self, from_project_path=None):
#Default, do nothing and return success
return True
@@ -154,7 +154,7 @@
if self.CTNParams:
params.append(self.CTNParams[1].getElementInfos(self.CTNParams[0]))
return params
-
+
def SetParamsAttribute(self, path, value):
self.ChangesToSave = True
# Filter IEC_Channel and Name, that have specific behavior
@@ -169,7 +169,7 @@
res = self.FindNewName(value)
self.CTNRequestSave()
return res, True
-
+
parts = path.split(".", 1)
if self.MandatoryParams and parts[0] == self.MandatoryParams[0]:
self.MandatoryParams[1].setElementValue(parts[1], value)
@@ -189,32 +189,32 @@
if not os.path.isdir(ctnpath):
# Create it
os.mkdir(ctnpath)
-
+
# generate XML for base XML parameters controller of the confnode
if self.MandatoryParams:
BaseXMLFile = open(self.ConfNodeBaseXmlFilePath(),'w')
BaseXMLFile.write(etree.tostring(
- self.MandatoryParams[1],
- pretty_print=True,
- xml_declaration=True,
+ self.MandatoryParams[1],
+ pretty_print=True,
+ xml_declaration=True,
encoding='utf-8'))
BaseXMLFile.close()
-
+
# generate XML for XML parameters controller of the confnode
if self.CTNParams:
XMLFile = open(self.ConfNodeXmlFilePath(),'w')
XMLFile.write(etree.tostring(
- self.CTNParams[1],
- pretty_print=True,
- xml_declaration=True,
+ self.CTNParams[1],
+ pretty_print=True,
+ xml_declaration=True,
encoding='utf-8'))
XMLFile.close()
-
+
# Call the confnode specific OnCTNSave method
result = self.OnCTNSave(from_project_path)
if not result:
return _("Error while saving \"%s\"\n")%self.CTNPath()
-
+
# mark confnode as saved
self.ChangesToSave = False
# go through all children and do the same
@@ -226,7 +226,7 @@
if result:
return result
return None
-
+
def CTNImport(self, src_CTNPath):
shutil.copytree(src_CTNPath, self.CTNPath)
return True
@@ -236,13 +236,13 @@
@return: [(instance_name, instance_type),...]
"""
return []
-
+
def _GlobalInstances(self):
instances = self.CTNGlobalInstances()
for CTNChild in self.IECSortedChildren():
instances.extend(CTNChild._GlobalInstances())
return instances
-
+
def CTNGenerate_C(self, buildpath, locations):
"""
Generate C code
@@ -257,7 +257,7 @@
"""
self.GetCTRoot().logger.write_warning(".".join(map(lambda x:str(x), self.GetCurrentLocation())) + " -> Nothing to do\n")
return [],"",False
-
+
def _Generate_C(self, buildpath, locations):
# Generate confnodes [(Cfiles, CFLAGS)], LDFLAGS, DoCalls, extra_files
# extra_files = [(fname,fobject), ...]
@@ -280,7 +280,7 @@
LDFLAGS=CTNLDFLAGS[:]
else:
LDFLAGS=[]
-
+
# recurse through all children, and stack their results
for CTNChild in self.IECSortedChildren():
new_location = CTNChild.GetCurrentLocation()
@@ -296,14 +296,14 @@
LocationCFilesAndCFLAGS += _LocationCFilesAndCFLAGS
LDFLAGS += _LDFLAGS
extra_files += _extra_files
-
+
return LocationCFilesAndCFLAGS, LDFLAGS, extra_files
def IterChildren(self):
for CTNType, Children in self.Children.items():
for CTNInstance in Children:
yield CTNInstance
-
+
def IECSortedChildren(self):
# reorder children by IEC_channels
ordered = [(chld.BaseParams.getIEC_Channel(),chld) for chld in self.IterChildren()]
@@ -312,7 +312,7 @@
return zip(*ordered)[1]
else:
return []
-
+
def _GetChildBySomething(self, something, toks):
for CTNInstance in self.IterChildren():
# if match component of the name
@@ -338,7 +338,7 @@
return self._GetChildBySomething("IEC_Channel", Location)
else:
return self
-
+
def GetCurrentLocation(self):
"""
@return: Tupple containing confnode IEC location of current confnode : %I0.0.4.5 => (0,0,4,5)
@@ -372,7 +372,7 @@
This function is meant to be overridden by confnodes.
It should returns an list of dictionaries
-
+
- IEC_type is an IEC type like BOOL/BYTE/SINT/...
- location is a string of this variable's location, like "%IX0.0.0"
'''
@@ -409,7 +409,7 @@
while res in AllNames:
res = "%s_%d"%(BaseDesiredName, suffix)
suffix += 1
-
+
# Get old path
oldname = self.CTNPath()
# Check previous confnode existance
@@ -444,7 +444,7 @@
#if CurrentChannel == DesiredChannel: return CurrentChannel
# Build a list of used Channels out of parent's Children
AllChannels = self.GetAllChannels()
-
+
# Now, try to guess the nearest available channel
res = DesiredChannel
while res in AllChannels: # While channel not free
@@ -466,14 +466,14 @@
if self.EditorType is not None:
app_frame = self.GetCTRoot().AppFrame
if self._View is None and not onlyopened:
-
+
self._View = self.EditorType(app_frame.TabsOpened, self, app_frame)
-
+
if self._View is not None:
if name is None:
name = self.CTNFullName()
app_frame.EditProjectElement(self._View, name)
-
+
return self._View
return None
@@ -527,23 +527,23 @@
CTNClass, CTNHelp = CTNChildrenTypes[CTNType]
except KeyError:
raise Exception, _("Cannot create child {a1} of type {a2} ").format(a1 = CTNName, a2 = CTNType)
-
+
# if CTNClass is a class factory, call it. (prevent unneeded imports)
if type(CTNClass) == types.FunctionType:
CTNClass = CTNClass()
-
+
# Eventualy Initialize child instance list for this class of confnode
ChildrenWithSameClass = self.Children.setdefault(CTNType, list())
# Check count
if getattr(CTNClass, "CTNMaxCount", None) and len(ChildrenWithSameClass) >= CTNClass.CTNMaxCount:
msg = _("Max count ({a1}) reached for this confnode of type {a2} ").format(a1 = CTNClass.CTNMaxCount, a2 = CTNType)
raise Exception, msg
-
+
# create the final class, derived of provided confnode and template
class FinalCTNClass(CTNClass, ConfigTreeNode):
"""
ConfNode class is derivated into FinalCTNClass before being instanciated
- This way __init__ is overloaded to ensure ConfigTreeNode.__init__ is called
+ This way __init__ is overloaded to ensure ConfigTreeNode.__init__ is called
before CTNClass.__init__, and to do the file related stuff.
"""
def __init__(_self):
@@ -568,7 +568,7 @@
raise Exception, msg
# Now, self.CTNPath() should be OK
-
+
# Check that IEC_Channel is not already in use.
_self.FindNewIEC_Channel(_self.BaseParams.getIEC_Channel())
# Call the confnode real __init__
@@ -589,29 +589,29 @@
_self.CTNRequestSave()
#just created, must be saved
_self.ChangesToSave = True
-
+
def _getBuildPath(_self):
return self._getBuildPath()
-
+
# Create the object out of the resulting class
newConfNodeOpj = FinalCTNClass()
# Store it in CTNgedChils
ChildrenWithSameClass.append(newConfNodeOpj)
-
+
return newConfNodeOpj
-
+
def ClearChildren(self):
for child in self.IterChildren():
child.ClearChildren()
self.Children = {}
-
+
def LoadXMLParams(self, CTNName = None):
methode_name = os.path.join(self.CTNPath(CTNName), "methods.py")
if os.path.isfile(methode_name):
execfile(methode_name)
-
+
ConfNodeName = CTNName if CTNName is not None else self.CTNName()
-
+
# Get the base xml tree
if self.MandatoryParams:
try:
@@ -626,7 +626,7 @@
msg = _("Couldn't load confnode base parameters {a1} :\n {a2}").format(a1 = ConfNodeName, a2 = unicode(exc))
self.GetCTRoot().logger.write_error(msg)
self.GetCTRoot().logger.write_error(traceback.format_exc())
-
+
# Get the xml tree
if self.CTNParams:
try:
@@ -643,7 +643,7 @@
msg = _("Couldn't load confnode parameters {a1} :\n {a2}").format(a1 = ConfNodeName, a2 = unicode(exc))
self.GetCTRoot().logger.write_error(msg)
self.GetCTRoot().logger.write_error(traceback.format_exc())
-
+
def LoadChildren(self):
# Iterate over all CTNName@CTNType in confnode directory, and try to open them
for CTNDir in os.listdir(self.CTNPath()):
@@ -656,4 +656,3 @@
msg = _("Could not add child \"{a1}\", type {a2} :\n{a3}\n").format(a1 = pname, a2 = ptype, a3 = unicode(exc))
self.GetCTRoot().logger.write_error(msg)
self.GetCTRoot().logger.write_error(traceback.format_exc())
-
--- a/IDEFrame.py Fri Aug 11 15:18:19 2017 +0300
+++ b/IDEFrame.py Mon Aug 14 19:13:01 2017 +0300
@@ -474,10 +474,10 @@
def _init_icon(self, parent):
if self.icon:
- self.SetIcon(self.icon)
+ self.SetIcon(self.icon)
elif parent and parent.icon:
- self.SetIcon(parent.icon)
-
+ self.SetIcon(parent.icon)
+
def _init_ctrls(self, prnt):
wx.Frame.__init__(self, id=ID_PLCOPENEDITOR, name='IDEFrame',
parent=prnt, pos=wx.DefaultPosition, size=wx.Size(1000, 600),
@@ -1626,7 +1626,7 @@
self.RefreshPageTitles()
elif item_infos["type"] == ITEM_TRANSITION:
pou_item = self.ProjectTree.GetItemParent(event.GetItem())
- pou_name = self.ProjectTree.GetItemText(pou_item)
+ pou_name = self.ProjectTree.GetItemText(pou_item)
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.GetProjectPouVariableNames(pou_name) if name != old_name]:
@@ -2630,4 +2630,3 @@
self.Viewer.DoDrawing(dc, True)
return True
-
--- a/NativeLib.py Fri Aug 11 15:18:19 2017 +0300
+++ b/NativeLib.py Mon Aug 14 19:13:01 2017 +0300
@@ -29,5 +29,4 @@
class NativeLibrary(POULibrary):
def GetLibraryPath(self):
- return paths.AbsNeighbourFile(__file__, "NativeLib.xml")
-
+ return paths.AbsNeighbourFile(__file__, "NativeLib.xml")
--- a/PLCGenerator.py Fri Aug 11 15:18:19 2017 +0300
+++ b/PLCGenerator.py Mon Aug 14 19:13:01 2017 +0300
@@ -771,7 +771,7 @@
connections = content["value"].getconnections()
if not connections:
raise PLCGenException, _("SFC transition in POU \"%s\" must be connected.") % self.Name
- for link in connections:
+ for link in connections:
connected = self.GetLinkedConnector(link, body)
if connected is not None and not self.ConnectionTypes.has_key(connected):
for related in self.ExtractRelatedConnections(connected):
@@ -1662,4 +1662,3 @@
generator = ProgramGenerator(controler, project, errors, warnings)
generator.GenerateProgram()
return generator.GetGeneratedProgram()
-
--- a/PLCOpenEditor.py Fri Aug 11 15:18:19 2017 +0300
+++ b/PLCOpenEditor.py Mon Aug 14 19:13:01 2017 +0300
@@ -156,14 +156,14 @@
# kind=wx.ITEM_NORMAL, text=u'PLCOpen\tF2')
#AppendMenu(parent, help='', id=wx.ID_HELP_CONTEXT,
# kind=wx.ITEM_NORMAL, text=u'IEC 61131-3\tF3')
-
+
handler=lambda event: {
wx.MessageBox(version.GetCommunityHelpMsg(), _(u'Community support'), wx.OK | wx.ICON_INFORMATION)
}
id = wx.NewId()
- parent.Append(help='', id=id, kind=wx.ITEM_NORMAL, text=_(u'Community support'))
+ parent.Append(help='', id=id, kind=wx.ITEM_NORMAL, text=_(u'Community support'))
self.Bind(wx.EVT_MENU, handler, id=id)
-
+
AppendMenu(parent, help='', id=wx.ID_ABOUT,
kind=wx.ITEM_NORMAL, text=_(u'About'))
self.Bind(wx.EVT_MENU, self.OnPLCOpenEditorMenu, id=wx.ID_HELP)
@@ -505,4 +505,3 @@
frame.Show()
app.MainLoop()
-
--- a/POULibrary.py Fri Aug 11 15:18:19 2017 +0300
+++ b/POULibrary.py Mon Aug 14 19:13:01 2017 +0300
@@ -38,14 +38,14 @@
def GetSTCode(self):
if not self.program:
self.program = self.LibraryControler.GenerateProgram()[0]+"\n"
- return self.program
+ return self.program
def GetName(self):
return self.LibName
def GetCTR(self):
return self.CTR()
-
+
def GetTypes(self):
return {"name" : self.GetName(), "types": self.LibraryControler.Project}
--- a/ProjectController.py Fri Aug 11 15:18:19 2017 +0300
+++ b/ProjectController.py Mon Aug 14 19:13:01 2017 +0300
@@ -98,9 +98,9 @@
for p in paths:
if test(p):
path = p
- break
+ break
return path
-
+
def findCmd(self):
cmd="iec2c"+(".exe" if wx.Platform == '__WXMSW__' else "")
paths=[
@@ -113,7 +113,7 @@
cmd=os.path.join(path, cmd)
return cmd
-
+
def findLibPath(self):
paths=[
os.path.join(base_folder, "matiec", "lib"),
@@ -121,7 +121,7 @@
]
path = self.findObject(paths, lambda p:os.path.isfile(os.path.join(p, "ieclib.txt")))
return path
-
+
def findLibCPath(self):
path=None
paths=[
@@ -1158,14 +1158,14 @@
def ShowError(self, logger, from_location, to_location):
chunk_infos = self.GetChunkInfos(from_location, to_location)
for infos, (start_row, start_col) in chunk_infos:
- row = 1 if from_location[0] < start_row else (from_location[0] - start_row)
+ row = 1 if from_location[0] < start_row else (from_location[0] - start_row)
col = 1 if (start_row != from_location[0]) else (from_location[1] - start_col)
start = (row, col)
- row = 1 if to_location[0] < start_row else (to_location[0] - start_row)
+ row = 1 if to_location[0] < start_row else (to_location[0] - start_row)
col = 1 if (start_row != to_location[0]) else (to_location[1] - start_col)
end = (row, col)
-
+
if self.AppFrame is not None:
self.AppFrame.ShowError(infos, start, end)
@@ -1198,7 +1198,7 @@
except:
text = '(* No IEC code have been generated at that time ! *)'
self._IECCodeView.SetText(text = text)
- self._IECCodeView.Editor.SetReadOnly(True)
+ self._IECCodeView.Editor.SetReadOnly(True)
self._IECCodeView.SetIcon(GetBitmap("ST"))
setattr(self._IECCodeView, "_OnClose", self.OnCloseEditor)
@@ -1305,11 +1305,11 @@
self.ShowMethod("_showIECcode", os.path.isfile(self._getIECcodepath()))
if self.AppFrame is not None and not self.UpdateMethodsFromPLCStatus():
self.AppFrame.RefreshStatusToolBar()
-
+
def UpdateButtons(self):
wx.CallAfter(self._UpdateButtons)
-
+
def UpdatePLCLog(self, log_count):
if log_count:
if self.AppFrame is not None:
@@ -1364,7 +1364,7 @@
"Disconnected": _("Disconnected")
}
return msgs.get(status, status)
-
+
def ShowPLCProgress(self, status = "", progress = 0):
self.AppFrame.ProgressStatusBar.Show()
self.AppFrame.ConnectionStatusBar.SetStatusText(self.GetTextStatus(status), 1)
@@ -1376,7 +1376,7 @@
self.previous_plcstate = ""
self.AppFrame.ProgressStatusBar.Hide()
self.UpdateMethodsFromPLCStatus()
-
+
def PullPLCStatusProc(self, event):
self.UpdateMethodsFromPLCStatus()
@@ -1821,7 +1821,7 @@
self.AppFrame.LogViewer.ResetLogCounters();
else:
self.logger.write_error(_("Transfer failed\n"))
- self.HidePLCProgress()
+ self.HidePLCProgress()
else:
self.logger.write_error(_("No PLC to transfer (did build succeed ?)\n"))
--- a/c_ext/CFileEditor.py Fri Aug 11 15:18:19 2017 +0300
+++ b/c_ext/CFileEditor.py Mon Aug 14 19:13:01 2017 +0300
@@ -29,20 +29,20 @@
class CppEditor(CodeEditor):
- KEYWORDS = ["asm", "auto", "bool", "break", "case", "catch", "char", "class",
- "const", "const_cast", "continue", "default", "delete", "do", "double",
- "dynamic_cast", "else", "enum", "explicit", "export", "extern", "false",
- "float", "for", "friend", "goto", "if", "inline", "int", "long", "mutable",
- "namespace", "new", "operator", "private", "protected", "public", "register",
- "reinterpret_cast", "return", "short", "signed", "sizeof", "static",
+ KEYWORDS = ["asm", "auto", "bool", "break", "case", "catch", "char", "class",
+ "const", "const_cast", "continue", "default", "delete", "do", "double",
+ "dynamic_cast", "else", "enum", "explicit", "export", "extern", "false",
+ "float", "for", "friend", "goto", "if", "inline", "int", "long", "mutable",
+ "namespace", "new", "operator", "private", "protected", "public", "register",
+ "reinterpret_cast", "return", "short", "signed", "sizeof", "static",
"static_cast", "struct", "switch", "template", "this", "throw", "true", "try",
- "typedef", "typeid", "typename", "union", "unsigned", "using", "virtual",
+ "typedef", "typeid", "typename", "union", "unsigned", "using", "virtual",
"void", "volatile", "wchar_t", "while"]
COMMENT_HEADER = "/"
-
+
def SetCodeLexer(self):
self.SetLexer(stc.STC_LEX_CPP)
-
+
self.StyleSetSpec(stc.STC_C_COMMENT, 'fore:#408060,size:%(size)d' % faces)
self.StyleSetSpec(stc.STC_C_COMMENTLINE, 'fore:#408060,size:%(size)d' % faces)
self.StyleSetSpec(stc.STC_C_COMMENTDOC, 'fore:#408060,size:%(size)d' % faces)
@@ -58,10 +58,7 @@
#-------------------------------------------------------------------------------
class CFileEditor(CodeFileEditor):
-
+
CONFNODEEDITOR_TABS = [
(_("C code"), "_create_CodePanel")]
CODE_EDITOR = CppEditor
-
-
-
--- a/canfestival/NetworkEditor.py Fri Aug 11 15:18:19 2017 +0300
+++ b/canfestival/NetworkEditor.py Mon Aug 14 19:13:01 2017 +0300
@@ -28,16 +28,16 @@
from networkeditortemplate import NetworkEditorTemplate
from editors.ConfTreeNodeEditor import ConfTreeNodeEditor
-[ID_NETWORKEDITOR,
+[ID_NETWORKEDITOR,
] = [wx.NewId() for _init_ctrls in range(1)]
-[ID_NETWORKEDITORCONFNODEMENUADDSLAVE, ID_NETWORKEDITORCONFNODEMENUREMOVESLAVE,
- ID_NETWORKEDITORCONFNODEMENUMASTER,
+[ID_NETWORKEDITORCONFNODEMENUADDSLAVE, ID_NETWORKEDITORCONFNODEMENUREMOVESLAVE,
+ ID_NETWORKEDITORCONFNODEMENUMASTER,
] = [wx.NewId() for _init_coll_ConfNodeMenu_Items in range(3)]
[ID_NETWORKEDITORMASTERMENUNODEINFOS, ID_NETWORKEDITORMASTERMENUDS301PROFILE,
ID_NETWORKEDITORMASTERMENUDS302PROFILE, ID_NETWORKEDITORMASTERMENUDSOTHERPROFILE,
- ID_NETWORKEDITORMASTERMENUADD,
+ ID_NETWORKEDITORMASTERMENUADD,
] = [wx.NewId() for _init_coll_MasterMenu_Items in range(5)]
[ID_NETWORKEDITORADDMENUSDOSERVER, ID_NETWORKEDITORADDMENUSDOCLIENT,
@@ -46,37 +46,37 @@
] = [wx.NewId() for _init_coll_AddMenu_Items in range(6)]
class NetworkEditor(ConfTreeNodeEditor, NetworkEditorTemplate):
-
+
ID = ID_NETWORKEDITOR
CONFNODEEDITOR_TABS = [
(_("CANOpen network"), "_create_NetworkEditor")]
-
+
def _create_NetworkEditor(self, prnt):
- self.NetworkEditor = wx.Panel(id=-1, parent=prnt, pos=wx.Point(0, 0),
+ self.NetworkEditor = wx.Panel(id=-1, parent=prnt, pos=wx.Point(0, 0),
size=wx.Size(0, 0), style=wx.TAB_TRAVERSAL)
-
+
NetworkEditorTemplate._init_ctrls(self, self.NetworkEditor)
-
+
main_sizer = wx.FlexGridSizer(cols=1, hgap=0, rows=1, vgap=0)
main_sizer.AddGrowableCol(0)
main_sizer.AddGrowableRow(0)
-
+
main_sizer.AddWindow(self.NetworkNodes, 0, border=5, flag=wx.GROW|wx.ALL)
-
+
self.NetworkEditor.SetSizer(main_sizer)
-
+
return self.NetworkEditor
-
+
def __init__(self, parent, controler, window):
ConfTreeNodeEditor.__init__(self, parent, controler, window)
NetworkEditorTemplate.__init__(self, controler, window, False)
-
+
self.RefreshNetworkNodes()
self.RefreshBufferState()
-
+
def __del__(self):
self.Controler.OnCloseEditor(self)
-
+
def GetConfNodeMenuItems(self):
add_menu = [(wx.ITEM_NORMAL, (_('SDO Server'), ID_NETWORKEDITORADDMENUSDOSERVER, '', self.OnAddSDOServerMenu)),
(wx.ITEM_NORMAL, (_('SDO Client'), ID_NETWORKEDITORADDMENUSDOCLIENT, '', self.OnAddSDOClientMenu)),
@@ -84,7 +84,7 @@
(wx.ITEM_NORMAL, (_('PDO Receive'), ID_NETWORKEDITORADDMENUPDORECEIVE, '', self.OnAddPDOReceiveMenu)),
(wx.ITEM_NORMAL, (_('Map Variable'), ID_NETWORKEDITORADDMENUMAPVARIABLE, '', self.OnAddMapVariableMenu)),
(wx.ITEM_NORMAL, (_('User Type'), ID_NETWORKEDITORADDMENUUSERTYPE, '', self.OnAddUserTypeMenu))]
-
+
profile = self.Manager.GetCurrentProfileName()
if profile not in ("None", "DS-301"):
other_profile_text = _("%s Profile") % profile
@@ -93,35 +93,35 @@
add_menu.append((wx.ITEM_NORMAL, (text, wx.NewId(), '', self.GetProfileCallBack(text))))
else:
other_profile_text = _('Other Profile')
-
+
master_menu = [(wx.ITEM_NORMAL, (_('DS-301 Profile'), ID_NETWORKEDITORMASTERMENUDS301PROFILE, '', self.OnCommunicationMenu)),
(wx.ITEM_NORMAL, (_('DS-302 Profile'), ID_NETWORKEDITORMASTERMENUDS302PROFILE, '', self.OnOtherCommunicationMenu)),
(wx.ITEM_NORMAL, (other_profile_text, ID_NETWORKEDITORMASTERMENUDSOTHERPROFILE, '', self.OnEditProfileMenu)),
(wx.ITEM_SEPARATOR, None),
(add_menu, (_('Add'), ID_NETWORKEDITORMASTERMENUADD))]
-
+
return [(wx.ITEM_NORMAL, (_('Add slave'), ID_NETWORKEDITORCONFNODEMENUADDSLAVE, '', self.OnAddSlaveMenu)),
(wx.ITEM_NORMAL, (_('Remove slave'), ID_NETWORKEDITORCONFNODEMENUREMOVESLAVE, '', self.OnRemoveSlaveMenu)),
(wx.ITEM_SEPARATOR, None),
(master_menu, (_('Master'), ID_NETWORKEDITORCONFNODEMENUMASTER))]
-
+
def RefreshMainMenu(self):
pass
-
+
def RefreshConfNodeMenu(self, confnode_menu):
confnode_menu.Enable(ID_NETWORKEDITORCONFNODEMENUMASTER, self.NetworkNodes.GetSelection() == 0)
-
+
def RefreshView(self):
ConfTreeNodeEditor.RefreshView(self)
self.RefreshCurrentIndexList()
-
+
def RefreshBufferState(self):
NetworkEditorTemplate.RefreshBufferState(self)
self.ParentWindow.RefreshTitle()
self.ParentWindow.RefreshFileMenu()
self.ParentWindow.RefreshEditMenu()
self.ParentWindow.RefreshPageTitles()
-
+
def OnNodeSelectedChanged(self, event):
NetworkEditorTemplate.OnNodeSelectedChanged(self, event)
wx.CallAfter(self.ParentWindow.RefreshEditMenu)
--- a/canfestival/SlaveEditor.py Fri Aug 11 15:18:19 2017 +0300
+++ b/canfestival/SlaveEditor.py Mon Aug 14 19:13:01 2017 +0300
@@ -30,7 +30,7 @@
[ID_SLAVEEDITORCONFNODEMENUNODEINFOS, ID_SLAVEEDITORCONFNODEMENUDS301PROFILE,
ID_SLAVEEDITORCONFNODEMENUDS302PROFILE, ID_SLAVEEDITORCONFNODEMENUDSOTHERPROFILE,
- ID_SLAVEEDITORCONFNODEMENUADD,
+ ID_SLAVEEDITORCONFNODEMENUADD,
] = [wx.NewId() for _init_coll_ConfNodeMenu_Items in range(5)]
[ID_SLAVEEDITORADDMENUSDOSERVER, ID_SLAVEEDITORADDMENUSDOCLIENT,
@@ -39,22 +39,22 @@
] = [wx.NewId() for _init_coll_AddMenu_Items in range(6)]
class SlaveEditor(ConfTreeNodeEditor, NodeEditorTemplate):
-
+
CONFNODEEDITOR_TABS = [
(_("CANOpen slave"), "_create_SlaveNodeEditor")]
-
+
def _create_SlaveNodeEditor(self, prnt):
self.SlaveNodeEditor = EditingPanel(prnt, self, self.Controler, self.Editable)
return self.SlaveNodeEditor
-
+
def __init__(self, parent, controler, window, editable=True):
self.Editable = editable
ConfTreeNodeEditor.__init__(self, parent, controler, window)
NodeEditorTemplate.__init__(self, controler, window, False)
-
+
def __del__(self):
self.Controler.OnCloseEditor(self)
-
+
def GetConfNodeMenuItems(self):
if self.Editable:
add_menu = [(wx.ITEM_NORMAL, (_('SDO Server'), ID_SLAVEEDITORADDMENUSDOSERVER, '', self.OnAddSDOServerMenu)),
@@ -63,7 +63,7 @@
(wx.ITEM_NORMAL, (_('PDO Receive'), ID_SLAVEEDITORADDMENUPDORECEIVE, '', self.OnAddPDOReceiveMenu)),
(wx.ITEM_NORMAL, (_('Map Variable'), ID_SLAVEEDITORADDMENUMAPVARIABLE, '', self.OnAddMapVariableMenu)),
(wx.ITEM_NORMAL, (_('User Type'), ID_SLAVEEDITORADDMENUUSERTYPE, '', self.OnAddUserTypeMenu))]
-
+
profile = self.Controler.GetCurrentProfileName()
if profile not in ("None", "DS-301"):
other_profile_text = _("%s Profile") % profile
@@ -72,14 +72,14 @@
add_menu.append((wx.ITEM_NORMAL, (text, wx.NewId(), '', self.GetProfileCallBack(text))))
else:
other_profile_text = _('Other Profile')
-
+
return [(wx.ITEM_NORMAL, (_('DS-301 Profile'), ID_SLAVEEDITORCONFNODEMENUDS301PROFILE, '', self.OnCommunicationMenu)),
(wx.ITEM_NORMAL, (_('DS-302 Profile'), ID_SLAVEEDITORCONFNODEMENUDS302PROFILE, '', self.OnOtherCommunicationMenu)),
(wx.ITEM_NORMAL, (other_profile_text, ID_SLAVEEDITORCONFNODEMENUDSOTHERPROFILE, '', self.OnEditProfileMenu)),
(wx.ITEM_SEPARATOR, None),
(add_menu, (_('Add'), ID_SLAVEEDITORCONFNODEMENUADD))]
return []
-
+
def RefreshConfNodeMenu(self, confnode_menu):
if self.Editable:
confnode_menu.Enable(ID_SLAVEEDITORCONFNODEMENUDSOTHERPROFILE, False)
@@ -90,7 +90,7 @@
def RefreshCurrentIndexList(self):
self.RefreshView()
-
+
def RefreshBufferState(self):
self.ParentWindow.RefreshTitle()
self.ParentWindow.RefreshFileMenu()
@@ -100,27 +100,26 @@
class MasterViewer(SlaveEditor):
SHOW_BASE_PARAMS = False
SHOW_PARAMS = False
-
+
def __init__(self, parent, controler, window, tagname):
SlaveEditor.__init__(self, parent, controler, window, False)
-
+
self.TagName = tagname
-
+
def GetTagName(self):
return self.TagName
-
+
def GetCurrentNodeId(self):
return None
-
+
def GetInstancePath(self):
return self.Controler.CTNFullName() + ".generated_master"
-
+
def GetTitle(self):
return self.GetInstancePath()
-
+
def IsViewing(self, tagname):
return self.GetInstancePath() == tagname
def RefreshView(self):
self.SlaveNodeEditor.RefreshIndexList()
-
--- a/canfestival/canfestival.py Fri Aug 11 15:18:19 2017 +0300
+++ b/canfestival/canfestival.py Mon Aug 14 19:13:01 2017 +0300
@@ -67,7 +67,7 @@
"size": size,
"IEC_type": IECTypeConversion.get(typeinfos["name"]),
"var_name": "%s_%4.4x_%2.2x" % ("_".join(name.split()), index, subindex),
- "location": "%s%s"%(SizeConversion[size], ".".join(map(str, current_location +
+ "location": "%s%s"%(SizeConversion[size], ".".join(map(str, current_location +
(index, subindex)))),
"description": "",
"children": []})
@@ -102,7 +102,7 @@
</xsd:element>
</xsd:schema>
"""
-
+
EditorType = SlaveEditor
IconPath = os.path.join(CanFestivalPath, "objdictgen", "networkedit.png")
@@ -125,7 +125,7 @@
self.CreateNewNode(name, # Name - will be changed at build time
id, # NodeID - will be changed at build time
"slave", # Type
- description,# description
+ description,# description
profile, # profile
filepath, # prfile filepath
NMT, # NMT
@@ -134,7 +134,7 @@
self.CreateNewNode("SlaveNode", # Name - will be changed at build time
0x00, # NodeID - will be changed at build time
"slave", # Type
- "", # description
+ "", # description
"None", # profile
"", # prfile filepath
"heartbeat", # NMT
@@ -156,48 +156,48 @@
if self._View is not None:
self._View.SetBusId(self.GetCurrentLocation())
return self._View
-
+
def _ExportSlave(self):
- dialog = wx.FileDialog(self.GetCTRoot().AppFrame,
- _("Choose a file"),
- os.path.expanduser("~"),
- "%s.eds" % self.CTNName(),
+ dialog = wx.FileDialog(self.GetCTRoot().AppFrame,
+ _("Choose a file"),
+ os.path.expanduser("~"),
+ "%s.eds" % self.CTNName(),
_("EDS files (*.eds)|*.eds|All files|*.*"),
wx.SAVE|wx.OVERWRITE_PROMPT)
if dialog.ShowModal() == wx.ID_OK:
result = eds_utils.GenerateEDSFile(dialog.GetPath(), self.GetCurrentNodeCopy())
if result:
self.GetCTRoot().logger.write_error(_("Error: Export slave failed\n"))
- dialog.Destroy()
-
+ dialog.Destroy()
+
ConfNodeMethods = [
{"bitmap" : "ExportSlave",
- "name" : _("Export slave"),
+ "name" : _("Export slave"),
"tooltip" : _("Export CanOpen slave to EDS file"),
"method" : "_ExportSlave"},
]
-
+
def CTNTestModified(self):
return self.ChangesToSave or self.OneFileHasChanged()
-
+
def OnCTNSave(self, from_project_path=None):
return self.SaveCurrentInFile(self.GetSlaveODPath())
def SetParamsAttribute(self, path, value):
result = ConfigTreeNode.SetParamsAttribute(self, path, value)
-
+
# Filter IEC_Channel and Name, that have specific behavior
if path == "BaseParams.IEC_Channel" and self._View is not None:
self._View.SetBusId(self.GetCurrentLocation())
-
+
return result
-
+
def GetVariableLocationTree(self):
current_location = self.GetCurrentLocation()
- return GetSlaveLocationTree(self.CurrentNode,
- self.GetCurrentLocation(),
+ return GetSlaveLocationTree(self.CurrentNode,
+ self.GetCurrentLocation(),
self.BaseParams.getName())
-
+
def CTNGenerate_C(self, buildpath, locations):
"""
Generate C code
@@ -230,10 +230,10 @@
def LoadPrevious(self):
self.LoadCurrentPrevious()
-
+
def LoadNext(self):
self.LoadCurrentNext()
-
+
def GetBufferState(self):
return self.GetCurrentBufferState()
@@ -242,30 +242,30 @@
#--------------------------------------------------
class MiniNodeManager(NodeManager):
-
+
def __init__(self, parent, filepath, fullname):
NodeManager.__init__(self)
-
+
self.OpenFileInCurrent(filepath)
-
+
self.Parent = parent
self.Fullname = fullname
-
+
def GetIconName(self):
return None
-
+
def OnCloseEditor(self, view):
self.Parent.OnCloseEditor(view)
-
+
def CTNFullName(self):
return self.Fullname
-
+
def CTNTestModified(self):
return False
-
+
def GetBufferState(self):
return self.GetCurrentBufferState()
-
+
ConfNodeMethods = []
class _NodeManager(NodeManager):
@@ -273,16 +273,16 @@
def __init__(self, parent, *args, **kwargs):
NodeManager.__init__(self, *args, **kwargs)
self.Parent = parent
-
+
def __del__(self):
self.Parent = None
-
+
def GetCurrentNodeName(self):
return self.Parent.CTNName()
-
+
def GetCurrentNodeID(self):
return self.Parent.CanFestivalNode.getNodeId()
-
+
class _NodeListCTN(NodeList):
XSD = """<?xml version="1.0" encoding="ISO-8859-1" ?>
<xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema">
@@ -295,20 +295,20 @@
</xsd:complexType>
</xsd:element>
</xsd:schema>
- """
-
+ """
+
EditorType = NetworkEditor
IconPath = os.path.join(CanFestivalPath, "objdictgen", "networkedit.png")
-
+
def __init__(self):
manager = _NodeManager(self)
NodeList.__init__(self, manager)
self.LoadProject(self.CTNPath())
self.SetNetworkName(self.BaseParams.getName())
-
+
def GetCanDevice(self):
return self.CanFestivalNode.getCAN_Device()
-
+
def SetParamsAttribute(self, path, value):
if path == "CanFestivalNode.NodeId":
nodeid = self.CanFestivalNode.getNodeId()
@@ -319,10 +319,10 @@
value += dir
if value < 0:
value = nodeid
-
+
value, refresh = ConfigTreeNode.SetParamsAttribute(self, path, value)
refresh_network = False
-
+
# Filter IEC_Channel and Name, that have specific behavior
if path == "BaseParams.IEC_Channel" and self._View is not None:
self._View.SetBusId(self.GetCurrentLocation())
@@ -331,11 +331,11 @@
refresh_network = True
elif path == "CanFestivalNode.NodeId":
refresh_network = True
-
+
if refresh_network and self._View is not None:
wx.CallAfter(self._View.RefreshBufferState)
return value, refresh
-
+
def GetVariableLocationTree(self):
current_location = self.GetCurrentLocation()
nodeindexes = self.SlaveNodes.keys()
@@ -345,17 +345,17 @@
"location": self.GetFullIEC_Channel(),
"children": [GetSlaveLocationTree(self.Manager.GetCurrentNodeCopy(),
current_location,
- _("Local entries"))] +
- [GetSlaveLocationTree(self.SlaveNodes[nodeid]["Node"],
- current_location + (nodeid,),
+ _("Local entries"))] +
+ [GetSlaveLocationTree(self.SlaveNodes[nodeid]["Node"],
+ current_location + (nodeid,),
self.SlaveNodes[nodeid]["Name"])
for nodeid in nodeindexes]
}
-
+
_GeneratedMasterView = None
def _ShowGeneratedMaster(self):
self._OpenView("Generated master")
-
+
def _OpenView(self, name=None, onlyopened=False):
if name == "Generated master":
app_frame = self.GetCTRoot().AppFrame
@@ -365,37 +365,37 @@
if not os.path.exists(buildpath):
self.GetCTRoot().logger.write_error(_("Error: No PLC built\n"))
return
-
+
masterpath = os.path.join(buildpath, "MasterGenerated.od")
if not os.path.exists(masterpath):
self.GetCTRoot().logger.write_error(_("Error: No Master generated\n"))
return
-
+
manager = MiniNodeManager(self, masterpath, self.CTNFullName())
self._GeneratedMasterView = MasterViewer(app_frame.TabsOpened, manager, app_frame, name)
-
+
if self._GeneratedMasterView is not None:
app_frame.EditProjectElement(self._GeneratedMasterView, self._GeneratedMasterView.GetInstancePath())
-
+
return self._GeneratedMasterView
else:
ConfigTreeNode._OpenView(self, name, onlyopened)
if self._View is not None:
self._View.SetBusId(self.GetCurrentLocation())
return self._View
-
+
ConfNodeMethods = [
{"bitmap" : "ShowMaster",
- "name" : _("Show Master"),
+ "name" : _("Show Master"),
"tooltip" : _("Show Master generated by config_utils"),
"method" : "_ShowGeneratedMaster"}
]
-
+
def OnCloseEditor(self, view):
ConfigTreeNode.OnCloseEditor(self, view)
if self._GeneratedMasterView == view:
self._GeneratedMasterView = None
-
+
def OnCTNClose(self):
ConfigTreeNode.OnCTNClose(self)
self._CloseView(self._GeneratedMasterView)
@@ -403,11 +403,11 @@
def CTNTestModified(self):
return self.ChangesToSave or self.HasChanged()
-
+
def OnCTNSave(self, from_project_path=None):
self.SetRoot(self.CTNPath())
if from_project_path is not None:
- shutil.copytree(self.GetEDSFolder(from_project_path),
+ shutil.copytree(self.GetEDSFolder(from_project_path),
self.GetEDSFolder())
return self.SaveProject() is None
@@ -438,22 +438,22 @@
res = gen_cfile.GenerateFile(Gen_OD_path, master, pointers)
if res :
raise Exception, res
-
+
file = open(os.path.join(buildpath, "MasterGenerated.od"), "w")
dump(master, file)
file.close()
-
+
return [(Gen_OD_path,local_canfestival_config.getCFLAGS(CanFestivalPath))],"",False
-
+
def LoadPrevious(self):
self.Manager.LoadCurrentPrevious()
-
+
def LoadNext(self):
self.Manager.LoadCurrentNext()
-
+
def GetBufferState(self):
return self.Manager.GetCurrentBufferState()
-
+
class RootClass:
XSD = """<?xml version="1.0" encoding="ISO-8859-1" ?>
<xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema">
@@ -464,7 +464,7 @@
</xsd:element>
</xsd:schema>
"""
-
+
CTNChildrenTypes = [("CanOpenNode",_NodeListCTN, "CanOpen Master"),
("CanOpenSlave",_SlaveCTN, "CanOpen Slave")]
def GetParamsAttributes(self, path = None):
@@ -475,13 +475,13 @@
if child["name"] == "CAN_Driver":
child["type"] = local_canfestival_config.DLL_LIST
return infos
-
+
def GetCanDriver(self):
res = self.CanFestivalInstance.getCAN_Driver()
if not res :
return ""
return res
-
+
def CTNGenerate_C(self, buildpath, locations):
can_driver = self.GetCanDriver()
if can_driver is not None:
@@ -494,7 +494,7 @@
else:
can_driver_name = ""
-
+
format_dict = {"locstr" : "_".join(map(str,self.GetCurrentLocation())),
"candriver" : can_driver_name,
"nodes_includes" : "",
@@ -515,7 +515,7 @@
for child in self.IECSortedChildren():
childlocstr = "_".join(map(str,child.GetCurrentLocation()))
nodename = "OD_%s" % childlocstr
-
+
# Try to get Slave Node
child_data = getattr(child, "CanFestivalSlaveNode", None)
if child_data is None:
@@ -569,7 +569,7 @@
format_dict["nodes_init"] += 'NODE_SLAVE_INIT(%s, %s)\n '%(
nodename,
child_data.getNodeId())
-
+
# Include generated OD headers
format_dict["nodes_includes"] += '#include "%s.h"\n'%(nodename)
# Declare CAN channels according user filled config
@@ -580,7 +580,7 @@
format_dict["nodes_open"] += 'NODE_OPEN(%s)\n '%(nodename)
format_dict["nodes_close"] += 'NODE_CLOSE(%s)\n '%(nodename)
format_dict["nodes_stop"] += 'NODE_STOP(%s)\n '%(nodename)
-
+
filename = paths.AbsNeighbourFile(__file__,"cf_runtime.c")
cf_main = open(filename).read() % format_dict
cf_main_path = os.path.join(buildpath, "CF_%(locstr)s.c"%format_dict)
@@ -589,11 +589,10 @@
f.close()
res = [(cf_main_path, local_canfestival_config.getCFLAGS(CanFestivalPath))],local_canfestival_config.getLDFLAGS(CanFestivalPath), True
-
+
if can_driver is not None:
can_driver_path = os.path.join(CanFestivalPath,"drivers",can_driver,can_driver_name)
if os.path.exists(can_driver_path):
res += ((can_driver_name, file(can_driver_path,"rb")),)
return res
-
--- a/canfestival/config_utils.py Fri Aug 11 15:18:19 2017 +0300
+++ b/canfestival/config_utils.py Mon Aug 14 19:13:01 2017 +0300
@@ -30,7 +30,7 @@
"LREAL":0x11,"STRING":0x09,"BYTE":0x05,"WORD":0x06,"DWORD":0x07,
"LWORD":0x1B,"WSTRING":0x0B}
-# Constants for PDO types
+# Constants for PDO types
RPDO = 1
TPDO = 2
@@ -61,7 +61,7 @@
@param size: number of bytes generated
@return: a string containing the value converted
"""
-
+
data = ("%" + str(size * 2) + "." + str(size * 2) + "X") % value
list_car = [data[i:i+2] for i in xrange(0, len(data), 2)]
list_car.reverse()
@@ -71,12 +71,12 @@
def GetNodePDOIndexes(node, type, parameters = False):
"""
Find the PDO indexes of a node
- @param node: node
+ @param node: node
@param type: type of PDO searched (RPDO or TPDO or both)
@param parameters: indicate which indexes are expected (PDO paramaters : True or PDO mappings : False)
@return: a list of indexes found
"""
-
+
indexes = []
if type & RPDO:
indexes.extend([idx for idx in node.GetIndexes() if 0x1400 <= idx <= 0x15FF])
@@ -91,14 +91,14 @@
def SearchNodePDOMapping(loc_infos, node):
"""
Find the PDO indexes of a node
- @param node: node
+ @param node: node
@param type: type of PDO searched (RPDO or TPDO or both)
@param parameters: indicate which indexes are expected (PDO paramaters : True or PDO mappings : False)
@return: a list of indexes found
"""
-
+
model = (loc_infos["index"] << 16) + (loc_infos["subindex"] << 8)
-
+
for PDOidx in GetNodePDOIndexes(node, loc_infos["pdotype"]):
values = node.GetEntry(PDOidx)
if values != None:
@@ -115,9 +115,9 @@
@param cobid: PDO generated COB ID
@param transmittype : PDO transmit type
@param pdomapping: list of PDO mappings
- @return: a tuple of value and number of parameters to add to DCF
- """
-
+ @return: a tuple of value and number of parameters to add to DCF
+ """
+
dcfdata=[]
# Create entry for RPDO or TPDO parameters and Disable PDO
# ---- INDEX ----- --- SUBINDEX ---- ----- SIZE ------ ------ DATA ------
@@ -152,7 +152,7 @@
self.TrashVariables = {}
# Dictionary of pointed variables
self.PointedVariables = {}
-
+
self.NodeList = nodelist
self.Manager = self.NodeList.Manager
self.MasterNode = self.Manager.GetCurrentNodeCopy()
@@ -161,18 +161,18 @@
def GetPointedVariables(self):
return self.PointedVariables
-
+
def RemoveUsedNodeCobId(self, node):
"""
Remove all PDO COB ID used by the given node from the list of available COB ID
@param node: node
@return: a tuple of number of RPDO and TPDO for the node
"""
-
+
# Get list of all node TPDO and RPDO indexes
nodeRpdoIndexes = GetNodePDOIndexes(node, RPDO, True)
nodeTpdoIndexes = GetNodePDOIndexes(node, TPDO, True)
-
+
# Mark all the COB ID of the node already mapped PDO as not available
for PdoIdx in nodeRpdoIndexes + nodeTpdoIndexes:
pdo_cobid = node.GetEntry(PdoIdx, 0x01)
@@ -182,20 +182,20 @@
# Remove COB ID from the list of available COB ID
if pdo_cobid in self.ListCobIDAvailable:
self.ListCobIDAvailable.remove(pdo_cobid)
-
+
return len(nodeRpdoIndexes), len(nodeTpdoIndexes)
-
+
def PrepareMasterNode(self):
"""
Add mandatory entries for DCF generation into MasterNode.
"""
-
+
# Adding DCF entry into Master node
if not self.MasterNode.IsEntry(0x1F22):
self.MasterNode.AddEntry(0x1F22, 1, "")
self.Manager.AddSubentriesToCurrent(0x1F22, 127, self.MasterNode)
-
+
# Adding trash mappable variables for unused mapped datas
idxTrashVariables = 0x2000 + self.MasterNode.GetNodeID()
# Add an entry for storing unexpected all variable
@@ -206,9 +206,9 @@
self.Manager.SetCurrentEntry(idxTrashVariables, subidx + 1, typeidx, "type", None, self.MasterNode)
# Store the mapping value for this entry
self.TrashVariables[size] = (idxTrashVariables << 16) + ((subidx + 1) << 8) + size
-
+
RPDOnumber, TPDOnumber = self.RemoveUsedNodeCobId(self.MasterNode)
-
+
# Store the indexes of the first RPDO and TPDO available for MasterNode
self.CurrentPDOParamsIdx = {RPDO : 0x1400 + RPDOnumber, TPDO : 0x1800 + TPDOnumber}
@@ -216,9 +216,9 @@
for idx, (nodeid, nodeinfos) in enumerate(self.NodeList.SlaveNodes.items()):
node = nodeinfos["Node"]
node.SetNodeID(nodeid)
-
+
RPDOnumber, TPDOnumber = self.RemoveUsedNodeCobId(node)
-
+
# Get Slave's default SDO server parameters
RSDO_cobid = node.GetEntry(0x1200,0x01)
if not RSDO_cobid:
@@ -226,20 +226,20 @@
TSDO_cobid = node.GetEntry(0x1200,0x02)
if not TSDO_cobid:
TSDO_cobid = 0x580 + nodeid
-
+
# Configure Master's SDO parameters entries
self.Manager.ManageEntriesOfCurrent([0x1280 + idx], [], self.MasterNode)
self.MasterNode.SetEntry(0x1280 + idx, 0x01, RSDO_cobid)
self.MasterNode.SetEntry(0x1280 + idx, 0x02, TSDO_cobid)
- self.MasterNode.SetEntry(0x1280 + idx, 0x03, nodeid)
-
-
+ self.MasterNode.SetEntry(0x1280 + idx, 0x03, nodeid)
+
+
def GetMasterNode(self):
"""
Return MasterNode.
"""
return self.MasterNode
-
+
def AddParamsToDCF(self, nodeid, data, nbparams):
"""
Add entry to DCF, for the requested nodeID
@@ -249,19 +249,19 @@
"""
# Get current DCF for slave
nodeDCF = self.MasterNode.GetEntry(0x1F22, nodeid)
-
+
# Extract data and number of params in current DCF
if nodeDCF != None and nodeDCF != '':
tmpnbparams = [i for i in nodeDCF[:4]]
tmpnbparams.reverse()
nbparams += int(''.join(["%2.2x"%ord(i) for i in tmpnbparams]), 16)
data = nodeDCF[4:] + data
-
+
# Build new DCF
dcf = LE_to_BE(nbparams, 0x04) + data
# Set new DCF for slave
self.MasterNode.SetEntry(0x1F22, nodeid, dcf)
-
+
def GetEmptyPDO(self, nodeid, pdotype, start_index=None):
"""
Search a not configured PDO for a slave
@@ -275,7 +275,7 @@
index = PDOTypeBaseIndex[pdotype]
else:
index = start_index
-
+
# Search for all PDO possible index until find a configurable PDO
# starting from start_index
while index < PDOTypeBaseIndex[pdotype] + 0x200:
@@ -296,7 +296,7 @@
return index, cobid, values[0]
index += 1
return None
-
+
def AddPDOMapping(self, nodeid, pdotype, pdoindex, pdocobid, pdomapping, sync_TPDOs):
"""
Record a new mapping request for a slave, and add related slave config to the DCF
@@ -305,16 +305,16 @@
@param pdomapping: list od variables to map with PDO
"""
# Add an entry to MasterMapping
- self.MasterMapping[pdocobid] = {"type" : InvertPDOType[pdotype],
+ self.MasterMapping[pdocobid] = {"type" : InvertPDOType[pdotype],
"mapping" : [None] + [(loc_infos["type"], name) for name, loc_infos in pdomapping]}
-
+
# Return the data to add to DCF
if sync_TPDOs:
return GeneratePDOMappingDCF(pdoindex, pdocobid, 0x01, pdomapping)
else:
return GeneratePDOMappingDCF(pdoindex, pdocobid, 0xFF, pdomapping)
return 0, ""
-
+
def GenerateDCF(self, locations, current_location, sync_TPDOs):
"""
Generate Concise DCF of MasterNode for the locations list given
@@ -322,18 +322,18 @@
@param current_location: tuple of the located prefixes not to be considered
@param sync_TPDOs: indicate if TPDO must be synchronous
"""
-
+
#-------------------------------------------------------------------------------
# Verify that locations correspond to real slave variables
#-------------------------------------------------------------------------------
-
+
# Get list of locations check if exists and mappables -> put them in IECLocations
for location in locations:
COlocationtype = IECToCOType[location["IEC_TYPE"]]
name = location["NAME"]
if name in self.IECLocations:
if self.IECLocations[name]["type"] != COlocationtype:
- raise PDOmappingException, _("Type conflict for location \"%s\"") % name
+ raise PDOmappingException, _("Type conflict for location \"%s\"") % name
else:
# Get only the part of the location that concern this node
loc = location["LOC"][len(current_location):]
@@ -342,30 +342,30 @@
raise PDOmappingException, _("Bad location size : %s") % str(loc)
elif len(loc) == 2:
continue
-
+
direction = location["DIR"]
-
+
sizelocation = location["SIZE"]
-
+
# Extract and check nodeid
nodeid, index, subindex = loc[:3]
-
+
# Check Id is in slave node list
if nodeid not in self.NodeList.SlaveNodes.keys():
raise PDOmappingException, _("Non existing node ID : {a1} (variable {a2})").format(a1 = nodeid, a2 = name)
-
+
# Get the model for this node (made from EDS)
node = self.NodeList.SlaveNodes[nodeid]["Node"]
-
+
# Extract and check index and subindex
if not node.IsEntry(index, subindex):
msg = _("No such index/subindex ({a1},{a2}) in ID : {a3} (variable {a4})").\
format(a1 = "%x" % index, a2 ="%x" % subindex, a3 = nodeid, a4 = name)
raise PDOmappingException, msg
-
+
# Get the entry info
subentry_infos = node.GetSubentryInfos(index, subindex)
-
+
# If a PDO mappable
if subentry_infos and subentry_infos["pdo"]:
if sizelocation == "X" and len(loc) > 3:
@@ -376,11 +376,11 @@
raise PDOmappingException, msg
else:
numbit = None
-
+
if location["IEC_TYPE"] != "BOOL" and subentry_infos["type"] != COlocationtype:
raise PDOmappingException, _("Invalid type \"{a1}\"-> {a2} != {a3} for location \"{a4}\"").\
format(a1 = location["IEC_TYPE"], a2 = COlocationtype, a3 = subentry_infos["type"] , a4 = name)
-
+
typeinfos = node.GetEntryInfos(COlocationtype)
self.IECLocations[name] = {"type":COlocationtype, "pdotype":SlavePDOType[direction],
"nodeid": nodeid, "index": index,"subindex": subindex,
@@ -388,21 +388,21 @@
else:
raise PDOmappingException, _("Not PDO mappable variable : '{a1}' (ID:{a2},Idx:{a3},sIdx:{a4}))").\
format(a1 = name, a2 = nodeid, a3 = "%x" % index, a4 = "%x" % subindex)
-
+
#-------------------------------------------------------------------------------
# Search for locations already mapped
#-------------------------------------------------------------------------------
-
+
for name, locationinfos in self.IECLocations.items():
node = self.NodeList.SlaveNodes[locationinfos["nodeid"]]["Node"]
-
+
# Search if slave has a PDO mapping this locations
result = SearchNodePDOMapping(locationinfos, node)
if result != None:
index, subindex = result
# Get COB ID of the PDO
cobid = self.NodeList.GetSlaveNodeEntry(locationinfos["nodeid"], index - 0x200, 1)
-
+
# Add PDO to MasterMapping
if cobid not in self.MasterMapping.keys():
# Verify that PDO transmit type is conform to sync_TPDOs
@@ -414,10 +414,10 @@
else:
# Change TransmitType to ASYCHRONE
data, nbparams = GeneratePDOMappingDCF(index - 0x200, cobid, 0xFF, [])
-
- # Add entry to slave dcf to change transmit type of
+
+ # Add entry to slave dcf to change transmit type of
self.AddParamsToDCF(locationinfos["nodeid"], data, nbparams)
-
+
mapping = [None]
values = node.GetEntry(index)
# Store the size of each entry mapped in PDO
@@ -425,7 +425,7 @@
if value != 0:
mapping.append(value % 0x100)
self.MasterMapping[cobid] = {"type" : InvertPDOType[locationinfos["pdotype"]], "mapping" : mapping}
-
+
# Indicate that this PDO entry must be saved
if locationinfos["bit"] is not None:
if not isinstance(self.MasterMapping[cobid]["mapping"][subindex], ListType):
@@ -434,24 +434,24 @@
self.MasterMapping[cobid]["mapping"][subindex][locationinfos["bit"]] = (locationinfos["type"], name)
else:
self.MasterMapping[cobid]["mapping"][subindex] = (locationinfos["type"], name)
-
+
else:
# Add location to those that haven't been mapped yet
if locationinfos["nodeid"] not in self.LocationsNotMapped.keys():
self.LocationsNotMapped[locationinfos["nodeid"]] = {TPDO : [], RPDO : []}
self.LocationsNotMapped[locationinfos["nodeid"]][locationinfos["pdotype"]].append((name, locationinfos))
-
+
#-------------------------------------------------------------------------------
# Build concise DCF for the others locations
#-------------------------------------------------------------------------------
-
+
for nodeid, locations in self.LocationsNotMapped.items():
node = self.NodeList.SlaveNodes[nodeid]["Node"]
-
+
# Initialize number of params and data to add to node DCF
nbparams = 0
dataparams = ""
-
+
# Generate the best PDO mapping for each type of PDO
for pdotype in (TPDO, RPDO):
if len(locations[pdotype]) > 0:
@@ -483,78 +483,78 @@
data, nbaddedparams = self.AddPDOMapping(nodeid, pdotype, pdoindex, pdocobid, pdomapping, sync_TPDOs)
dataparams += data
nbparams += nbaddedparams
-
+
# Add number of params and data to node DCF
self.AddParamsToDCF(nodeid, dataparams, nbparams)
-
+
#-------------------------------------------------------------------------------
# Master Node Configuration
#-------------------------------------------------------------------------------
-
+
# Generate Master's Configuration from informations stored in MasterMapping
for cobid, pdo_infos in self.MasterMapping.items():
# Get next PDO index in MasterNode for this PDO type
current_idx = self.CurrentPDOParamsIdx[pdo_infos["type"]]
-
+
# Search if there is already a PDO in MasterNode with this cob id
for idx in GetNodePDOIndexes(self.MasterNode, pdo_infos["type"], True):
if self.MasterNode.GetEntry(idx, 1) == cobid:
current_idx = idx
-
+
# Add a PDO to MasterNode if not PDO have been found
if current_idx == self.CurrentPDOParamsIdx[pdo_infos["type"]]:
addinglist = [current_idx, current_idx + 0x200]
self.Manager.ManageEntriesOfCurrent(addinglist, [], self.MasterNode)
self.MasterNode.SetEntry(current_idx, 0x01, cobid)
-
+
# Increment the number of PDO for this PDO type
self.CurrentPDOParamsIdx[pdo_infos["type"]] += 1
-
+
# Change the transmit type of the PDO
if sync_TPDOs:
self.MasterNode.SetEntry(current_idx, 0x02, 0x01)
else:
self.MasterNode.SetEntry(current_idx, 0x02, 0xFF)
-
+
mapping = []
for item in pdo_infos["mapping"]:
if isinstance(item, ListType):
mapping.extend(item)
else:
mapping.append(item)
-
+
# Add some subentries to PDO mapping if there is not enough
if len(mapping) > 1:
self.Manager.AddSubentriesToCurrent(current_idx + 0x200, len(mapping) - 1, self.MasterNode)
-
+
# Generate MasterNode's PDO mapping
for subindex, variable in enumerate(mapping):
if subindex == 0:
continue
new_index = False
-
+
if isinstance(variable, (IntType, LongType)):
# If variable is an integer then variable is unexpected
self.MasterNode.SetEntry(current_idx + 0x200, subindex, self.TrashVariables[variable])
else:
typeidx, varname = variable
variable_infos = self.IECLocations[varname]
-
+
# Calculate base index for storing variable
mapvariableidx = VariableStartIndex[variable_infos["pdotype"]] + \
VariableTypeOffset[variable_infos["sizelocation"]] * VariableIncrement + \
variable_infos["nodeid"]
-
+
# Generate entry name
indexname = "%s%s%s_%d"%(VariableDirText[variable_infos["pdotype"]],
variable_infos["sizelocation"],
'_'.join(map(str,current_location)),
- variable_infos["nodeid"])
-
- # Search for an entry that has an empty subindex
+ variable_infos["nodeid"])
+
+ # Search for an entry that has an empty subindex
while mapvariableidx < VariableStartIndex[variable_infos["pdotype"]] + 0x2000:
# Entry doesn't exist
- if not self.MasterNode.IsEntry(mapvariableidx):
+ if not self.MasterNode.IsEntry(mapvariableidx):
# Add entry to MasterNode
self.Manager.AddMapVariableToCurrent(mapvariableidx, "beremiz"+indexname, 3, 1, self.MasterNode)
new_index = True
@@ -567,7 +567,7 @@
mapvariableidx += 8 * VariableIncrement
else:
break
-
+
# Verify that a not full entry has been found
if mapvariableidx < VariableStartIndex[variable_infos["pdotype"]] + 0x2000:
# Generate subentry name
@@ -582,13 +582,13 @@
# Add informations to the new subentry created
self.MasterNode.SetMappingEntry(mapvariableidx, nbsubentries, values = {"name" : subindexname})
self.MasterNode.SetMappingEntry(mapvariableidx, nbsubentries, values = {"type" : typeidx})
-
+
# Set value of the PDO mapping
typeinfos = self.Manager.GetEntryInfos(typeidx)
if typeinfos != None:
value = (mapvariableidx << 16) + ((nbsubentries) << 8) + typeinfos["size"]
self.MasterNode.SetEntry(current_idx + 0x200, subindex, value)
-
+
# Add variable to pointed variables
self.PointedVariables[(mapvariableidx, nbsubentries)] = "%s_%s"%(indexname, subindexname)
@@ -605,7 +605,7 @@
@param nodelist: CanFestival network editor model
@return: a modified copy of the given CanFestival network editor model
"""
-
+
dcfgenerator = ConciseDCFGenerator(nodelist, nodename)
dcfgenerator.GenerateDCF(locations, current_location, sync_TPDOs)
masternode,pointers = dcfgenerator.GetMasterNode(), dcfgenerator.GetPointedVariables()
@@ -621,7 +621,7 @@
name = location["NAME"]
if name in IECLocations:
if IECLocations[name] != COlocationtype:
- raise PDOmappingException, _("Type conflict for location \"%s\"") % name
+ raise PDOmappingException, _("Type conflict for location \"%s\"") % name
else:
# Get only the part of the location that concern this node
loc = location["LOC"][len(current_location):]
@@ -630,25 +630,25 @@
raise PDOmappingException, _("Bad location size : %s") % str(loc)
elif len(loc) != 2:
continue
-
+
# Extract and check nodeid
index, subindex = loc[:2]
-
+
# Extract and check index and subindex
if not slave.IsEntry(index, subindex):
raise PDOmappingException, _("No such index/subindex ({a1},{a2}) (variable {a3})").\
format(a1 = "%x" % index, a2 = "%x" % subindex, a3 = name)
-
+
# Get the entry info
- subentry_infos = slave.GetSubentryInfos(index, subindex)
+ subentry_infos = slave.GetSubentryInfos(index, subindex)
if subentry_infos["type"] != COlocationtype:
raise PDOmappingException, _("Invalid type \"{a1}\"-> {a2} != {a3} for location \"{a4}\"").\
format( a1 = location["IEC_TYPE"], a2 = COlocationtype, a3 = subentry_infos["type"] , a4 = name)
-
+
IECLocations[name] = COlocationtype
pointers[(index, subindex)] = name
return pointers
-
+
if __name__ == "__main__":
import os, sys, getopt
@@ -667,7 +667,7 @@
Use with caution. Be sure that config_utils
is currently working properly.
"""%sys.argv[0]
-
+
# Boolean that indicate if reference result must be redefined
reset = False
@@ -693,15 +693,15 @@
base_folder = os.path.split(base_folder)[0]
# Add CanFestival folder to search pathes
sys.path.append(os.path.join(base_folder, "CanFestival-3", "objdictgen"))
-
+
from nodemanager import *
from nodelist import *
-
+
# Open the test nodelist contained into test_config folder
manager = NodeManager()
nodelist = NodeList(manager)
result = nodelist.LoadProject("test_config")
-
+
# List of locations, we try to map for test
locations = [{"IEC_TYPE":"BYTE","NAME":"__IB0_1_64_24576_1","DIR":"I","SIZE":"B","LOC":(0,1,64,24576,1)},
{"IEC_TYPE":"INT","NAME":"__IW0_1_64_25601_2","DIR":"I","SIZE":"W","LOC":(0,1,64,25601,2)},
@@ -713,34 +713,34 @@
{"IEC_TYPE":"UDINT","NAME":"__ID0_1_64_25638_3","DIR":"I","SIZE":"D","LOC":(0,1,64,25638,3)},
{"IEC_TYPE":"UDINT","NAME":"__ID0_1_64_25638_4","DIR":"I","SIZE":"D","LOC":(0,1,64,25638,4)},
{"IEC_TYPE":"UDINT","NAME":"__ID0_1_4096_0","DIR":"I","SIZE":"D","LOC":(0,1,4096,0)}]
-
+
# Generate MasterNode configuration
try:
masternode, pointedvariables = GenerateConciseDCF(locations, (0, 1), nodelist, True, "TestNode")
except ValueError, message:
print "%s\nTest Failed!"%message
sys.exit()
-
+
import pprint
- # Get Text corresponding to MasterNode
+ # Get Text corresponding to MasterNode
result_node = masternode.PrintString()
result_vars = pprint.pformat(pointedvariables)
result = result_node + "\n********POINTERS*********\n" + result_vars + "\n"
-
+
# If reset has been choosen
if reset:
# Write Text into reference result file
testfile = open("test_config/result.txt", "w")
testfile.write(result)
testfile.close()
-
+
print "Reset Successful!"
else:
import os
-
+
testfile = open("test_config/result_tmp.txt", "w")
testfile.write(result)
testfile.close()
-
+
os.system("diff test_config/result.txt test_config/result_tmp.txt")
os.remove("test_config/result_tmp.txt")
--- a/controls/CustomToolTip.py Fri Aug 11 15:18:19 2017 +0300
+++ b/controls/CustomToolTip.py Mon Aug 14 19:13:01 2017 +0300
@@ -39,32 +39,32 @@
"""
class CustomToolTip(wx.PopupWindow):
-
+
def __init__(self, parent, tip, restricted=True):
"""
Constructor
@param parent: Parent window
@param tip: Tip text (may be multiline)
- @param restricted: Tool tip must follow size restriction in line and
+ @param restricted: Tool tip must follow size restriction in line and
characters number defined (default True)
"""
wx.PopupWindow.__init__(self, parent)
-
+
self.Restricted = restricted
-
+
self.SetBackgroundStyle(wx.BG_STYLE_CUSTOM)
self.SetTip(tip)
-
+
# Initialize text font style
self.Font = wx.Font(
- faces["size"],
- wx.SWISS,
- wx.NORMAL,
- wx.NORMAL,
+ faces["size"],
+ wx.SWISS,
+ wx.NORMAL,
+ wx.NORMAL,
faceName = faces["mono"])
-
+
self.Bind(wx.EVT_PAINT, self.OnPaint)
-
+
def SetFont(self, font):
"""
Set tool tip text font style
@@ -72,7 +72,7 @@
"""
self.Font = font
self.RefreshTip()
-
+
def SetTip(self, tip):
"""
Set tool tip text
@@ -97,11 +97,11 @@
self.Tip.append(new_line)
else:
self.Tip.append(line)
-
+
# Restrict number of lines
if len(self.Tip) > TOOLTIP_MAX_LINE:
self.Tip = self.Tip[:TOOLTIP_MAX_LINE]
-
+
# Add ... to the end of last line to indicate that tool tip
# text is too long
if len(self.Tip[-1]) < TOOLTIP_MAX_CHARACTERS - 3:
@@ -111,10 +111,10 @@
[:TOOLTIP_MAX_CHARACTERS - 3] + "..."
else:
self.Tip = tip.splitlines()
-
+
# Prevent to call wx method in non-wx threads
wx.CallAfter(self.RefreshTip)
-
+
def SetToolTipPosition(self, pos):
"""
Set tool tip position
@@ -122,32 +122,32 @@
"""
# Get screen size to prevent tool tip to go out of the screen
screen_width, screen_height = wx.GetDisplaySize()
-
+
# Calculate position of tool tip to stay in screen limits
tip_width, tip_height = self.GetToolTipSize()
self.SetPosition(wx.Point(
max(0, min(pos.x, screen_width - tip_width)),
max(0, min(pos.y, screen_height - tip_height))))
-
+
def GetToolTipSize(self):
"""
Get tool tip size according to tip text and restriction
@return: wx.Size(tool_tip_width, tool_tip_height)
"""
max_width = max_height = 0
-
+
# Create a memory DC for calculating text extent
dc = wx.MemoryDC()
dc.SetFont(self.Font)
-
+
# Compute max tip text size
for line in self.Tip:
w, h = dc.GetTextExtent(line)
max_width = max(max_width, w)
max_height += h
-
+
return wx.Size(max_width + 4, max_height + 4)
-
+
def RefreshTip(self):
"""
Refresh tip on screen
@@ -156,10 +156,10 @@
if self:
# Refresh tool tip size and position
self.SetClientSize(self.GetToolTipSize())
-
+
# Redraw tool tip
self.Refresh()
-
+
def OnPaint(self, event):
"""
Callback for Paint Event
@@ -168,26 +168,26 @@
# Get buffered paint DC for tool tip
dc = wx.AutoBufferedPaintDC(self)
dc.Clear()
-
+
# Set DC drawing style
dc.SetPen(wx.BLACK_PEN)
dc.SetBrush(wx.Brush(wx.Colour(255, 238, 170)))
dc.SetFont(self.Font)
-
+
# Draw Tool tip
dc.BeginDrawing()
tip_width, tip_height = self.GetToolTipSize()
-
+
# Draw background rectangle
dc.DrawRectangle(0, 0, tip_width, tip_height)
-
+
# Draw tool tip text
line_offset = 0
for line in self.Tip:
dc.DrawText(line, 2, line_offset + 2)
line_width, line_height = dc.GetTextExtent(line)
line_offset += line_height
-
+
dc.EndDrawing()
-
+
event.Skip()
--- a/controls/CustomTree.py Fri Aug 11 15:18:19 2017 +0300
+++ b/controls/CustomTree.py Mon Aug 14 19:13:01 2017 +0300
@@ -44,30 +44,30 @@
CT.GenericTreeItem.GetCurrentCheckedImage = GetCurrentCheckedImage
class CustomTree(CT.CustomTreeCtrl):
-
+
def __init__(self, *args, **kwargs):
CT.CustomTreeCtrl.__init__(self, *args, **kwargs)
-
+
self.BackgroundBitmap = None
self.BackgroundAlign = wx.ALIGN_LEFT|wx.ALIGN_TOP
-
+
self.AddMenu = None
self.Enabled = False
-
+
self.Bind(wx.EVT_SCROLLWIN, self.OnScroll)
self.Bind(wx.EVT_LEFT_UP, self.OnLeftUp)
-
+
def SetBackgroundBitmap(self, bitmap, align):
self.BackgroundBitmap = bitmap
self.BackgroundAlign = align
-
+
def SetImageListCheck(self, sizex, sizey, imglist=None):
CT.CustomTreeCtrl.SetImageListCheck(self, sizex, sizey, imglist=None)
-
+
self.ExtraImages = {}
for image in ["function", "functionBlock", "program"]:
self.ExtraImages[image] = self._imageListCheck.Add(GetBitmap(image.upper()))
-
+
def SetItemExtraImage(self, item, bitmap):
dc = wx.ClientDC(self)
image = self.ExtraImages.get(bitmap)
@@ -76,45 +76,45 @@
else:
item.SetExtraImage(None)
self.CalculateSize(item, dc)
- self.RefreshLine(item)
-
+ self.RefreshLine(item)
+
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 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
+ if (bitmap_rect.InsideXY(pos.x, pos.y) or
flags & wx.TREE_HITTEST_NOWHERE) and self.AddMenu is not None:
wx.CallAfter(self.PopupMenuXY, self.AddMenu, pos.x, pos.y)
event.Skip()
-
+
def OnEraseBackground(self, event):
dc = event.GetDC()
@@ -122,12 +122,12 @@
dc = wx.ClientDC(self)
rect = self.GetUpdateRegion().GetBox()
dc.SetClippingRect(rect)
-
+
dc.Clear()
-
+
bitmap_rect = self.GetBitmapRect()
dc.DrawBitmap(self.BackgroundBitmap, bitmap_rect.x, bitmap_rect.y)
-
+
def OnScroll(self, event):
wx.CallAfter(self.Refresh)
event.Skip()
--- a/controls/DebugVariablePanel/DebugVariableGraphicViewer.py Fri Aug 11 15:18:19 2017 +0300
+++ b/controls/DebugVariablePanel/DebugVariableGraphicViewer.py Mon Aug 14 19:13:01 2017 +0300
@@ -83,23 +83,23 @@
min_value = range_min
elif range_min is not None:
min_value = min(min_value, range_min)
-
+
# Update maximal range value
if max_value is None:
max_value = range_max
elif range_min is not None:
max_value = max(max_value, range_max)
-
+
# Calculate range center and width if at least one valid range is defined
if min_value is not None and max_value is not None:
center = (min_value + max_value) / 2.
range_size = max(1.0, max_value - min_value)
-
+
# Set default center and with if no valid range is defined
else:
center = 0.5
range_size = 1.0
-
+
# Return range expended from 10 %
return center - range_size * 0.55, center + range_size * 0.55
@@ -113,7 +113,7 @@
"""
class DebugVariableGraphicDropTarget(wx.TextDropTarget):
-
+
def __init__(self, parent, window):
"""
Constructor
@@ -123,7 +123,7 @@
wx.TextDropTarget.__init__(self)
self.ParentControl = parent
self.ParentWindow = window
-
+
def __del__(self):
"""
Destructor
@@ -132,7 +132,7 @@
# Panel
self.ParentControl = None
self.ParentWindow = None
-
+
def OnDragOver(self, x, y, d):
"""
Function called when mouse is dragged over Drop Target
@@ -142,9 +142,9 @@
"""
# Signal parent that mouse is dragged over
self.ParentControl.OnMouseDragging(x, y)
-
+
return wx.TextDropTarget.OnDragOver(self, x, y, d)
-
+
def OnDropText(self, x, y, data):
"""
Function called when mouse is released in Drop Target
@@ -154,9 +154,9 @@
"""
# Signal Debug Variable Panel to reset highlight
self.ParentWindow.ResetHighlight()
-
+
message = None
-
+
# Check that data is valid regarding DebugVariablePanel
try:
values = eval(data)
@@ -165,54 +165,54 @@
except:
message = _("Invalid value \"%s\" for debug variable")%data
values = None
-
+
# Display message if data is invalid
if message is not None:
wx.CallAfter(self.ShowMessage, message)
-
+
# Data contain a reference to a variable to debug
elif values[1] == "debug":
target_idx = self.ParentControl.GetIndex()
-
+
# If mouse is dropped in graph canvas bounding box and graph is
# not 3D canvas, graphs will be merged
rect = self.ParentControl.GetAxesBoundingBox()
if not self.ParentControl.Is3DCanvas() and rect.InsideXY(x, y):
# Default merge type is parallel
merge_type = GRAPH_PARALLEL
-
+
# If mouse is dropped in left part of graph canvas, graph
# wall be merged orthogonally
- merge_rect = wx.Rect(rect.x, rect.y,
+ merge_rect = wx.Rect(rect.x, rect.y,
rect.width / 2., rect.height)
if merge_rect.InsideXY(x, y):
merge_type = GRAPH_ORTHOGONAL
-
+
# Merge graphs
- wx.CallAfter(self.ParentWindow.MergeGraphs,
- values[0], target_idx,
+ wx.CallAfter(self.ParentWindow.MergeGraphs,
+ values[0], target_idx,
merge_type, force=True)
-
+
else:
width, height = self.ParentControl.GetSize()
-
+
# Get Before which Viewer the variable has to be moved or added
# according to the position of mouse in Viewer.
if y > height / 2:
target_idx += 1
-
+
# Drag'n Drop is an internal is an internal move inside Debug
- # Variable Panel
+ # Variable Panel
if len(values) > 2 and values[2] == "move":
- self.ParentWindow.MoveValue(values[0],
+ self.ParentWindow.MoveValue(values[0],
target_idx)
-
+
# Drag'n Drop was initiated by another control of Beremiz
else:
- self.ParentWindow.InsertValue(values[0],
- target_idx,
+ self.ParentWindow.InsertValue(values[0],
+ target_idx,
force=True)
-
+
def OnLeave(self):
"""
Function called when mouse is leave Drop Target
@@ -220,15 +220,15 @@
# Signal Debug Variable Panel to reset highlight
self.ParentWindow.ResetHighlight()
return wx.TextDropTarget.OnLeave(self)
-
+
def ShowMessage(self, message):
"""
Show error message in Error Dialog
@param message: Error message to display
"""
- dialog = wx.MessageDialog(self.ParentWindow,
- message,
- _("Error"),
+ dialog = wx.MessageDialog(self.ParentWindow,
+ message,
+ _("Error"),
wx.OK|wx.ICON_ERROR)
dialog.ShowModal()
dialog.Destroy()
@@ -243,7 +243,7 @@
"""
class DebugVariableGraphicViewer(DebugVariableViewer, FigureCanvas):
-
+
def __init__(self, parent, window, items, graph_type):
"""
Constructor
@@ -253,36 +253,36 @@
@param graph_type: Graph display type (Parallel or orthogonal)
"""
DebugVariableViewer.__init__(self, window, items)
-
+
self.GraphType = graph_type # Graph type display
self.CursorTick = None # Tick of the graph cursor
-
+
# Mouse position when start dragging
self.MouseStartPos = None
# Tick when moving tick start
self.StartCursorTick = None
# Canvas size when starting to resize canvas
- self.CanvasStartSize = None
-
+ self.CanvasStartSize = None
+
# List of current displayed contextual buttons
self.ContextualButtons = []
# Reference to item for which contextual buttons was displayed
self.ContextualButtonsItem = None
-
+
# Flag indicating that zoom fit current displayed data range or whole
# data range if False
self.ZoomFit = False
-
+
# Create figure for drawing graphs
self.Figure = matplotlib.figure.Figure(facecolor='w')
# Defined border around figure in canvas
- self.Figure.subplotpars.update(top=0.95, left=0.1,
+ self.Figure.subplotpars.update(top=0.95, left=0.1,
bottom=0.1, right=0.95)
-
+
FigureCanvas.__init__(self, parent, -1, self.Figure)
self.SetWindowStyle(wx.WANTS_CHARS)
self.SetBackgroundColour(wx.WHITE)
-
+
# Bind wx events
self.Bind(wx.EVT_LEFT_DCLICK, self.OnLeftDClick)
self.Bind(wx.EVT_KEY_DOWN, self.OnKeyDown)
@@ -290,42 +290,42 @@
self.Bind(wx.EVT_LEAVE_WINDOW, self.OnLeave)
self.Bind(wx.EVT_ERASE_BACKGROUND, self.OnEraseBackground)
self.Bind(wx.EVT_SIZE, self.OnResize)
-
+
# Set canvas min size
canvas_size = self.GetCanvasMinSize()
self.SetMinSize(canvas_size)
-
+
# Define Viewer drop target
self.SetDropTarget(DebugVariableGraphicDropTarget(self, window))
-
+
# Connect matplotlib events
self.mpl_connect('button_press_event', self.OnCanvasButtonPressed)
self.mpl_connect('motion_notify_event', self.OnCanvasMotion)
self.mpl_connect('button_release_event', self.OnCanvasButtonReleased)
self.mpl_connect('scroll_event', self.OnCanvasScroll)
-
+
# Add buttons for zooming on current displayed data range
self.Buttons.append(
GraphButton(0, 0, "fit_graph", self.OnZoomFitButton))
-
+
# Add buttons for changing canvas size with predefined height
for size, bitmap in zip(
[SIZE_MINI, SIZE_MIDDLE, SIZE_MAXI],
["minimize_graph", "middle_graph", "maximize_graph"]):
self.Buttons.append(
- GraphButton(0, 0, bitmap,
+ GraphButton(0, 0, bitmap,
self.GetOnChangeSizeButton(size)))
-
+
# Add buttons for exporting graph values to clipboard and close graph
for bitmap, callback in [
("export_graph_mini", self.OnExportGraphButton),
("delete_graph", self.OnCloseButton)]:
self.Buttons.append(GraphButton(0, 0, bitmap, callback))
-
+
# Update graphs elements
self.ResetGraphics()
self.RefreshLabelsPosition(canvas_size.height)
-
+
def AddItem(self, item):
"""
Add an item to the list of items displayed by Viewer
@@ -333,14 +333,14 @@
"""
DebugVariableViewer.AddItem(self, item)
self.ResetGraphics()
-
+
def RemoveItem(self, item):
"""
Remove an item from the list of items displayed by Viewer
@param item: Item to remove from the list
"""
DebugVariableViewer.RemoveItem(self, item)
-
+
# If list of items is not empty
if not self.ItemsIsEmpty():
# Return to parallel graph if there is only one item
@@ -348,51 +348,51 @@
if len(self.Items) == 1:
self.GraphType = GRAPH_PARALLEL
self.ResetGraphics()
-
+
def SetCursorTick(self, cursor_tick):
"""
Set cursor tick
@param cursor_tick: Cursor tick
"""
self.CursorTick = cursor_tick
-
+
def SetZoomFit(self, zoom_fit):
"""
Set flag indicating that zoom fit current displayed data range
@param zoom_fit: Flag for zoom fit (False: zoom fit whole data range)
"""
- # Flag is different from the actual one
+ # Flag is different from the actual one
if zoom_fit != self.ZoomFit:
# Save new flag value
self.ZoomFit = zoom_fit
-
+
# Update button for zoom fit bitmap
self.Buttons[0].SetBitmap("full_graph" if zoom_fit else "fit_graph")
-
+
# Refresh canvas
self.RefreshViewer()
-
+
def SubscribeAllDataConsumers(self):
"""
Function that unsubscribe and remove every item that store values of
a variable that doesn't exist in PLC anymore
"""
DebugVariableViewer.SubscribeAllDataConsumers(self)
-
+
# Graph still have data to display
if not self.ItemsIsEmpty():
# Reset flag indicating that zoom fit current displayed data range
self.SetZoomFit(False)
-
+
self.ResetGraphics()
-
+
def Is3DCanvas(self):
"""
Return if Viewer is a 3D canvas
@return: True if Viewer is a 3D canvas
"""
return self.GraphType == GRAPH_ORTHOGONAL and len(self.Items) == 3
-
+
def GetButtons(self):
"""
Return list of buttons defined in Viewer
@@ -400,7 +400,7 @@
"""
# Add contextual buttons to default buttons
return self.Buttons + self.ContextualButtons
-
+
def PopupContextualButtons(self, item, rect, direction=wx.RIGHT):
"""
Show contextual menu for item aside a label of this item defined
@@ -412,19 +412,19 @@
# Return immediately if contextual menu for item is already shown
if self.ContextualButtonsItem == item:
return
-
+
# Close already shown contextual menu
self.DismissContextualButtons()
-
+
# Save item for which contextual menu is shown
self.ContextualButtonsItem = item
-
+
# If item variable is forced, add button for release variable to
# contextual menu
if self.ContextualButtonsItem.IsForced():
self.ContextualButtons.append(
GraphButton(0, 0, "release", self.OnReleaseItemButton))
-
+
# Add other buttons to contextual menu
for bitmap, callback in [
("force", self.OnForceItemButton),
@@ -432,13 +432,13 @@
("delete_graph", self.OnRemoveItemButton)]:
self.ContextualButtons.append(
GraphButton(0, 0, bitmap, callback))
-
+
# If buttons are shown at left side or upper side of rect, positions
# will be set in reverse order
buttons = self.ContextualButtons[:]
if direction in [wx.TOP, wx.LEFT]:
buttons.reverse()
-
+
# Set contextual menu buttons position aside rect depending on
# direction given
offset = 0
@@ -458,10 +458,10 @@
offset += h
button.SetPosition(x, y)
button.Show()
-
+
# Refresh canvas
self.ParentWindow.ForceRefresh()
-
+
def DismissContextualButtons(self):
"""
Close current shown contextual menu
@@ -469,14 +469,14 @@
# Return immediately if no contextual menu is shown
if self.ContextualButtonsItem is None:
return
-
+
# Reset variables corresponding to contextual menu
self.ContextualButtonsItem = None
self.ContextualButtons = []
-
+
# Refresh canvas
self.ParentWindow.ForceRefresh()
-
+
def IsOverContextualButton(self, x, y):
"""
Return if point is over one contextual button of Viewer
@@ -488,7 +488,7 @@
if button.HitTest(x, y):
return button
return None
-
+
def ExportGraph(self, item=None):
"""
Export item(s) data to clipboard in CSV format
@@ -497,17 +497,17 @@
"""
self.ParentWindow.CopyDataToClipboard(
[(item, [entry for entry in item.GetData()])
- for item in (self.Items
- if item is None
+ for item in (self.Items
+ if item is None
else [item])])
-
+
def OnZoomFitButton(self):
"""
Function called when Viewer Zoom Fit button is pressed
"""
# Toggle zoom fit flag value
self.SetZoomFit(not self.ZoomFit)
-
+
def GetOnChangeSizeButton(self, height):
"""
Function that generate callback function for change Viewer height to
@@ -518,32 +518,32 @@
def OnChangeSizeButton():
self.SetCanvasHeight(height)
return OnChangeSizeButton
-
+
def OnExportGraphButton(self):
"""
Function called when Viewer Export button is pressed
"""
# Export data of every item in Viewer
self.ExportGraph()
-
+
def OnForceItemButton(self):
"""
Function called when contextual menu Force button is pressed
"""
- # Open dialog for forcing item variable value
+ # Open dialog for forcing item variable value
self.ForceValue(self.ContextualButtonsItem)
# Close contextual menu
self.DismissContextualButtons()
-
+
def OnReleaseItemButton(self):
"""
Function called when contextual menu Release button is pressed
"""
- # Release item variable value
+ # Release item variable value
self.ReleaseValue(self.ContextualButtonsItem)
# Close contextual menu
self.DismissContextualButtons()
-
+
def OnExportItemGraphButton(self):
"""
Function called when contextual menu Export button is pressed
@@ -552,17 +552,17 @@
self.ExportGraph(self.ContextualButtonsItem)
# Close contextual menu
self.DismissContextualButtons()
-
- def OnRemoveItemButton(self):
+
+ def OnRemoveItemButton(self):
"""
Function called when contextual menu Remove button is pressed
"""
# Remove item from Viewer
- wx.CallAfter(self.ParentWindow.DeleteValue, self,
+ wx.CallAfter(self.ParentWindow.DeleteValue, self,
self.ContextualButtonsItem)
# Close contextual menu
self.DismissContextualButtons()
-
+
def HandleCursorMove(self, event):
"""
Update Cursor position according to mouse position and graph type
@@ -571,7 +571,7 @@
start_tick, end_tick = self.ParentWindow.GetRange()
cursor_tick = None
items = self.ItemsDict.values()
-
+
# Graph is orthogonal
if self.GraphType == GRAPH_ORTHOGONAL:
# Extract items data displayed in canvas figure
@@ -579,31 +579,31 @@
end_tick = max(end_tick, start_tick)
x_data = items[0].GetData(start_tick, end_tick)
y_data = items[1].GetData(start_tick, end_tick)
-
+
# Search for the nearest point from mouse position
if len(x_data) > 0 and len(y_data) > 0:
- length = min(len(x_data), len(y_data))
+ length = min(len(x_data), len(y_data))
d = numpy.sqrt((x_data[:length,1]-event.xdata) ** 2 + \
(y_data[:length,1]-event.ydata) ** 2)
-
+
# Set cursor tick to the tick of this point
cursor_tick = x_data[numpy.argmin(d), 0]
-
+
# Graph is parallel
else:
# Extract items tick
data = items[0].GetData(start_tick, end_tick)
-
+
# Search for point that tick is the nearest from mouse X position
# and set cursor tick to the tick of this point
if len(data) > 0:
cursor_tick = data[numpy.argmin(
numpy.abs(data[:,0] - event.xdata)), 0]
-
+
# Update cursor tick
if cursor_tick is not None:
self.ParentWindow.SetCursorTick(cursor_tick)
-
+
def OnCanvasButtonPressed(self, event):
"""
Function called when a button of mouse is pressed
@@ -613,18 +613,18 @@
# comparing to wx
width, height = self.GetSize()
x, y = event.x, height - event.y
-
+
# Return immediately if mouse is over a button
if self.IsOverButton(x, y):
- return
-
+ return
+
# Mouse was clicked inside graph figure
if event.inaxes == self.Axes:
-
+
# Find if it was on an item label
item_idx = None
# Check every label paired with corresponding item
- for i, t in ([pair for pair in enumerate(self.AxesLabels)] +
+ for i, t in ([pair for pair in enumerate(self.AxesLabels)] +
[pair for pair in enumerate(self.Labels)]):
# Get label bounding box
(x0, y0), (x1, y1) = t.get_window_extent().get_points()
@@ -633,46 +633,46 @@
if rect.InsideXY(x, y):
item_idx = i
break
-
+
# If an item label have been clicked
if item_idx is not None:
# Hide buttons and contextual buttons
self.ShowButtons(False)
self.DismissContextualButtons()
-
+
# Start a drag'n drop from mouse position in wx coordinate of
# parent
xw, yw = self.GetPosition()
- self.ParentWindow.StartDragNDrop(self,
- self.ItemsDict.values()[item_idx],
+ self.ParentWindow.StartDragNDrop(self,
+ self.ItemsDict.values()[item_idx],
x + xw, y + yw, # Current mouse position
x + xw, y + yw) # Mouse position when button was clicked
-
+
# Don't handle mouse button if canvas is 3D and let matplotlib do
# the default behavior (rotate 3D axes)
elif not self.Is3DCanvas():
# Save mouse position when clicked
self.MouseStartPos = wx.Point(x, y)
-
+
# Mouse button was left button, start moving cursor
if event.button == 1:
# Save current tick in case a drag'n drop is initiate to
# restore it
self.StartCursorTick = self.CursorTick
-
+
self.HandleCursorMove(event)
-
+
# Mouse button is middle button and graph is parallel, start
# moving graph along X coordinate (tick)
elif event.button == 2 and self.GraphType == GRAPH_PARALLEL:
self.StartCursorTick = self.ParentWindow.GetRange()[0]
-
+
# Mouse was clicked outside graph figure and over resize highlight with
# left button, start resizing Viewer
elif event.button == 1 and event.y <= 5:
self.MouseStartPos = wx.Point(x, y)
self.CanvasStartSize = height
-
+
def OnCanvasButtonReleased(self, event):
"""
Function called when a button of mouse is released
@@ -686,37 +686,37 @@
# Give mouse position in wx coordinate of parent
self.ParentWindow.StopDragNDrop(item.GetVariable(),
xw + event.x, yw + height - event.y)
-
+
else:
# Reset any move in progress
self.MouseStartPos = None
self.CanvasStartSize = None
-
+
# Handle button under mouse if it exist
width, height = self.GetSize()
self.HandleButton(event.x, height - event.y)
-
+
def OnCanvasMotion(self, event):
"""
Function called when a button of mouse is moved over Viewer
@param event: Mouse event
"""
width, height = self.GetSize()
-
+
# If a drag'n drop is in progress, move canvas dragged
if self.ParentWindow.IsDragging():
xw, yw = self.GetPosition()
# Give mouse position in wx coordinate of parent
self.ParentWindow.MoveDragNDrop(
- xw + event.x,
+ xw + event.x,
yw + height - event.y)
-
- # If a Viewer resize is in progress, change Viewer size
+
+ # If a Viewer resize is in progress, change Viewer size
elif event.button == 1 and self.CanvasStartSize is not None:
width, height = self.GetSize()
self.SetCanvasHeight(
self.CanvasStartSize + height - event.y - self.MouseStartPos.y)
-
+
# If no button is pressed, show or hide contextual buttons or resize
# highlight
elif event.button is None:
@@ -729,13 +729,13 @@
wx.LEFT, wx.BOTTOM] # Directions for Labels
else: # Graph is orthogonal in 3D
directions = [wx.LEFT] * len(self.Labels)
-
+
# Find if mouse is over an item label
item_idx = None
menu_direction = None
for (i, t), dir in zip(
- [pair for pair in enumerate(self.AxesLabels)] +
- [pair for pair in enumerate(self.Labels)],
+ [pair for pair in enumerate(self.AxesLabels)] +
+ [pair for pair in enumerate(self.Labels)],
directions):
# Check every label paired with corresponding item
(x0, y0), (x1, y1) = t.get_window_extent().get_points()
@@ -745,19 +745,19 @@
item_idx = i
menu_direction = dir
break
-
- # If mouse is over an item label,
+
+ # If mouse is over an item label,
if item_idx is not None:
self.PopupContextualButtons(
- self.ItemsDict.values()[item_idx],
+ self.ItemsDict.values()[item_idx],
rect, menu_direction)
return
-
+
# If mouse isn't over a contextual menu, hide the current shown one
- # if it exists
+ # if it exists
if self.IsOverContextualButton(event.x, height - event.y) is None:
self.DismissContextualButtons()
-
+
# Update resize highlight
if event.y <= 5:
if self.SetHighlight(HIGHLIGHT_RESIZE):
@@ -767,46 +767,46 @@
if self.SetHighlight(HIGHLIGHT_NONE):
self.SetCursor(wx.NullCursor)
self.ParentWindow.ForceRefresh()
-
- # Handle buttons if canvas is not 3D
+
+ # Handle buttons if canvas is not 3D
elif not self.Is3DCanvas():
-
+
# If left button is pressed
if event.button == 1:
-
+
# Mouse is inside graph figure
if event.inaxes == self.Axes:
-
+
# If a cursor move is in progress, update cursor position
if self.MouseStartPos is not None:
self.HandleCursorMove(event)
-
+
# Mouse is outside graph figure, cursor move is in progress and
# there is only one item in Viewer, start a drag'n drop
elif self.MouseStartPos is not None and len(self.Items) == 1:
xw, yw = self.GetPosition()
self.ParentWindow.SetCursorTick(self.StartCursorTick)
- self.ParentWindow.StartDragNDrop(self,
+ self.ParentWindow.StartDragNDrop(self,
self.ItemsDict.values()[0],
# Current mouse position
event.x + xw, height - event.y + yw,
# Mouse position when button was clicked
self.MouseStartPos.x + xw,
self.MouseStartPos.y + yw)
-
+
# If middle button is pressed and moving graph along X coordinate
# is in progress
elif event.button == 2 and self.GraphType == GRAPH_PARALLEL and \
self.MouseStartPos is not None:
start_tick, end_tick = self.ParentWindow.GetRange()
rect = self.GetAxesBoundingBox()
-
+
# Move graph along X coordinate
self.ParentWindow.SetCanvasPosition(
- self.StartCursorTick +
+ self.StartCursorTick +
(self.MouseStartPos.x - event.x) *
(end_tick - start_tick) / rect.width)
-
+
def OnCanvasScroll(self, event):
"""
Function called when a wheel mouse is use in Viewer
@@ -815,7 +815,7 @@
# Change X range of graphs if mouse is in canvas figure and ctrl is
# pressed
if event.inaxes is not None and event.guiEvent.ControlDown():
-
+
# Calculate position of fixed tick point according to graph type
# and mouse position
if self.GraphType == GRAPH_ORTHOGONAL:
@@ -824,10 +824,10 @@
else:
tick = event.xdata
self.ParentWindow.ChangeRange(int(-event.step) / 3, tick)
-
+
# Vetoing event to prevent parent panel to be scrolled
self.ParentWindow.VetoScrollEvent = True
-
+
def OnLeftDClick(self, event):
"""
Function called when a left mouse button is double clicked
@@ -841,17 +841,17 @@
self.ParentWindow.SetCursorTick(self.StartCursorTick)
# Toggle to text Viewer(s)
self.ParentWindow.ToggleViewerType(self)
-
+
else:
event.Skip()
-
+
# Cursor tick move for each arrow key
KEY_CURSOR_INCREMENT = {
wx.WXK_LEFT: -1,
wx.WXK_RIGHT: 1,
wx.WXK_UP: 10,
wx.WXK_DOWN: -10}
-
+
def OnKeyDown(self, event):
"""
Function called when key is pressed
@@ -863,7 +863,7 @@
if move is not None:
self.ParentWindow.MoveCursorTick(move)
event.Skip()
-
+
def OnLeave(self, event):
"""
Function called when mouse leave Viewer
@@ -876,7 +876,7 @@
DebugVariableViewer.OnLeave(self, event)
else:
event.Skip()
-
+
def GetCanvasMinSize(self):
"""
Return the minimum size of Viewer so that all items label can be
@@ -885,10 +885,10 @@
"""
# The minimum height take in account the height of all items, padding
# inside figure and border around figure
- return wx.Size(200,
- CANVAS_BORDER[0] + CANVAS_BORDER[1] +
+ return wx.Size(200,
+ CANVAS_BORDER[0] + CANVAS_BORDER[1] +
2 * CANVAS_PADDING + VALUE_LABEL_HEIGHT * len(self.Items))
-
+
def SetCanvasHeight(self, height):
"""
Set Viewer size checking that it respects Viewer minimum size
@@ -899,7 +899,7 @@
self.SetMinSize(wx.Size(min_width, height))
self.RefreshLabelsPosition(height)
self.ParentWindow.RefreshGraphicsSizer()
-
+
def GetAxesBoundingBox(self, parent_coordinate=False):
"""
Return figure bounding box in wx coordinate
@@ -911,15 +911,15 @@
ax, ay, aw, ah = self.figure.gca().get_position().bounds
bbox = wx.Rect(ax * width, height - (ay + ah) * height - 1,
aw * width + 2, ah * height + 1)
-
+
# If parent_coordinate, add Viewer position in parent
if parent_coordinate:
xw, yw = self.GetPosition()
bbox.x += xw
bbox.y += yw
-
+
return bbox
-
+
def RefreshHighlight(self, x, y):
"""
Refresh Viewer highlight according to mouse position
@@ -927,7 +927,7 @@
@param y: Y coordinate of mouse pointer
"""
width, height = self.GetSize()
-
+
# Mouse is over Viewer figure and graph is not 3D
bbox = self.GetAxesBoundingBox()
if bbox.InsideXY(x, y) and not self.Is3DCanvas():
@@ -935,28 +935,28 @@
# Mouse is over Viewer left part of figure
if rect.InsideXY(x, y):
self.SetHighlight(HIGHLIGHT_LEFT)
-
+
# Mouse is over Viewer right part of figure
else:
self.SetHighlight(HIGHLIGHT_RIGHT)
-
+
# Mouse is over upper part of Viewer
elif y < height / 2:
# Viewer is upper one in Debug Variable Panel, show highlight
if self.ParentWindow.IsViewerFirst(self):
self.SetHighlight(HIGHLIGHT_BEFORE)
-
+
# Viewer is not the upper one, show highlight in previous one
# It prevents highlight to move when mouse leave one Viewer to
# another
else:
self.SetHighlight(HIGHLIGHT_NONE)
self.ParentWindow.HighlightPreviousViewer(self)
-
+
# Mouse is over lower part of Viewer
else:
self.SetHighlight(HIGHLIGHT_AFTER)
-
+
def OnAxesMotion(self, event):
"""
Function overriding default function called when mouse is dragged for
@@ -969,7 +969,7 @@
if current_time - self.LastMotionTime > REFRESH_PERIOD:
self.LastMotionTime = current_time
Axes3D._on_move(self.Axes, event)
-
+
def GetAddTextFunction(self):
"""
Return function for adding text in figure according to graph type
@@ -987,58 +987,58 @@
self.Axes.set_prop_cycle(cycler('color',color))
else:
self.Axes.set_color_cycle(color)
-
+
def ResetGraphics(self):
"""
Reset figure and graphical elements displayed in it
- Called any time list of items or graph type change
+ Called any time list of items or graph type change
"""
# Clear figure from any axes defined
self.Figure.clear()
-
+
# Add 3D projection if graph is in 3D
if self.Is3DCanvas():
self.Axes = self.Figure.gca(projection='3d')
self.SetAxesColor(['b'])
-
- # Override function to prevent too much refresh when graph is
+
+ # Override function to prevent too much refresh when graph is
# rotated
self.LastMotionTime = gettime()
setattr(self.Axes, "_on_move", self.OnAxesMotion)
-
+
# Init graph mouse event so that graph can be rotated
self.Axes.mouse_init()
-
+
# Set size of Z axis labels
self.Axes.tick_params(axis='z', labelsize='small')
-
+
else:
self.Axes = self.Figure.gca()
self.SetAxesColor(COLOR_CYCLE)
-
+
# Set size of X and Y axis labels
self.Axes.tick_params(axis='x', labelsize='small')
self.Axes.tick_params(axis='y', labelsize='small')
-
+
# Init variables storing graphical elements added to figure
self.Plots = [] # List of curves
self.VLine = None # Vertical line for cursor
self.HLine = None # Horizontal line for cursor (only orthogonal 2D)
self.AxesLabels = [] # List of items variable path text label
self.Labels = [] # List of items text label
-
- # Get function to add a text in figure according to graph type
+
+ # Get function to add a text in figure according to graph type
add_text_func = self.GetAddTextFunction()
-
+
# Graph type is parallel or orthogonal in 3D
if self.GraphType == GRAPH_PARALLEL or self.Is3DCanvas():
num_item = len(self.Items)
for idx in xrange(num_item):
-
+
# Get color from color cycle (black if only one item)
color = ('k' if num_item == 1
else COLOR_CYCLE[idx % len(COLOR_CYCLE)])
-
+
# In 3D graph items variable label are not displayed as text
# in figure, but as axis title
if not self.Is3DCanvas():
@@ -1046,12 +1046,12 @@
self.AxesLabels.append(
add_text_func(size='small', color=color,
verticalalignment='top'))
-
+
# Items variable labels are in figure lower right corner
self.Labels.append(
- add_text_func(size='large', color=color,
+ add_text_func(size='large', color=color,
horizontalalignment='right'))
-
+
# Graph type is orthogonal in 2D
else:
# X coordinate labels are in figure lower side
@@ -1059,7 +1059,7 @@
self.Labels.append(
add_text_func(size='large',
horizontalalignment='right'))
-
+
# Y coordinate labels are vertical and in figure left side
self.AxesLabels.append(
add_text_func(size='small', rotation='vertical',
@@ -1067,11 +1067,11 @@
self.Labels.append(
add_text_func(size='large', rotation='vertical',
verticalalignment='top'))
-
+
# Refresh position of labels according to Viewer size
width, height = self.GetSize()
self.RefreshLabelsPosition(height)
-
+
def RefreshLabelsPosition(self, height):
"""
Function called when mouse leave Viewer
@@ -1087,30 +1087,30 @@
graph_ratio = 1. / (
(1.0 - (CANVAS_BORDER[0] + CANVAS_BORDER[1]) * canvas_ratio)
* height) # Divide by figure height in pixel
-
+
# Update position of figure (keeping up and bottom border the same
# size)
self.Figure.subplotpars.update(
- top= 1.0 - CANVAS_BORDER[1] * canvas_ratio,
+ top= 1.0 - CANVAS_BORDER[1] * canvas_ratio,
bottom= CANVAS_BORDER[0] * canvas_ratio)
-
+
# Update position of items labels
if self.GraphType == GRAPH_PARALLEL or self.Is3DCanvas():
num_item = len(self.Items)
for idx in xrange(num_item):
-
+
# In 3D graph items variable label are not displayed
if not self.Is3DCanvas():
# Items variable labels are in figure upper left corner
self.AxesLabels[idx].set_position(
- (0.05,
- 1.0 - (CANVAS_PADDING +
+ (0.05,
+ 1.0 - (CANVAS_PADDING +
AXES_LABEL_HEIGHT * idx) * graph_ratio))
-
+
# Items variable labels are in figure lower right corner
self.Labels[idx].set_position(
- (0.95,
- CANVAS_PADDING * graph_ratio +
+ (0.95,
+ CANVAS_PADDING * graph_ratio +
(num_item - idx - 1) * VALUE_LABEL_HEIGHT * graph_ratio))
else:
# X coordinate labels are in figure lower side
@@ -1118,16 +1118,16 @@
(0.1, CANVAS_PADDING * graph_ratio))
self.Labels[0].set_position(
(0.95, CANVAS_PADDING * graph_ratio))
-
+
# Y coordinate labels are vertical and in figure left side
self.AxesLabels[1].set_position(
(0.05, 2 * CANVAS_PADDING * graph_ratio))
self.Labels[1].set_position(
(0.05, 1.0 - CANVAS_PADDING * graph_ratio))
-
+
# Update subplots
self.Figure.subplots_adjust()
-
+
def RefreshViewer(self, refresh_graphics=True):
"""
Function called to refresh displayed by matplotlib canvas
@@ -1138,55 +1138,55 @@
if refresh_graphics:
# Get tick range of values to display
start_tick, end_tick = self.ParentWindow.GetRange()
-
+
# Graph is parallel
- if self.GraphType == GRAPH_PARALLEL:
+ if self.GraphType == GRAPH_PARALLEL:
# Init list of data range for each variable displayed
ranges = []
-
+
# Get data and range for each variable displayed
for idx, item in enumerate(self.Items):
data, min_value, max_value = item.GetDataAndValueRange(
start_tick, end_tick, not self.ZoomFit)
-
+
# Check that data is not empty
if data is not None:
# Add variable range to list of variable data range
ranges.append((min_value, max_value))
-
+
# Add plot to canvas if not yet created
if len(self.Plots) <= idx:
self.Plots.append(
self.Axes.plot(data[:, 0], data[:, 1])[0])
-
+
# Set data to already created plot in canvas
else:
self.Plots[idx].set_data(data[:, 0], data[:, 1])
-
+
# Get X and Y axis ranges
x_min, x_max = start_tick, end_tick
y_min, y_max = merge_ranges(ranges)
-
+
# Display cursor in canvas if a cursor tick is defined and it is
# include in values tick range
- if (self.CursorTick is not None and
+ if (self.CursorTick is not None and
start_tick <= self.CursorTick <= end_tick):
-
+
# Define a vertical line to display cursor position if no
# line is already defined
if self.VLine is None:
- self.VLine = self.Axes.axvline(self.CursorTick,
+ self.VLine = self.Axes.axvline(self.CursorTick,
color=CURSOR_COLOR)
-
+
# Set value of vertical line if already defined
else:
self.VLine.set_xdata((self.CursorTick, self.CursorTick))
self.VLine.set_visible(True)
-
+
# Hide vertical line if cursor tick is not defined or reset
elif self.VLine is not None:
self.VLine.set_visible(False)
-
+
# Graph is orthogonal
else:
# Update tick range, removing ticks that don't have a value for
@@ -1194,76 +1194,76 @@
start_tick = max(start_tick, self.GetItemsMinCommonTick())
end_tick = max(end_tick, start_tick)
items = self.ItemsDict.values()
-
+
# Get data and range for first variable (X coordinate)
x_data, x_min, x_max = items[0].GetDataAndValueRange(
start_tick, end_tick, not self.ZoomFit)
# Get data and range for second variable (Y coordinate)
y_data, y_min, y_max = items[1].GetDataAndValueRange(
start_tick, end_tick, not self.ZoomFit)
-
+
# Normalize X and Y coordinates value range
x_min, x_max = merge_ranges([(x_min, x_max)])
y_min, y_max = merge_ranges([(y_min, y_max)])
-
- # Get X and Y coordinates for cursor if cursor tick is defined
+
+ # Get X and Y coordinates for cursor if cursor tick is defined
if self.CursorTick is not None:
x_cursor, x_forced = items[0].GetValue(
self.CursorTick, raw=True)
y_cursor, y_forced = items[1].GetValue(
self.CursorTick, raw=True)
-
+
# Get common data length so that each value has an x and y
# coordinate
length = (min(len(x_data), len(y_data))
if x_data is not None and y_data is not None
else 0)
-
- # Graph is orthogonal 2D
+
+ # Graph is orthogonal 2D
if len(self.Items) < 3:
-
+
# Check that x and y data are not empty
if x_data is not None and y_data is not None:
-
+
# Add plot to canvas if not yet created
if len(self.Plots) == 0:
self.Plots.append(
- self.Axes.plot(x_data[:, 1][:length],
+ self.Axes.plot(x_data[:, 1][:length],
y_data[:, 1][:length])[0])
-
+
# Set data to already created plot in canvas
else:
self.Plots[0].set_data(
- x_data[:, 1][:length],
+ x_data[:, 1][:length],
y_data[:, 1][:length])
-
+
# Display cursor in canvas if a cursor tick is defined and it is
# include in values tick range
- if (self.CursorTick is not None and
+ if (self.CursorTick is not None and
start_tick <= self.CursorTick <= end_tick):
-
+
# Define a vertical line to display cursor x coordinate
# if no line is already defined
if self.VLine is None:
- self.VLine = self.Axes.axvline(x_cursor,
+ self.VLine = self.Axes.axvline(x_cursor,
color=CURSOR_COLOR)
# Set value of vertical line if already defined
else:
self.VLine.set_xdata((x_cursor, x_cursor))
-
-
+
+
# Define a horizontal line to display cursor y
# coordinate if no line is already defined
if self.HLine is None:
- self.HLine = self.Axes.axhline(y_cursor,
+ self.HLine = self.Axes.axhline(y_cursor,
color=CURSOR_COLOR)
# Set value of horizontal line if already defined
else:
self.HLine.set_ydata((y_cursor, y_cursor))
-
+
self.VLine.set_visible(True)
self.HLine.set_visible(True)
-
+
# Hide vertical and horizontal line if cursor tick is not
# defined or reset
else:
@@ -1271,42 +1271,42 @@
self.VLine.set_visible(False)
if self.HLine is not None:
self.HLine.set_visible(False)
-
+
# Graph is orthogonal 3D
else:
# Remove all plots already defined in 3D canvas
while len(self.Axes.lines) > 0:
self.Axes.lines.pop()
-
+
# Get data and range for third variable (Z coordinate)
z_data, z_min, z_max = items[2].GetDataAndValueRange(
start_tick, end_tick, not self.ZoomFit)
-
+
# Normalize Z coordinate value range
z_min, z_max = merge_ranges([(z_min, z_max)])
-
+
# Check that x, y and z data are not empty
- if (x_data is not None and y_data is not None and
+ if (x_data is not None and y_data is not None and
z_data is not None):
-
+
# Get common data length so that each value has an x, y
# and z coordinate
length = min(length, len(z_data))
-
+
# Add plot to canvas
self.Axes.plot(x_data[:, 1][:length],
y_data[:, 1][:length],
zs = z_data[:, 1][:length])
-
+
# Display cursor in canvas if a cursor tick is defined and
# it is include in values tick range
- if (self.CursorTick is not None and
+ if (self.CursorTick is not None and
start_tick <= self.CursorTick <= end_tick):
-
+
# Get Z coordinate for cursor
z_cursor, z_forced = items[2].GetValue(
self.CursorTick, raw=True)
-
+
# Add 3 lines parallel to x, y and z axis to display
# cursor position in 3D
for kwargs in [{"xs": numpy.array([x_min, x_max])},
@@ -1319,14 +1319,14 @@
kwargs.setdefault(param, value)
kwargs["color"] = CURSOR_COLOR
self.Axes.plot(**kwargs)
-
+
# Set Z axis limits
self.Axes.set_zlim(z_min, z_max)
-
+
# Set X and Y axis limits
self.Axes.set_xlim(x_min, x_max)
self.Axes.set_ylim(y_min, y_max)
-
+
# Get value and forced flag for each variable displayed in graph
# If cursor tick is not defined get value and flag of last received
# or get value and flag of variable at cursor tick
@@ -1335,34 +1335,34 @@
if self.CursorTick is not None
else (item.GetValue(), item.IsForced()))
for item in self.Items])
-
+
# Get path of each variable displayed simplified using panel variable
# name mask
- labels = [item.GetVariable(self.ParentWindow.GetVariableNameMask())
+ labels = [item.GetVariable(self.ParentWindow.GetVariableNameMask())
for item in self.Items]
-
- # Get style for each variable according to
+
+ # Get style for each variable according to
styles = map(lambda x: {True: 'italic', False: 'normal'}[x], forced)
-
+
# Graph is orthogonal 3D, set variables path as 3D axis label
if self.Is3DCanvas():
- for idx, label_func in enumerate([self.Axes.set_xlabel,
+ for idx, label_func in enumerate([self.Axes.set_xlabel,
self.Axes.set_ylabel,
self.Axes.set_zlabel]):
label_func(labels[idx], fontdict={'size': 'small',
'color': COLOR_CYCLE[idx]})
-
+
# Graph is not orthogonal 3D, set variables path in axes labels
else:
for label, text in zip(self.AxesLabels, labels):
label.set_text(text)
-
+
# Set value label text and style according to value and forced flag for
# each variable displayed
for label, value, style in zip(self.Labels, values, styles):
label.set_text(value)
label.set_style(style)
-
+
# Refresh figure
self.draw()
@@ -1372,51 +1372,49 @@
"""
# Render figure using agg
FigureCanvasAgg.draw(self)
-
+
# Get bitmap of figure rendered
self.bitmap = _convert_agg_to_wx_bitmap(self.get_renderer(), None)
- if wx.VERSION < (3, 0, 0):
+ if wx.VERSION < (3, 0, 0):
self.bitmap.UseAlpha()
-
+
# Create DC for rendering graphics in bitmap
destDC = wx.MemoryDC()
destDC.SelectObject(self.bitmap)
-
+
# Get Graphics Context for DC, for anti-aliased and transparent
# rendering
destGC = wx.GCDC(destDC)
-
+
destGC.BeginDrawing()
-
+
# Get canvas size and figure bounding box in canvas
width, height = self.GetSize()
bbox = self.GetAxesBoundingBox()
-
+
# If highlight to display is resize, draw thick grey line at bottom
- # side of canvas
+ # side of canvas
if self.Highlight == HIGHLIGHT_RESIZE:
destGC.SetPen(HIGHLIGHT_RESIZE_PEN)
destGC.SetBrush(HIGHLIGHT_RESIZE_BRUSH)
destGC.DrawRectangle(0, height - 5, width, 5)
-
+
# If highlight to display is merging graph, draw 50% transparent blue
# rectangle on left or right part of figure depending on highlight type
elif self.Highlight in [HIGHLIGHT_LEFT, HIGHLIGHT_RIGHT]:
destGC.SetPen(HIGHLIGHT_DROP_PEN)
destGC.SetBrush(HIGHLIGHT_DROP_BRUSH)
-
- x_offset = (bbox.width / 2
+
+ x_offset = (bbox.width / 2
if self.Highlight == HIGHLIGHT_RIGHT
else 0)
- destGC.DrawRectangle(bbox.x + x_offset, bbox.y,
+ destGC.DrawRectangle(bbox.x + x_offset, bbox.y,
bbox.width / 2, bbox.height)
-
+
# Draw other Viewer common elements
self.DrawCommonElements(destGC, self.GetButtons())
-
+
destGC.EndDrawing()
-
+
self._isDrawn = True
self.gui_repaint(drawDC=drawDC)
-
-
--- a/controls/DebugVariablePanel/DebugVariableItem.py Fri Aug 11 15:18:19 2017 +0300
+++ b/controls/DebugVariablePanel/DebugVariableItem.py Mon Aug 14 19:13:01 2017 +0300
@@ -44,7 +44,7 @@
"""
class DebugVariableItem(DebugDataConsumer):
-
+
def __init__(self, parent, variable, store_data=False):
"""
Constructor
@@ -52,24 +52,24 @@
@param variable: Path of variable to debug
"""
DebugDataConsumer.__init__(self)
-
+
self.Parent = parent
self.Variable = variable
self.StoreData = store_data
-
+
# Get Variable data type
self.RefreshVariableType()
-
+
def __del__(self):
"""
Destructor
"""
# Reset reference to debug variable panel
self.Parent = None
-
+
def SetVariable(self, variable):
"""
- Set path of variable
+ Set path of variable
@param variable: Path of variable to debug
"""
if self.Parent is not None and self.Variable != variable:
@@ -77,46 +77,46 @@
self.Variable = variable
# Get Variable data type
self.RefreshVariableType()
-
+
# Refresh debug variable panel
self.Parent.RefreshView()
-
+
def GetVariable(self, mask=None):
"""
- Return path of variable
+ Return path of variable
@param mask: Mask to apply to variable path [var_name, '*',...]
@return: String containing masked variable path
"""
# Apply mask to variable name
if mask is not None:
# '#' correspond to parts that are different between all items
-
+
# Extract variable path parts
parts = self.Variable.split('.')
# Adjust mask size to size of variable path
mask = mask + ['*'] * max(0, len(parts) - len(mask))
-
+
# Store previous mask
last = None
# Init masked variable path
variable = ""
-
+
for m, p in zip(mask, parts):
# Part is not masked, add part prefixed with '.' is previous
# wasn't masked
if m == '*':
variable += ('.' if last == '*' else '') + p
-
+
# Part is mask, add '..' if first or previous wasn't masked
elif last is None or last == '*':
variable += '..'
-
+
last = m
-
+
return variable
-
+
return self.Variable
-
+
def RefreshVariableType(self):
"""
Get and store variable data type
@@ -124,14 +124,14 @@
self.VariableType = self.Parent.GetDataType(self.Variable)
# Reset data stored
self.ResetData()
-
+
def GetVariableType(self):
"""
Return variable data type
@return: Variable data type
"""
return self.VariableType
-
+
def GetData(self, start_tick=None, end_tick=None):
"""
Return data stored contained in given range
@@ -142,7 +142,7 @@
# Return immediately if data empty or none
if self.Data is None or len(self.Data) == 0:
return self.Data
-
+
# Find nearest data outside given range indexes
start_idx = (self.GetNearestData(start_tick, -1)
if start_tick is not None
@@ -150,10 +150,10 @@
end_idx = (self.GetNearestData(end_tick, 1)
if end_tick is not None
else len(self.Data))
-
+
# Return data between indexes
return self.Data[start_idx:end_idx]
-
+
def GetRawValue(self, index):
"""
Return raw value at given index for string variables
@@ -164,14 +164,14 @@
index < len(self.RawData)):
return self.RawData[index][0]
return ""
-
+
def GetValueRange(self):
"""
Return variable value range
@return: (minimum_value, maximum_value)
"""
return self.MinValue, self.MaxValue
-
+
def GetDataAndValueRange(self, start_tick, end_tick, full_range=True):
"""
Return variable data and value range for a given tick range
@@ -179,16 +179,16 @@
@param end_tick: end tick of given range (default None, last data)
@param full_range: Value range is calculated on whole data (False: only
calculated on data in given range)
- @return: (numpy.array([(tick, value, forced),...]),
+ @return: (numpy.array([(tick, value, forced),...]),
min_value, max_value)
"""
# Get data in given tick range
data = self.GetData(start_tick, end_tick)
-
+
# Value range is calculated on whole data
if full_range:
return data, self.MinValue, self.MaxValue
-
+
# Check that data in given range is not empty
values = data[:, 1]
if len(values) > 0:
@@ -196,10 +196,10 @@
return (data,
data[numpy.argmin(values), 1],
data[numpy.argmax(values), 1])
-
+
# Return default values
return data, None, None
-
+
def ResetData(self):
"""
Reset data stored when store data option enabled
@@ -207,31 +207,31 @@
if self.StoreData and self.IsNumVariable():
# Init table storing data
self.Data = numpy.array([]).reshape(0, 3)
-
+
# Init table storing raw data if variable is strin
self.RawData = ([]
if self.VariableType in ["STRING", "WSTRING"]
else None)
-
+
# Init Value range variables
self.MinValue = None
self.MaxValue = None
-
+
else:
self.Data = None
-
+
# Init variable value
self.Value = ""
-
+
def IsNumVariable(self):
"""
Return if variable data type is numeric. String variables are
considered as numeric (string CRC)
@return: True if data type is numeric
"""
- return (self.Parent.IsNumType(self.VariableType) or
+ return (self.Parent.IsNumType(self.VariableType) or
self.VariableType in ["STRING", "WSTRING"])
-
+
def NewValues(self, ticks, values):
"""
Function called by debug thread when a new debug value is available
@@ -240,24 +240,24 @@
@param forced: Forced flag, True if value is forced (default: False)
"""
DebugDataConsumer.NewValues(self, ticks[-1], values[-1], raw=None)
-
+
if self.Data is not None:
-
+
if self.VariableType in ["STRING", "WSTRING"]:
last_raw_data = (self.RawData[-1]
if len(self.RawData) > 0 else None)
last_raw_data_idx = len(self.RawData) - 1
-
+
data_values = []
for tick, (value, forced) in zip(ticks, values):
# Translate forced flag to float for storing in Data table
forced_value = float(forced)
-
+
# String data value is CRC
num_value = (binascii.crc32(value) & STRING_CRC_MASK
if self.VariableType in ["STRING", "WSTRING"]
else float(value))
-
+
# Update variable range values
self.MinValue = (min(self.MinValue, num_value)
if self.MinValue is not None
@@ -265,10 +265,10 @@
self.MaxValue = (max(self.MaxValue, num_value)
if self.MaxValue is not None
else num_value)
-
+
# In the case of string variables, we store raw string value and
# forced flag in raw data table. Only changes in this two values
- # are stored. Index to the corresponding raw value is stored in
+ # are stored. Index to the corresponding raw value is stored in
# data third column
if self.VariableType in ["STRING", "WSTRING"]:
raw_data = (value, forced_value)
@@ -277,20 +277,20 @@
last_raw_data = raw_data
self.RawData.append(raw_data)
extra_value = last_raw_data_idx
-
+
# In other case, data third column is forced flag
else:
extra_value = forced_value
-
+
data_values.append(
[float(tick), num_value, extra_value])
-
+
# Add New data to stored data table
self.Data = numpy.append(self.Data, data_values, axis=0)
-
+
# Signal to debug variable panel to refresh
self.Parent.HasNewData = True
-
+
def SetForced(self, forced):
"""
Update Forced flag
@@ -299,10 +299,10 @@
# Store forced flag
if self.Forced != forced:
self.Forced = forced
-
+
# Signal to debug variable panel to refresh
self.Parent.HasNewData = True
-
+
def SetValue(self, value):
"""
Update value.
@@ -314,14 +314,14 @@
self.VariableType == "WSTRING" and
value.startswith('"') and value.endswith('"')):
value = value[1:-1]
-
+
# Store variable value
if self.Value != value:
self.Value = value
-
+
# Signal to debug variable panel to refresh
self.Parent.HasNewData = True
-
+
def GetValue(self, tick=None, raw=False):
"""
Return current value or value and forced flag for tick given
@@ -329,26 +329,26 @@
"""
# If tick given and stored data option enabled
if tick is not None and self.Data is not None:
-
+
# Return current value and forced flag if data empty
if len(self.Data) == 0:
return self.Value, self.IsForced()
-
+
# Get index of nearest data from tick given
idx = self.GetNearestData(tick, 0)
-
+
# Get value and forced flag at given index
value, forced = self.RawData[int(self.Data[idx, 2])] \
if self.VariableType in ["STRING", "WSTRING"] \
else self.Data[idx, 1:3]
-
+
# Get raw value if asked
if not raw:
value = TYPE_TRANSLATOR.get(
self.VariableType, str)(value)
-
+
return value, forced
-
+
# Return raw value if asked
if not raw and self.VariableType in ["STRING", "WSTRING"]:
return TYPE_TRANSLATOR.get(
@@ -368,16 +368,16 @@
# Return immediately if data is empty
if self.Data is None:
return None
-
+
# Extract data ticks
ticks = self.Data[:, 0]
-
+
# Get nearest data from tick
idx = numpy.argmin(abs(ticks - tick))
-
+
# Adjust data index according to constraint
if (adjust < 0 and ticks[idx] > tick and idx > 0 or
adjust > 0 and ticks[idx] < tick and idx < len(ticks)):
idx += adjust
-
+
return idx
--- a/controls/DebugVariablePanel/DebugVariablePanel.py Fri Aug 11 15:18:19 2017 +0300
+++ b/controls/DebugVariablePanel/DebugVariablePanel.py Mon Aug 14 19:13:01 2017 +0300
@@ -67,11 +67,11 @@
for item, data in variables:
if len(data) == 0:
continue
-
+
next_tick = (data[0][0]
if next_tick is None
else min(next_tick, data[0][0]))
-
+
return next_tick
#-------------------------------------------------------------------------------
@@ -84,7 +84,7 @@
"""
class DebugVariableDropTarget(wx.TextDropTarget):
-
+
def __init__(self, window):
"""
Constructor
@@ -92,14 +92,14 @@
"""
wx.TextDropTarget.__init__(self)
self.ParentWindow = window
-
+
def __del__(self):
"""
Destructor
"""
# Remove reference to Debug Variable Panel
self.ParentWindow = None
-
+
def OnDragOver(self, x, y, d):
"""
Function called when mouse is dragged over Drop Target
@@ -110,7 +110,7 @@
# Signal Debug Variable Panel to refresh highlight giving mouse position
self.ParentWindow.RefreshHighlight(x, y)
return wx.TextDropTarget.OnDragOver(self, x, y, d)
-
+
def OnDropText(self, x, y, data):
"""
Function called when mouse is released in Drop Target
@@ -120,9 +120,9 @@
"""
# Signal Debug Variable Panel to reset highlight
self.ParentWindow.ResetHighlight()
-
+
message = None
-
+
# Check that data is valid regarding DebugVariablePanel
try:
values = eval(data)
@@ -131,23 +131,23 @@
except:
message = _("Invalid value \"%s\" for debug variable")%data
values = None
-
+
# Display message if data is invalid
if message is not None:
wx.CallAfter(self.ShowMessage, message)
-
+
# Data contain a reference to a variable to debug
elif values[1] == "debug":
-
+
# Drag'n Drop is an internal is an internal move inside Debug
- # Variable Panel
+ # Variable Panel
if len(values) > 2 and values[2] == "move":
self.ParentWindow.MoveValue(values[0])
-
+
# Drag'n Drop was initiated by another control of Beremiz
else:
self.ParentWindow.InsertValue(values[0], force=True)
-
+
def OnLeave(self):
"""
Function called when mouse is leave Drop Target
@@ -155,15 +155,15 @@
# Signal Debug Variable Panel to reset highlight
self.ParentWindow.ResetHighlight()
return wx.TextDropTarget.OnLeave(self)
-
+
def ShowMessage(self, message):
"""
Show error message in Error Dialog
@param message: Error message to display
"""
- dialog = wx.MessageDialog(self.ParentWindow,
- message,
- _("Error"),
+ dialog = wx.MessageDialog(self.ParentWindow,
+ message,
+ _("Error"),
wx.OK|wx.ICON_ERROR)
dialog.ShowModal()
dialog.Destroy()
@@ -178,7 +178,7 @@
"""
class DebugVariablePanel(wx.Panel, DebugViewer):
-
+
def __init__(self, parent, producer, window):
"""
Constructor
@@ -188,48 +188,48 @@
@param window: Reference to Beremiz frame
"""
wx.Panel.__init__(self, parent, style=wx.SP_3D|wx.TAB_TRAVERSAL)
-
+
# Save Reference to Beremiz frame
self.ParentWindow = window
-
+
# Variable storing flag indicating that variable displayed in table
# received new value and then table need to be refreshed
self.HasNewData = False
-
+
# Variable storing flag indicating that refresh has been forced, and
# that next time refresh is possible, it will be done even if no new
# data is available
self.Force = False
-
+
self.SetBackgroundColour(wx.WHITE)
-
+
main_sizer = wx.BoxSizer(wx.VERTICAL)
-
+
self.Ticks = numpy.array([]) # List of tick received
self.StartTick = 0 # Tick starting range of data displayed
self.Fixed = False # Flag that range of data is fixed
self.CursorTick = None # Tick of cursor for displaying values
-
+
self.DraggingAxesPanel = None
self.DraggingAxesBoundingBox = None
self.DraggingAxesMousePos = None
self.VetoScrollEvent = False
-
+
self.VariableNameMask = []
-
+
self.GraphicPanels = []
-
+
graphics_button_sizer = wx.BoxSizer(wx.HORIZONTAL)
main_sizer.AddSizer(graphics_button_sizer, border=5, flag=wx.GROW|wx.ALL)
-
+
range_label = wx.StaticText(self, label=_('Range:'))
graphics_button_sizer.AddWindow(range_label, flag=wx.ALIGN_CENTER_VERTICAL)
-
+
self.CanvasRange = wx.ComboBox(self, style=wx.CB_READONLY)
self.Bind(wx.EVT_COMBOBOX, self.OnRangeChanged, self.CanvasRange)
- graphics_button_sizer.AddWindow(self.CanvasRange, 1,
+ graphics_button_sizer.AddWindow(self.CanvasRange, 1,
border=5, flag=wx.LEFT|wx.ALIGN_CENTER_VERTICAL)
-
+
self.CanvasRange.Clear()
default_range_idx = 0
for idx, (text, value) in enumerate(RANGE_VALUES):
@@ -237,44 +237,44 @@
if text == "1s":
default_range_idx = idx
self.CanvasRange.SetSelection(default_range_idx)
-
+
for name, bitmap, help in [
("CurrentButton", "current", _("Go to current value")),
("ExportGraphButton", "export_graph", _("Export graph values to clipboard"))]:
- button = wx.lib.buttons.GenBitmapButton(self,
- bitmap=GetBitmap(bitmap),
+ button = wx.lib.buttons.GenBitmapButton(self,
+ bitmap=GetBitmap(bitmap),
size=wx.Size(28, 28), style=wx.NO_BORDER)
button.SetToolTipString(help)
setattr(self, name, button)
self.Bind(wx.EVT_BUTTON, getattr(self, "On" + name), button)
graphics_button_sizer.AddWindow(button, border=5, flag=wx.LEFT)
-
- self.CanvasPosition = wx.ScrollBar(self,
+
+ self.CanvasPosition = wx.ScrollBar(self,
size=wx.Size(0, 16), style=wx.SB_HORIZONTAL)
- self.CanvasPosition.Bind(wx.EVT_SCROLL_THUMBTRACK,
+ self.CanvasPosition.Bind(wx.EVT_SCROLL_THUMBTRACK,
self.OnPositionChanging, self.CanvasPosition)
- self.CanvasPosition.Bind(wx.EVT_SCROLL_LINEUP,
+ self.CanvasPosition.Bind(wx.EVT_SCROLL_LINEUP,
self.OnPositionChanging, self.CanvasPosition)
- self.CanvasPosition.Bind(wx.EVT_SCROLL_LINEDOWN,
+ self.CanvasPosition.Bind(wx.EVT_SCROLL_LINEDOWN,
self.OnPositionChanging, self.CanvasPosition)
- self.CanvasPosition.Bind(wx.EVT_SCROLL_PAGEUP,
+ self.CanvasPosition.Bind(wx.EVT_SCROLL_PAGEUP,
self.OnPositionChanging, self.CanvasPosition)
- self.CanvasPosition.Bind(wx.EVT_SCROLL_PAGEDOWN,
+ self.CanvasPosition.Bind(wx.EVT_SCROLL_PAGEDOWN,
self.OnPositionChanging, self.CanvasPosition)
main_sizer.AddWindow(self.CanvasPosition, border=5, flag=wx.GROW|wx.LEFT|wx.RIGHT|wx.BOTTOM)
-
+
self.TickSizer = wx.BoxSizer(wx.HORIZONTAL)
main_sizer.AddSizer(self.TickSizer, border=5, flag=wx.ALL|wx.GROW)
-
+
self.TickLabel = wx.StaticText(self)
self.TickSizer.AddWindow(self.TickLabel, border=5, flag=wx.RIGHT)
-
+
self.MaskLabel = wx.TextCtrl(self, style=wx.TE_READONLY|wx.TE_CENTER|wx.NO_BORDER)
self.TickSizer.AddWindow(self.MaskLabel, 1, border=5, flag=wx.RIGHT|wx.GROW)
-
+
self.TickTimeLabel = wx.StaticText(self)
self.TickSizer.AddWindow(self.TickTimeLabel)
-
+
self.GraphicsWindow = wx.ScrolledWindow(self, style=wx.HSCROLL|wx.VSCROLL)
self.GraphicsWindow.SetBackgroundColour(wx.WHITE)
self.GraphicsWindow.SetDropTarget(DebugVariableDropTarget(self))
@@ -282,17 +282,17 @@
self.GraphicsWindow.Bind(wx.EVT_PAINT, self.OnGraphicsWindowPaint)
self.GraphicsWindow.Bind(wx.EVT_SIZE, self.OnGraphicsWindowResize)
self.GraphicsWindow.Bind(wx.EVT_MOUSEWHEEL, self.OnGraphicsWindowMouseWheel)
-
+
main_sizer.AddWindow(self.GraphicsWindow, 1, flag=wx.GROW)
-
+
self.GraphicsSizer = wx.BoxSizer(wx.VERTICAL)
self.GraphicsWindow.SetSizer(self.GraphicsSizer)
-
+
DebugViewer.__init__(self, producer, True)
-
+
self.SetSizer(main_sizer)
self.SetTickTime()
-
+
def SetTickTime(self, ticktime=0):
"""
Set Ticktime for calculate data range according to time range selected
@@ -300,26 +300,26 @@
"""
# Save ticktime
self.Ticktime = ticktime
-
+
# Set ticktime to millisecond if undefined
if self.Ticktime == 0:
self.Ticktime = MILLISECOND
-
+
# Calculate range to apply to data
self.CurrentRange = RANGE_VALUES[
self.CanvasRange.GetSelection()][1] / self.Ticktime
-
+
def SetDataProducer(self, producer):
"""
Set Data Producer
@param producer: Data Producer
"""
DebugViewer.SetDataProducer(self, producer)
-
+
# Set ticktime if data producer is available
if self.DataProducer is not None:
self.SetTickTime(self.DataProducer.GetTicktime())
-
+
def RefreshNewData(self):
"""
Called to refresh Panel according to values received by variables
@@ -329,50 +329,50 @@
if self.HasNewData or self.Force:
self.HasNewData = False
self.RefreshView()
-
+
DebugViewer.RefreshNewData(self)
-
+
def NewDataAvailable(self, ticks):
"""
Called by DataProducer for each tick captured or by panel to refresh
graphs
@param tick: PLC tick captured
- All other parameters are passed to refresh function
+ All other parameters are passed to refresh function
"""
# If tick given
if ticks is not None:
tick = ticks[-1]
-
+
# Save tick as start tick for range if data is still empty
if len(self.Ticks) == 0:
self.StartTick = ticks[0]
-
+
# Add tick to list of ticks received
self.Ticks = numpy.append(self.Ticks, ticks)
-
+
# Update start tick for range if range follow ticks received
if not self.Fixed or tick < self.StartTick + self.CurrentRange:
self.StartTick = max(self.StartTick, tick - self.CurrentRange)
-
+
# Force refresh if graph is fixed because range of data received
# is too small to fill data range selected
if self.Fixed and \
self.Ticks[-1] - self.Ticks[0] < self.CurrentRange:
self.Force = True
-
+
self.HasNewData = False
self.RefreshView()
-
+
else:
DebugViewer.NewDataAvailable(self, ticks)
-
+
def ForceRefresh(self):
"""
Called to force refresh of graphs
"""
self.Force = True
wx.CallAfter(self.NewDataAvailable, None)
-
+
def SetCursorTick(self, cursor_tick):
"""
Set Cursor for displaying values of items at a tick given
@@ -381,37 +381,37 @@
# Save cursor tick
self.CursorTick = cursor_tick
self.Fixed = cursor_tick is not None
- self.UpdateCursorTick()
-
+ self.UpdateCursorTick()
+
def MoveCursorTick(self, move):
if self.CursorTick is not None:
- cursor_tick = max(self.Ticks[0],
- min(self.CursorTick + move,
+ cursor_tick = max(self.Ticks[0],
+ min(self.CursorTick + move,
self.Ticks[-1]))
cursor_tick_idx = numpy.argmin(numpy.abs(self.Ticks - cursor_tick))
if self.Ticks[cursor_tick_idx] == self.CursorTick:
- cursor_tick_idx = max(0,
- min(cursor_tick_idx + abs(move) / move,
+ cursor_tick_idx = max(0,
+ min(cursor_tick_idx + abs(move) / move,
len(self.Ticks) - 1))
self.CursorTick = self.Ticks[cursor_tick_idx]
self.StartTick = max(self.Ticks[
- numpy.argmin(numpy.abs(self.Ticks -
+ numpy.argmin(numpy.abs(self.Ticks -
self.CursorTick + self.CurrentRange))],
min(self.StartTick, self.CursorTick))
self.RefreshCanvasPosition()
- self.UpdateCursorTick()
-
+ self.UpdateCursorTick()
+
def ResetCursorTick(self):
self.CursorTick = None
self.Fixed = False
self.UpdateCursorTick()
-
+
def UpdateCursorTick(self):
for panel in self.GraphicPanels:
if isinstance(panel, DebugVariableGraphicViewer):
panel.SetCursorTick(self.CursorTick)
self.ForceRefresh()
-
+
def StartDragNDrop(self, panel, item, x_mouse, y_mouse, x_mouse_start, y_mouse_start):
if len(panel.GetItems()) > 1:
self.DraggingAxesPanel = DebugVariableGraphicViewer(self.GraphicsWindow, self, [item], GRAPH_PARALLEL)
@@ -424,21 +424,21 @@
self.DraggingAxesPanel = panel
self.DraggingAxesBoundingBox = panel.GetAxesBoundingBox(parent_coordinate=True)
self.DraggingAxesMousePos = wx.Point(
- x_mouse_start - self.DraggingAxesBoundingBox.x,
+ x_mouse_start - self.DraggingAxesBoundingBox.x,
y_mouse_start - self.DraggingAxesBoundingBox.y)
self.MoveDragNDrop(x_mouse, y_mouse)
-
+
def MoveDragNDrop(self, x_mouse, y_mouse):
self.DraggingAxesBoundingBox.x = x_mouse - self.DraggingAxesMousePos.x
self.DraggingAxesBoundingBox.y = y_mouse - self.DraggingAxesMousePos.y
self.RefreshHighlight(x_mouse, y_mouse)
-
+
def RefreshHighlight(self, x_mouse, y_mouse):
for idx, panel in enumerate(self.GraphicPanels):
x, y = panel.GetPosition()
width, height = panel.GetSize()
rect = wx.Rect(x, y, width, height)
- if (rect.InsideXY(x_mouse, y_mouse) or
+ if (rect.InsideXY(x_mouse, y_mouse) or
idx == 0 and y_mouse < 0 or
idx == len(self.GraphicPanels) - 1 and y_mouse > panel.GetPosition()[1]):
panel.RefreshHighlight(x_mouse - x, y_mouse - y)
@@ -448,7 +448,7 @@
self.RefreshView()
else:
self.ForceRefresh()
-
+
def ResetHighlight(self):
for panel in self.GraphicPanels:
panel.SetHighlight(HIGHLIGHT_NONE)
@@ -456,10 +456,10 @@
self.RefreshView()
else:
self.ForceRefresh()
-
+
def IsDragging(self):
return self.DraggingAxesPanel is not None
-
+
def GetDraggingAxesClippingRegion(self, panel):
x, y = panel.GetPosition()
width, height = panel.GetSize()
@@ -468,12 +468,12 @@
bbox.x -= x
bbox.y -= y
return bbox
-
+
def GetDraggingAxesPosition(self, panel):
x, y = panel.GetPosition()
return wx.Point(self.DraggingAxesBoundingBox.x - x,
self.DraggingAxesBoundingBox.y - y)
-
+
def StopDragNDrop(self, variable, x_mouse, y_mouse):
if self.DraggingAxesPanel not in self.GraphicPanels:
self.DraggingAxesPanel.Destroy()
@@ -504,25 +504,25 @@
idx += 1
wx.CallAfter(self.MoveValue, variable, idx, True)
self.ForceRefresh()
- return
+ return
width, height = self.GraphicsWindow.GetVirtualSize()
rect = wx.Rect(0, 0, width, height)
if rect.InsideXY(x_mouse, y_mouse):
wx.CallAfter(self.MoveValue, variable, len(self.GraphicPanels), True)
self.ForceRefresh()
-
+
def RefreshGraphicsSizer(self):
self.GraphicsSizer.Clear()
-
+
for panel in self.GraphicPanels:
self.GraphicsSizer.AddWindow(panel, flag=wx.GROW)
-
+
self.GraphicsSizer.Layout()
self.RefreshGraphicsWindowScrollbars()
-
+
def RefreshView(self):
self.RefreshCanvasPosition()
-
+
width, height = self.GraphicsWindow.GetVirtualSize()
bitmap = wx.EmptyBitmap(width, height)
dc = wx.BufferedDC(wx.ClientDC(self.GraphicsWindow), bitmap)
@@ -531,22 +531,22 @@
if self.DraggingAxesPanel is not None:
destBBox = self.DraggingAxesBoundingBox
srcBBox = self.DraggingAxesPanel.GetAxesBoundingBox()
-
+
srcBmp = _convert_agg_to_wx_bitmap(self.DraggingAxesPanel.get_renderer(), None)
srcDC = wx.MemoryDC()
srcDC.SelectObject(srcBmp)
-
- dc.Blit(destBBox.x, destBBox.y,
- int(destBBox.width), int(destBBox.height),
+
+ dc.Blit(destBBox.x, destBBox.y,
+ int(destBBox.width), int(destBBox.height),
srcDC, srcBBox.x, srcBBox.y)
dc.EndDrawing()
-
+
if not self.Fixed or self.Force:
self.Force = False
refresh_graphics = True
else:
refresh_graphics = False
-
+
if self.DraggingAxesPanel is not None and self.DraggingAxesPanel not in self.GraphicPanels:
self.DraggingAxesPanel.RefreshViewer(refresh_graphics)
for panel in self.GraphicPanels:
@@ -554,7 +554,7 @@
panel.RefreshViewer(refresh_graphics)
else:
panel.RefreshViewer()
-
+
if self.CursorTick is not None:
tick = self.CursorTick
elif len(self.Ticks) > 0:
@@ -570,27 +570,27 @@
((tick_duration % DAY) / HOUR, _("%dh")),
((tick_duration % HOUR) / MINUTE, _("%dm")),
((tick_duration % MINUTE) / SECOND, _("%ds"))]:
-
+
if value > 0 or not_null:
duration += format % value
not_null = True
-
- duration += _("%03gms") % (float(tick_duration % SECOND) / MILLISECOND)
+
+ duration += _("%03gms") % (float(tick_duration % SECOND) / MILLISECOND)
self.TickTimeLabel.SetLabel("t: %s" % duration)
else:
self.TickLabel.SetLabel("")
self.TickTimeLabel.SetLabel("")
self.TickSizer.Layout()
-
+
def SubscribeAllDataConsumers(self):
DebugViewer.SubscribeAllDataConsumers(self)
-
+
if self.DataProducer is not None:
if self.DataProducer is not None:
self.SetTickTime(self.DataProducer.GetTicktime())
-
+
self.ResetCursorTick()
-
+
for panel in self.GraphicPanels[:]:
panel.SubscribeAllDataConsumers()
if panel.ItemsIsEmpty():
@@ -598,28 +598,28 @@
panel.ReleaseMouse()
self.GraphicPanels.remove(panel)
panel.Destroy()
-
+
self.ResetVariableNameMask()
self.RefreshGraphicsSizer()
self.ForceRefresh()
-
+
def ResetView(self):
self.UnsubscribeAllDataConsumers()
-
+
self.Fixed = False
for panel in self.GraphicPanels:
panel.Destroy()
self.GraphicPanels = []
self.ResetVariableNameMask()
self.RefreshGraphicsSizer()
-
+
def SetCanvasPosition(self, tick):
tick = max(self.Ticks[0], min(tick, self.Ticks[-1] - self.CurrentRange))
self.StartTick = self.Ticks[numpy.argmin(numpy.abs(self.Ticks - tick))]
self.Fixed = True
self.RefreshCanvasPosition()
self.ForceRefresh()
-
+
def RefreshCanvasPosition(self):
if len(self.Ticks) > 0:
pos = int(self.StartTick - self.Ticks[0])
@@ -628,7 +628,7 @@
pos = 0
range = 0
self.CanvasPosition.SetScrollbar(pos, self.CurrentRange, range, self.CurrentRange)
-
+
def ChangeRange(self, dir, tick=None):
current_range = self.CurrentRange
current_range_idx = self.CanvasRange.GetSelection()
@@ -644,7 +644,7 @@
self.StartTick = self.Ticks[numpy.argmin(numpy.abs(self.Ticks - new_start_tick))]
self.Fixed = new_start_tick < self.Ticks[-1] - self.CurrentRange
self.ForceRefresh()
-
+
def RefreshRange(self):
if len(self.Ticks) > 0:
if self.Fixed and self.Ticks[-1] - self.Ticks[0] < self.CurrentRange:
@@ -654,7 +654,7 @@
else:
self.StartTick = max(self.Ticks[0], self.Ticks[-1] - self.CurrentRange)
self.ForceRefresh()
-
+
def OnRangeChanged(self, event):
try:
self.CurrentRange = RANGE_VALUES[self.CanvasRange.GetSelection()][1] / self.Ticktime
@@ -662,13 +662,13 @@
self.CanvasRange.SetValue(str(self.CurrentRange))
wx.CallAfter(self.RefreshRange)
event.Skip()
-
+
def OnCurrentButton(self, event):
if len(self.Ticks) > 0:
self.StartTick = max(self.Ticks[0], self.Ticks[-1] - self.CurrentRange)
self.ResetCursorTick()
event.Skip()
-
+
def CopyDataToClipboard(self, variables):
text = "tick;%s;\n" % ";".join([item.GetVariable() for item, data in variables])
next_tick = NextTick(variables)
@@ -693,7 +693,7 @@
text += "%d;%s;\n" % (next_tick, ";".join(values))
next_tick = NextTick(variables)
self.ParentWindow.SetCopyBuffer(text)
-
+
def OnExportGraphButton(self, event):
items = reduce(lambda x, y: x + y,
[panel.GetItems() for panel in self.GraphicPanels],
@@ -703,25 +703,25 @@
if item.IsNumVariable()]
wx.CallAfter(self.CopyDataToClipboard, variables)
event.Skip()
-
+
def OnPositionChanging(self, event):
if len(self.Ticks) > 0:
self.StartTick = self.Ticks[0] + event.GetPosition()
self.Fixed = True
self.ForceRefresh()
event.Skip()
-
+
def GetRange(self):
return self.StartTick, self.StartTick + self.CurrentRange
-
+
def GetViewerIndex(self, viewer):
if viewer in self.GraphicPanels:
return self.GraphicPanels.index(viewer)
return None
-
+
def IsViewerFirst(self, viewer):
return viewer == self.GraphicPanels[0]
-
+
def HighlightPreviousViewer(self, viewer):
if self.IsViewerFirst(viewer):
return
@@ -729,7 +729,7 @@
if idx is None:
return
self.GraphicPanels[idx-1].SetHighlight(HIGHLIGHT_AFTER)
-
+
def ResetVariableNameMask(self):
items = []
for panel in self.GraphicPanels:
@@ -743,10 +743,10 @@
self.VariableNameMask = []
self.MaskLabel.ChangeValue(".".join(self.VariableNameMask))
self.MaskLabel.SetInsertionPoint(self.MaskLabel.GetLastPosition())
-
+
def GetVariableNameMask(self):
return self.VariableNameMask
-
+
def InsertValue(self, iec_path, idx = None, force=False, graph=False):
for panel in self.GraphicPanels:
if panel.GetItem(iec_path) is not None:
@@ -758,7 +758,7 @@
item = DebugVariableItem(self, iec_path, True)
result = self.AddDataConsumer(iec_path.upper(), item, True)
if result is not None or force:
-
+
self.Freeze()
if item.IsNumVariable() and graph:
panel = DebugVariableGraphicViewer(self.GraphicsWindow, self, [item], GRAPH_PARALLEL)
@@ -774,7 +774,7 @@
self.RefreshGraphicsSizer()
self.Thaw()
self.ForceRefresh()
-
+
def MoveValue(self, iec_path, idx = None, graph=False):
if idx is None:
idx = len(self.GraphicPanels)
@@ -787,9 +787,9 @@
break
if source_panel is not None:
source_panel_idx = self.GraphicPanels.index(source_panel)
-
+
if (len(source_panel.GetItems()) == 1):
-
+
if source_panel_idx < idx:
self.GraphicPanels.insert(idx, source_panel)
self.GraphicPanels.pop(source_panel_idx)
@@ -798,7 +798,7 @@
self.GraphicPanels.insert(idx, source_panel)
else:
return
-
+
else:
source_panel.RemoveItem(item)
source_size = source_panel.GetSize()
@@ -807,22 +807,22 @@
panel.SetCanvasHeight(source_size.height)
if self.CursorTick is not None:
panel.SetCursorTick(self.CursorTick)
-
+
else:
panel = DebugVariableTextViewer(self.GraphicsWindow, self, [item])
-
+
self.GraphicPanels.insert(idx, panel)
-
+
if source_panel.ItemsIsEmpty():
if source_panel.HasCapture():
source_panel.ReleaseMouse()
source_panel.Destroy()
self.GraphicPanels.remove(source_panel)
-
+
self.ResetVariableNameMask()
self.RefreshGraphicsSizer()
self.ForceRefresh()
-
+
def MergeGraphs(self, source, target_idx, merge_type, force=False):
source_item = None
source_panel = None
@@ -846,11 +846,11 @@
graph_type = target_panel.GraphType
if target_panel != source_panel:
if (merge_type == GRAPH_PARALLEL and graph_type != merge_type or
- merge_type == GRAPH_ORTHOGONAL and
+ merge_type == GRAPH_ORTHOGONAL and
(graph_type == GRAPH_PARALLEL and len(target_panel.Items) > 1 or
graph_type == GRAPH_ORTHOGONAL and len(target_panel.Items) >= 3)):
return
-
+
if source_panel is not None:
source_panel.RemoveItem(source_item)
if source_panel.ItemsIsEmpty():
@@ -862,7 +862,7 @@
target_panel.RemoveItem(source_item)
else:
target_panel = None
-
+
if target_panel is not None:
target_panel.AddItem(source_item)
target_panel.GraphType = merge_type
@@ -874,15 +874,15 @@
else:
target_panel.SetCanvasHeight(size.height)
target_panel.ResetGraphics()
-
+
self.ResetVariableNameMask()
self.RefreshGraphicsSizer()
self.ForceRefresh()
-
+
def DeleteValue(self, source_panel, item=None):
source_idx = self.GetViewerIndex(source_panel)
if source_idx is not None:
-
+
if item is None:
source_panel.ClearItems()
source_panel.Destroy()
@@ -900,7 +900,7 @@
self.Fixed = False
self.ResetCursorTick()
self.ForceRefresh()
-
+
def ToggleViewerType(self, panel):
panel_idx = self.GetViewerIndex(panel)
if panel_idx is not None:
@@ -916,7 +916,7 @@
panel.Destroy()
self.RefreshGraphicsSizer()
self.ForceRefresh()
-
+
def ResetGraphicsValues(self):
self.Ticks = numpy.array([])
self.StartTick = 0
@@ -931,22 +931,22 @@
posx = max(0, min(xstart, (vwidth - window_size[0]) / SCROLLBAR_UNIT))
posy = max(0, min(ystart, (vheight - window_size[1]) / SCROLLBAR_UNIT))
self.GraphicsWindow.Scroll(posx, posy)
- self.GraphicsWindow.SetScrollbars(SCROLLBAR_UNIT, SCROLLBAR_UNIT,
+ self.GraphicsWindow.SetScrollbars(SCROLLBAR_UNIT, SCROLLBAR_UNIT,
vwidth / SCROLLBAR_UNIT, vheight / SCROLLBAR_UNIT, posx, posy)
-
+
def OnGraphicsWindowEraseBackground(self, event):
pass
-
+
def OnGraphicsWindowPaint(self, event):
self.RefreshView()
event.Skip()
-
+
def OnGraphicsWindowResize(self, event):
size = self.GetSize()
for panel in self.GraphicPanels:
panel_size = panel.GetSize()
- if (isinstance(panel, DebugVariableGraphicViewer) and
- panel.GraphType == GRAPH_ORTHOGONAL and
+ if (isinstance(panel, DebugVariableGraphicViewer) and
+ panel.GraphType == GRAPH_ORTHOGONAL and
panel_size.width == panel_size.height):
panel.SetCanvasHeight(size.width)
self.RefreshGraphicsWindowScrollbars()
--- a/controls/DebugVariablePanel/DebugVariableTextViewer.py Fri Aug 11 15:18:19 2017 +0300
+++ b/controls/DebugVariablePanel/DebugVariableTextViewer.py Mon Aug 14 19:13:01 2017 +0300
@@ -39,7 +39,7 @@
"""
class DebugVariableTextDropTarget(wx.TextDropTarget):
-
+
def __init__(self, parent, window):
"""
Constructor
@@ -49,7 +49,7 @@
wx.TextDropTarget.__init__(self)
self.ParentControl = parent
self.ParentWindow = window
-
+
def __del__(self):
"""
Destructor
@@ -58,7 +58,7 @@
# Panel
self.ParentControl = None
self.ParentWindow = None
-
+
def OnDragOver(self, x, y, d):
"""
Function called when mouse is dragged over Drop Target
@@ -68,9 +68,9 @@
"""
# Signal parent that mouse is dragged over
self.ParentControl.OnMouseDragging(x, y)
-
+
return wx.TextDropTarget.OnDragOver(self, x, y, d)
-
+
def OnDropText(self, x, y, data):
"""
Function called when mouse is released in Drop Target
@@ -80,9 +80,9 @@
"""
# Signal Debug Variable Panel to reset highlight
self.ParentWindow.ResetHighlight()
-
+
message = None
-
+
# Check that data is valid regarding DebugVariablePanel
try:
values = eval(data)
@@ -91,50 +91,50 @@
except:
message = _("Invalid value \"%s\" for debug variable") % data
values = None
-
+
# Display message if data is invalid
if message is not None:
wx.CallAfter(self.ShowMessage, message)
-
+
# Data contain a reference to a variable to debug
elif values[1] == "debug":
-
+
# Get Before which Viewer the variable has to be moved or added
# according to the position of mouse in Viewer.
width, height = self.ParentControl.GetSize()
target_idx = self.ParentControl.GetIndex()
if y > height / 2:
target_idx += 1
-
+
# Drag'n Drop is an internal is an internal move inside Debug
- # Variable Panel
+ # Variable Panel
if len(values) > 2 and values[2] == "move":
- self.ParentWindow.MoveValue(values[0],
+ self.ParentWindow.MoveValue(values[0],
target_idx)
-
+
# Drag'n Drop was initiated by another control of Beremiz
else:
- self.ParentWindow.InsertValue(values[0],
- target_idx,
+ self.ParentWindow.InsertValue(values[0],
+ target_idx,
force=True)
-
+
def OnLeave(self):
"""
Function called when mouse is leave Drop Target
"""
# Signal Debug Variable Panel to reset highlight
self.ParentWindow.ResetHighlight()
-
+
return wx.TextDropTarget.OnLeave(self)
-
+
def ShowMessage(self, message):
"""
Show error message in Error Dialog
@param message: Error message to display
"""
- dialog = wx.MessageDialog(self.ParentWindow,
- message,
- _("Error"),
+ dialog = wx.MessageDialog(self.ParentWindow,
+ message,
+ _("Error"),
wx.OK|wx.ICON_ERROR)
dialog.ShowModal()
dialog.Destroy()
@@ -149,7 +149,7 @@
"""
class DebugVariableTextViewer(DebugVariableViewer, wx.Panel):
-
+
def __init__(self, parent, window, items=[]):
"""
Constructor
@@ -158,13 +158,13 @@
@param items: List of DebugVariableItem displayed by Viewer
"""
DebugVariableViewer.__init__(self, window, items)
-
+
wx.Panel.__init__(self, parent)
# Set panel background colour
self.SetBackgroundColour(wx.WHITE)
# Define panel drop target
self.SetDropTarget(DebugVariableTextDropTarget(self, window))
-
+
# Bind events
self.Bind(wx.EVT_LEFT_DOWN, self.OnLeftDown)
self.Bind(wx.EVT_LEFT_UP, self.OnLeftUp)
@@ -174,16 +174,16 @@
self.Bind(wx.EVT_SIZE, self.OnResize)
self.Bind(wx.EVT_ERASE_BACKGROUND, self.OnEraseBackground)
self.Bind(wx.EVT_PAINT, self.OnPaint)
-
+
# Define panel min size for parent sizer layout
self.SetMinSize(wx.Size(0, 25))
-
+
# Add buttons to Viewer
for bitmap, callback in [("force", self.OnForceButton),
("release", self.OnReleaseButton),
("delete_graph", self.OnCloseButton)]:
self.Buttons.append(GraphButton(0, 0, bitmap, callback))
-
+
def RefreshViewer(self):
"""
Method that refresh the content displayed by Viewer
@@ -193,24 +193,24 @@
bitmap = wx.EmptyBitmap(width, height)
dc = wx.BufferedDC(wx.ClientDC(self), bitmap)
dc.Clear()
-
+
# Get Graphics Context for DC, for anti-aliased and transparent
# rendering
gc = wx.GCDC(dc)
-
+
gc.BeginDrawing()
-
+
# Get first item
item = self.ItemsDict.values()[0]
-
+
# Get item variable path masked according Debug Variable Panel mask
item_path = item.GetVariable(
self.ParentWindow.GetVariableNameMask())
-
+
# Draw item variable path at Viewer left side
w, h = gc.GetTextExtent(item_path)
gc.DrawText(item_path, 20, (height - h) / 2)
-
+
# Update 'Release' button state and text color according to item forced
# flag value
item_forced = item.IsForced()
@@ -218,17 +218,17 @@
self.RefreshButtonsPosition()
if item_forced:
gc.SetTextForeground(wx.BLUE)
-
+
# Draw item current value at right side of Viewer
item_value = item.GetValue()
w, h = gc.GetTextExtent(item_value)
gc.DrawText(item_value, width - 40 - w, (height - h) / 2)
-
+
# Draw other Viewer common elements
self.DrawCommonElements(gc)
-
+
gc.EndDrawing()
-
+
def OnLeftDown(self, event):
"""
Function called when mouse left button is pressed
@@ -236,15 +236,15 @@
"""
# Get first item
item = self.ItemsDict.values()[0]
-
+
# Calculate item path bounding box
width, height = self.GetSize()
item_path = item.GetVariable(
self.ParentWindow.GetVariableNameMask())
w, h = self.GetTextExtent(item_path)
-
+
# Test if mouse has been pressed in this bounding box. In that case
- # start a move drag'n drop of item variable
+ # start a move drag'n drop of item variable
x, y = event.GetPosition()
item_path_bbox = wx.Rect(20, (height - h) / 2, w, h)
if item_path_bbox.InsideXY(x, y):
@@ -253,11 +253,11 @@
dragSource = wx.DropSource(self)
dragSource.SetData(data)
dragSource.DoDragDrop()
-
+
# In other case handle event normally
else:
event.Skip()
-
+
def OnLeftUp(self, event):
"""
Function called when mouse left button is released
@@ -267,7 +267,7 @@
x, y = event.GetPosition()
wx.CallAfter(self.HandleButton, x, y)
event.Skip()
-
+
def OnLeftDClick(self, event):
"""
Function called when mouse left button is double clicked
@@ -276,7 +276,7 @@
# Only numeric variables can be toggled to graph canvas
if self.ItemsDict.values()[0].IsNumVariable():
self.ParentWindow.ToggleViewerType(self)
-
+
def OnPaint(self, event):
"""
Function called when redrawing Viewer content is needed
--- a/controls/DebugVariablePanel/DebugVariableViewer.py Fri Aug 11 15:18:19 2017 +0300
+++ b/controls/DebugVariablePanel/DebugVariableViewer.py Mon Aug 14 19:13:01 2017 +0300
@@ -56,7 +56,7 @@
"""
class DebugVariableViewer:
-
+
def __init__(self, window, items=[]):
"""
Constructor
@@ -67,26 +67,26 @@
self.ItemsDict = OrderedDict([(item.GetVariable(), item)
for item in items])
self.Items = self.ItemsDict.viewvalues()
-
+
# Variable storing current highlight displayed in Viewer
self.Highlight = HIGHLIGHT_NONE
# List of buttons
self.Buttons = []
-
+
def __del__(self):
"""
Destructor
"""
# Remove reference to Debug Variable Panel
self.ParentWindow = None
-
+
def GetIndex(self):
"""
Return position of Viewer in Debug Variable Panel
@return: Position of Viewer
"""
return self.ParentWindow.GetViewerIndex(self)
-
+
def GetItem(self, variable):
"""
Return item storing values of a variable
@@ -94,28 +94,28 @@
@return: Item storing values of this variable
"""
return self.ItemsDict.get(variable, None)
-
+
def GetItems(self):
"""
Return items displayed by Viewer
@return: List of items displayed in Viewer
"""
return self.ItemsDict.values()
-
+
def AddItem(self, item):
"""
Add an item to the list of items displayed by Viewer
@param item: Item to add to the list
"""
self.ItemsDict[item.GetVariable()] = item
-
+
def RemoveItem(self, item):
"""
Remove an item from the list of items displayed by Viewer
@param item: Item to remove from the list
"""
self.ItemsDict.pop(item.GetVariable(), None)
-
+
def ClearItems(self):
"""
Clear list of items displayed by Viewer
@@ -123,17 +123,17 @@
# Unsubscribe every items of the list
for item in self.Items:
self.ParentWindow.RemoveDataConsumer(item)
-
+
# Clear list
self.ItemsDict.clear()
-
+
def ItemsIsEmpty(self):
"""
Return if list of items displayed by Viewer is empty
@return: True if list is empty
"""
return len(self.Items) == 0
-
+
def SubscribeAllDataConsumers(self):
"""
Function that unsubscribe and remove every item that store values of
@@ -141,7 +141,7 @@
"""
for item in self.ItemsDict.values()[:]:
iec_path = item.GetVariable()
-
+
# Check that variablepath exist in PLC
if self.ParentWindow.GetDataType(iec_path) is None:
# If not, unsubscribe and remove it
@@ -151,30 +151,30 @@
# If it exist, resubscribe and refresh data type
self.ParentWindow.AddDataConsumer(iec_path.upper(), item, True)
item.RefreshVariableType()
-
+
def ResetItemsData(self):
"""
Reset data stored in every items displayed in Viewer
"""
for item in self.Items:
item.ResetData()
-
+
def GetItemsMinCommonTick(self):
"""
Return the minimum tick common to all iems displayed in Viewer
@return: Minimum common tick between items
"""
- return reduce(max, [item.GetData()[0, 0]
+ return reduce(max, [item.GetData()[0, 0]
for item in self.Items
if len(item.GetData()) > 0], 0)
-
+
def RefreshViewer(self):
"""
Method that refresh the content displayed by Viewer
Need to be overridden by inherited classes
"""
pass
-
+
def SetHighlight(self, highlight):
"""
Set Highlight type displayed in Viewer
@@ -183,17 +183,17 @@
# Return immediately if highlight don't change
if self.Highlight == highlight:
return False
-
+
self.Highlight = highlight
return True
-
+
def GetButtons(self):
"""
Return list of buttons defined in Viewer
@return: List of buttons
"""
return self.Buttons
-
+
def IsOverButton(self, x, y):
"""
Return if point is over one button of Viewer
@@ -205,7 +205,7 @@
if button.HitTest(x, y):
return button
return None
-
+
def HandleButton(self, x, y):
"""
Search for the button under point and if found execute associated
@@ -217,10 +217,10 @@
button = self.IsOverButton(x, y)
if button is None:
return False
-
+
button.ProcessCallback()
return True
-
+
def ShowButtons(self, show):
"""
Set display state of buttons in Viewer
@@ -229,27 +229,27 @@
# Change display of every buttons
for button in self.Buttons:
button.Show(show)
-
+
# Refresh button positions
self.RefreshButtonsPosition()
self.RefreshViewer()
-
+
def RefreshButtonsPosition(self):
"""
Function that refresh buttons position in Viewer
"""
# Get Viewer size
width, height = self.GetSize()
-
+
# Buttons are align right so we calculate buttons positions in
# reverse order
buttons = self.Buttons[:]
buttons.reverse()
-
+
# Position offset on x coordinate
x_offset = 0
for button in buttons:
- # Buttons are stacked right, removing those that are not active
+ # Buttons are stacked right, removing those that are not active
if button.IsEnabled():
# Update button position according to button width and offset
# on x coordinate
@@ -257,7 +257,7 @@
button.SetPosition(width - 5 - w - x_offset, 5)
# Update offset on x coordinate
x_offset += w + 2
-
+
def DrawCommonElements(self, dc, buttons=None):
"""
Function that draw common graphics for every Viewers
@@ -268,26 +268,26 @@
"""
# Get Viewer size
width, height = self.GetSize()
-
+
# Set dc styling for drop before or drop after highlight
dc.SetPen(HIGHLIGHT_DROP_PEN)
dc.SetBrush(HIGHLIGHT_DROP_BRUSH)
-
+
# Draw line at upper side of Viewer if highlight is drop before
if self.Highlight == HIGHLIGHT_BEFORE:
dc.DrawLine(0, 1, width - 1, 1)
-
+
# Draw line at lower side of Viewer if highlight is drop before
elif self.Highlight == HIGHLIGHT_AFTER:
dc.DrawLine(0, height - 1, width - 1, height - 1)
-
+
# If no specific buttons are defined, get default buttons
if buttons is None:
buttons = self.Buttons
# Draw buttons
for button in buttons:
button.Draw(dc)
-
+
# If graph dragging is processing
if self.ParentWindow.IsDragging():
destBBox = self.ParentWindow.GetDraggingAxesClippingRegion(self)
@@ -295,55 +295,55 @@
if destBBox.width > 0 and destBBox.height > 0:
srcPanel = self.ParentWindow.DraggingAxesPanel
srcBBox = srcPanel.GetAxesBoundingBox()
-
+
srcX = srcBBox.x - (srcPos.x if destBBox.x == 0 else 0)
srcY = srcBBox.y - (srcPos.y if destBBox.y == 0 else 0)
-
+
srcBmp = _convert_agg_to_wx_bitmap(
srcPanel.get_renderer(), None)
srcDC = wx.MemoryDC()
srcDC.SelectObject(srcBmp)
-
- dc.Blit(destBBox.x, destBBox.y,
- int(destBBox.width), int(destBBox.height),
+
+ dc.Blit(destBBox.x, destBBox.y,
+ int(destBBox.width), int(destBBox.height),
srcDC, srcX, srcY)
-
+
def OnEnter(self, event):
"""
Function called when entering Viewer
- @param event: wx.MouseEvent
+ @param event: wx.MouseEvent
"""
# Display buttons
self.ShowButtons(True)
event.Skip()
-
+
def OnLeave(self, event):
"""
Function called when leaving Viewer
- @param event: wx.MouseEvent
+ @param event: wx.MouseEvent
"""
# Hide buttons
self.ShowButtons(False)
event.Skip()
-
+
def OnCloseButton(self):
"""
Function called when Close button is pressed
"""
wx.CallAfter(self.ParentWindow.DeleteValue, self)
-
+
def OnForceButton(self):
"""
Function called when Force button is pressed
"""
self.ForceValue(self.ItemsDict.values()[0])
-
+
def OnReleaseButton(self):
"""
Function called when Release button is pressed
"""
self.ReleaseValue(self.ItemsDict.values()[0])
-
+
def OnMouseDragging(self, x, y):
"""
Function called when mouse is dragged over Viewer
@@ -354,7 +354,7 @@
# Refresh highlight in Debug Variable Panel (highlight can be displayed
# in another Viewer
self.ParentWindow.RefreshHighlight(x + xw, y + yw)
-
+
def RefreshHighlight(self, x, y):
"""
Function called by Debug Variable Panel asking Viewer to refresh
@@ -364,22 +364,22 @@
"""
# Get Viewer size
width, height = self.GetSize()
-
+
# Mouse is in the first half of Viewer
if y < height / 2:
# If Viewer is the upper one, draw drop before highlight
if self.ParentWindow.IsViewerFirst(self):
self.SetHighlight(HIGHLIGHT_BEFORE)
-
+
# Else draw drop after highlight in previous Viewer
else:
self.SetHighlight(HIGHLIGHT_NONE)
self.ParentWindow.HighlightPreviousViewer(self)
-
- # Mouse is in the second half of Viewer, draw drop after highlight
+
+ # Mouse is in the second half of Viewer, draw drop after highlight
else:
self.SetHighlight(HIGHLIGHT_AFTER)
-
+
def OnEraseBackground(self, event):
"""
Function called when Viewer background is going to be erase
@@ -387,7 +387,7 @@
"""
# Prevent flicker on Windows
pass
-
+
def OnResize(self, event):
"""
Function called when Viewer size changed
@@ -397,7 +397,7 @@
self.RefreshButtonsPosition()
self.ParentWindow.ForceRefresh()
event.Skip()
-
+
def ForceValue(self, item):
"""
Force value of item given
@@ -409,13 +409,13 @@
# Return immediately if not found
if iec_type is None:
return
-
+
# Open a dialog to enter varaible forced value
dialog = ForceVariableDialog(self, iec_type, str(item.GetValue()))
if dialog.ShowModal() == wx.ID_OK:
self.ParentWindow.ForceDataValue(iec_path.upper(),
dialog.GetValue())
-
+
def ReleaseValue(self, item):
"""
Release value of item given
--- a/controls/DebugVariablePanel/GraphButton.py Fri Aug 11 15:18:19 2017 +0300
+++ b/controls/DebugVariablePanel/GraphButton.py Mon Aug 14 19:13:01 2017 +0300
@@ -35,7 +35,7 @@
"""
class GraphButton():
-
+
def __init__(self, x, y, bitmap, callback):
"""
Constructor
@@ -48,21 +48,21 @@
self.SetPosition(x, y)
# Set button bitmap
self.SetBitmap(bitmap)
-
+
# By default button is hide and enabled
self.Shown = False
self.Enabled = True
-
+
# Save reference to callback function
self.Callback = callback
-
+
def __del__(self):
"""
Destructor
"""
# Remove reference to callback function
self.callback = None
-
+
def SetBitmap(self, bitmap):
"""
Set bitmap to use for button
@@ -70,7 +70,7 @@
"""
# Get wx.Bitmap object corresponding to bitmap
self.Bitmap = GetBitmap(bitmap)
-
+
def GetSize(self):
"""
Return size of button
@@ -78,7 +78,7 @@
"""
# Button size is size of bitmap
return self.Bitmap.GetSize()
-
+
def SetPosition(self, x, y):
"""
Set button position
@@ -86,7 +86,7 @@
@param y: Y coordinate of Button in Graphic Viewer
"""
self.Position = wx.Point(x, y)
-
+
def Show(self, show=True):
"""
Mark if button to be displayed in Graphic Viewer
@@ -94,20 +94,20 @@
(default True)
"""
self.Shown = show
-
+
def Hide(self):
"""
Hide button from Graphic Viewer
"""
self.Show(False)
-
+
def IsShown(self):
"""
Return if button is displayed in Graphic Viewer
@return: True if button is displayed in Graphic Viewer
"""
return self.Shown
-
+
def Enable(self, enable=True):
"""
Mark if button is active in Graphic Viewer
@@ -115,44 +115,44 @@
(default True)
"""
self.Enabled = enable
-
+
def Disable(self):
"""
Deactivate button in Graphic Viewer
"""
self.Enabled = False
-
+
def IsEnabled(self):
"""
Return if button is active in Graphic Viewer
@return: True if button is active in Graphic Viewer
"""
return self.Enabled
-
+
def HitTest(self, x, y):
"""
Test if point is inside button
@param x: X coordinate of point
@param y: Y coordinate of point
@return: True if button is active and displayed and point is inside
- button
+ button
"""
# Return immediately if button is hidden or inactive
if not (self.IsShown() and self.IsEnabled()):
return False
-
+
# Test if point is inside button
w, h = self.Bitmap.GetSize()
rect = wx.Rect(self.Position.x, self.Position.y, w, h)
return rect.InsideXY(x, y)
-
+
def ProcessCallback(self):
"""
Call callback function if defined
"""
if self.Callback is not None:
self.Callback()
-
+
def Draw(self, dc):
"""
Draw button in Graphic Viewer
--- a/controls/DurationCellEditor.py Fri Aug 11 15:18:19 2017 +0300
+++ b/controls/DurationCellEditor.py Mon Aug 14 19:13:01 2017 +0300
@@ -27,39 +27,39 @@
from dialogs.DurationEditorDialog import DurationEditorDialog
class DurationCellControl(wx.PyControl):
-
+
'''
Custom cell editor control with a text box and a button that launches
the DurationEditorDialog.
'''
def __init__(self, parent):
wx.Control.__init__(self, parent)
-
+
main_sizer = wx.FlexGridSizer(cols=2, hgap=0, rows=1, vgap=0)
main_sizer.AddGrowableCol(0)
main_sizer.AddGrowableRow(0)
-
+
# create location text control
- self.Duration = wx.TextCtrl(self, size=wx.Size(0, -1),
+ self.Duration = wx.TextCtrl(self, size=wx.Size(0, -1),
style=wx.TE_PROCESS_ENTER)
self.Duration.Bind(wx.EVT_KEY_DOWN, self.OnDurationChar)
main_sizer.AddWindow(self.Duration, flag=wx.GROW)
-
+
# create browse button
self.EditButton = wx.Button(self, label='...', size=wx.Size(30, -1))
self.Bind(wx.EVT_BUTTON, self.OnEditButtonClick, self.EditButton)
main_sizer.AddWindow(self.EditButton, flag=wx.GROW)
-
+
self.Bind(wx.EVT_SIZE, self.OnSize)
-
+
self.SetSizer(main_sizer)
-
+
self.Default = None
-
+
def SetValue(self, value):
self.Default = value
self.Duration.SetValue(value)
-
+
def GetValue(self):
return self.Duration.GetValue()
@@ -90,7 +90,7 @@
def SetInsertionPoint(self, i):
self.Duration.SetInsertionPoint(i)
-
+
def SetFocus(self):
self.Duration.SetFocus()
@@ -100,13 +100,13 @@
'''
def __init__(self, table, colname):
wx.grid.PyGridCellEditor.__init__(self)
-
+
self.Table = table
self.Colname = colname
-
+
def __del__(self):
self.CellControl = None
-
+
def Create(self, parent, id, evt_handler):
self.CellControl = DurationCellControl(parent)
self.SetControl(self.CellControl)
@@ -131,8 +131,8 @@
return self.EndEditInternal(row, col, grid, oldval)
else:
def EndEdit(self, row, col, grid):
- oldval = self.Table.GetValueByName(row, self.Colname)
- return self.EndEditInternal(row, col, grid, oldval)
+ oldval = self.Table.GetValueByName(row, self.Colname)
+ return self.EndEditInternal(row, col, grid, oldval)
def SetSize(self, rect):
self.CellControl.SetDimensions(rect.x + 1, rect.y,
--- a/controls/EnhancedStatusBar.py Fri Aug 11 15:18:19 2017 +0300
+++ b/controls/EnhancedStatusBar.py Mon Aug 14 19:13:01 2017 +0300
@@ -16,7 +16,7 @@
#
# For All Kind Of Problems, Requests Of Enhancements And Bug Reports, Please
# Write To Me At:
-#
+#
#
# andrea.gavana@agip.it
# andrea_gavan@tin.it
@@ -47,7 +47,7 @@
And Can Be ESB_EXACT_FIT, ESB_ALIGN_CENTER_VERTICAL, ESB_ALIGN_BOTTOM And
ESB_ALIGN_LEFT;
-EnhancedStatusBar Is Freeware And Distributed Under The wxPython License.
+EnhancedStatusBar Is Freeware And Distributed Under The wxPython License.
Latest Revision: 21 September 2005, 19.57.20 GMT+2
Latest Revision before Latest Revision: 21 September 2005, 18.29.35 GMT+2
@@ -90,17 +90,17 @@
style=wx.ST_SIZEGRIP,
name="EnhancedStatusBar")
"""
-
+
wx.StatusBar.__init__(self, parent, id, style, name)
-
+
self._items = {}
self._curPos = 0
self._parent = parent
-
- wx.EVT_SIZE(self, self.OnSize)
+
+ wx.EVT_SIZE(self, self.OnSize)
wx.CallAfter(self.OnSize, None)
-
+
def OnSize(self, event):
"""Handles The wx.EVT_SIZE Events For The StatusBar.
@@ -109,15 +109,15 @@
for pos, item in self._items.items():
widget, horizontalalignment, verticalalignment = item.widget, item.horizontalalignment, item.verticalalignment
-
+
rect = self.GetFieldRect(pos)
widgetpos = widget.GetPosition()
widgetsize = widget.GetSize()
rect = self.GetFieldRect(pos)
-
+
if horizontalalignment == ESB_EXACT_FIT:
-
+
if verticalalignment == ESB_EXACT_FIT:
""" 1 September 2015 Fix fit align """
widget.SetSize((rect.width-4, rect.height-4))
@@ -138,7 +138,7 @@
widget.SetPosition((rect.x-1, rect.height-widgetsize[1]))
elif horizontalalignment == ESB_ALIGN_LEFT:
-
+
xpos = rect.x - 1
if verticalalignment == ESB_EXACT_FIT:
widget.SetSize((widgetsize[0], rect.height-2))
@@ -154,9 +154,9 @@
widget.SetPosition((xpos, rect.y))
elif verticalalignment == ESB_ALIGN_BOTTOM:
widget.SetPosition((xpos, rect.height-widgetsize[1]))
-
+
elif horizontalalignment == ESB_ALIGN_RIGHT:
-
+
xpos = rect.x + rect.width - widgetsize[0] - 1
if verticalalignment == ESB_EXACT_FIT:
widget.SetSize((widgetsize[0], rect.height-2))
@@ -174,7 +174,7 @@
widget.SetPosition((xpos, rect.height-widgetsize[1]))
elif horizontalalignment == ESB_ALIGN_CENTER_HORIZONTAL:
-
+
xpos = rect.x + (rect.width - widgetsize[0])/2 - 1
if verticalalignment == ESB_EXACT_FIT:
widget.SetSize((widgetsize[0], rect.height))
@@ -191,11 +191,11 @@
elif verticalalignment == ESB_ALIGN_BOTTOM:
widget.SetPosition((xpos, rect.height-widgetsize[1]))
-
+
if event is not None:
event.Skip()
-
-
+
+
def AddWidget(self, widget, horizontalalignment=ESB_ALIGN_CENTER_HORIZONTAL,
verticalalignment=ESB_ALIGN_CENTER_VERTICAL, pos = -1):
"""Add A Widget To The EnhancedStatusBar.
@@ -221,7 +221,7 @@
if pos == -1:
pos = self._curPos
self._curPos += 1
-
+
if self.GetFieldsCount() <= pos:
raise "\nERROR: EnhancedStatusBar has a max of %d items, you tried to set item #%d" % (self.GetFieldsCount(), pos)
@@ -236,13 +236,13 @@
raise '\nERROR: Parameter "verticalalignment" Should Be One Of '\
'"ESB_ALIGN_CENTER_VERTICAL", "ESB_ALIGN_TOP", "ESB_ALIGN_BOTTOM"' \
'"ESB_EXACT_FIT"'
-
+
try:
self.RemoveChild(self._items[pos].widget)
self._items[pos].widget.Destroy()
except KeyError: pass
-
+
self._items[pos] = EnhancedStatusBarItem(widget, pos, horizontalalignment, verticalalignment)
-
+
wx.CallAfter(self.OnSize, None)
--- a/controls/FolderTree.py Fri Aug 11 15:18:19 2017 +0300
+++ b/controls/FolderTree.py Mon Aug 14 19:13:01 2017 +0300
@@ -47,13 +47,13 @@
return splitpath(head) + [tail]
class FolderTree(wx.Panel):
-
+
def __init__(self, parent, folder, filter=None, editable=True):
wx.Panel.__init__(self, parent, style=wx.TAB_TRAVERSAL)
-
+
main_sizer = wx.BoxSizer(wx.VERTICAL)
-
- self.Tree = wx.TreeCtrl(self,
+
+ self.Tree = wx.TreeCtrl(self,
style=wx.TR_HAS_BUTTONS|
wx.TR_SINGLE|
wx.SUNKEN_BORDER|
@@ -69,19 +69,19 @@
self.Bind(wx.EVT_TREE_BEGIN_LABEL_EDIT, self.OnTreeBeginLabelEdit, self.Tree)
self.Bind(wx.EVT_TREE_END_LABEL_EDIT, self.OnTreeEndLabelEdit, self.Tree)
main_sizer.AddWindow(self.Tree, 1, flag=wx.GROW)
-
+
if filter is not None:
self.Filter = wx.ComboBox(self, style=wx.CB_READONLY)
self.Bind(wx.EVT_COMBOBOX, self.OnFilterChanged, self.Filter)
main_sizer.AddWindow(self.Filter, flag=wx.GROW)
else:
self.Filter = None
-
+
self.SetSizer(main_sizer)
-
+
self.Folder = folder
self.Editable = editable
-
+
self.TreeImageList = wx.ImageList(16, 16)
self.TreeImageDict = {}
for item_type, bitmap in [(DRIVE, "tree_drive"),
@@ -89,7 +89,7 @@
(FILE, "tree_file")]:
self.TreeImageDict[item_type] = self.TreeImageList.Add(GetBitmap(bitmap))
self.Tree.SetImageList(self.TreeImageList)
-
+
self.Filters = {}
if self.Filter is not None:
filter_parts = filter.split("|")
@@ -101,11 +101,11 @@
self.Filter.Append(filter_parts[idx])
if idx == 0:
self.Filter.SetStringSelection(filter_parts[idx])
-
+
self.CurrentFilter = self.Filters[self.Filter.GetStringSelection()]
else:
self.CurrentFilter = ""
-
+
def _GetFolderChildren(self, folderpath, recursive=True):
items = []
if wx.Platform == '__WXMSW__' and folderpath == "/":
@@ -127,25 +127,25 @@
else:
children = 0
items.append((filename, FOLDER, children))
- elif (self.CurrentFilter == "" or
+ elif (self.CurrentFilter == "" or
os.path.splitext(filename)[1] == self.CurrentFilter):
items.append((filename, FILE, None))
if recursive:
items.sort(sort_folder)
return items
-
+
def SetFilter(self, filter):
self.CurrentFilter = filter
-
+
def GetTreeCtrl(self):
return self.Tree
-
+
def RefreshTree(self):
root = self.Tree.GetRootItem()
if not root.IsOk():
root = self.Tree.AddRoot("")
self.GenerateTreeBranch(root, self.Folder)
-
+
def GenerateTreeBranch(self, root, folderpath):
item, item_cookie = self.Tree.GetFirstChild(root)
for idx, (filename, item_type, children) in enumerate(self._GetFolderChildren(folderpath)):
@@ -172,18 +172,18 @@
def ExpandItem(self, item):
self.GenerateTreeBranch(item, self.GetPath(item))
self.Tree.Expand(item)
-
+
def OnTreeItemActivated(self, event):
self.ExpandItem(event.GetItem())
event.Skip()
-
+
def OnTreeLeftDown(self, event):
item, flags = self.Tree.HitTest(event.GetPosition())
if flags & wx.TREE_HITTEST_ONITEMBUTTON and not self.Tree.IsExpanded(item):
self.ExpandItem(item)
else:
event.Skip()
-
+
def OnTreeItemExpanded(self, event):
item = event.GetItem()
self.GenerateTreeBranch(item, self.GetPath(item))
@@ -201,7 +201,7 @@
event.Skip()
else:
event.Veto()
-
+
def OnTreeEndLabelEdit(self, event):
new_name = event.GetLabel()
if new_name != "":
@@ -212,20 +212,20 @@
os.rename(old_filepath, new_filepath)
event.Skip()
else:
- message = wx.MessageDialog(self,
- _("File '%s' already exists!") % new_name,
+ message = wx.MessageDialog(self,
+ _("File '%s' already exists!") % new_name,
_("Error"), wx.OK|wx.ICON_ERROR)
message.ShowModal()
message.Destroy()
event.Veto()
else:
event.Skip()
-
+
def OnFilterChanged(self, event):
self.CurrentFilter = self.Filters[self.Filter.GetStringSelection()]
self.RefreshTree()
event.Skip()
-
+
def _SelectItem(self, root, parts):
if len(parts) == 0:
self.Tree.SelectItem(root)
@@ -233,7 +233,7 @@
item, item_cookie = self.Tree.GetFirstChild(root)
while item.IsOk():
if self.Tree.GetItemText(item) == parts[0]:
- if (self.Tree.ItemHasChildren(item) and
+ if (self.Tree.ItemHasChildren(item) and
not self.Tree.IsExpanded(item)):
self.Tree.Expand(item)
wx.CallAfter(self._SelectItem, item, parts[1:])
@@ -241,14 +241,14 @@
self._SelectItem(item, parts[1:])
return
item, item_cookie = self.Tree.GetNextChild(root, item_cookie)
-
+
def SetPath(self, path):
if path.startswith(self.Folder):
root = self.Tree.GetRootItem()
if root.IsOk():
relative_path = path.replace(os.path.join(self.Folder, ""), "")
self._SelectItem(root, splitpath(relative_path))
-
+
def GetPath(self, item=None):
if item is None:
item = self.Tree.GetSelection()
--- a/controls/LibraryPanel.py Fri Aug 11 15:18:19 2017 +0300
+++ b/controls/LibraryPanel.py Mon Aug 14 19:13:01 2017 +0300
@@ -42,7 +42,7 @@
"""
class LibraryPanel(wx.Panel):
-
+
def __init__(self, parent, enable_drag=False):
"""
Constructor
@@ -51,19 +51,19 @@
be drag'n drop from LibraryPanel (default: False)
"""
wx.Panel.__init__(self, parent, style=wx.TAB_TRAVERSAL)
-
+
# Define LibraryPanel main sizer
main_sizer = wx.FlexGridSizer(cols=1, hgap=0, rows=2, vgap=0)
main_sizer.AddGrowableCol(0)
main_sizer.AddGrowableRow(1)
-
+
# Add SearchCtrl to main sizer
self.SearchCtrl = wx.SearchCtrl(self)
# Add a button with a magnifying glass, essentially to show that this
# control is for searching in tree
self.SearchCtrl.ShowSearchButton(True)
self.Bind(wx.EVT_TEXT, self.OnSearchCtrlChanged, self.SearchCtrl)
- self.Bind(wx.EVT_SEARCHCTRL_SEARCH_BTN,
+ self.Bind(wx.EVT_SEARCHCTRL_SEARCH_BTN,
self.OnSearchButtonClick, self.SearchCtrl)
# Bind keyboard event on SearchCtrl text control to catch UP and DOWN
# for search previous and next occurrence
@@ -74,16 +74,16 @@
search_textctrl.Bind(wx.EVT_CHAR, self.OnKeyDown)
main_sizer.AddWindow(self.SearchCtrl, flag=wx.GROW)
-
+
# Add Splitter window for tree and block comment to main sizer
splitter_window = wx.SplitterWindow(self)
splitter_window.SetSashGravity(1.0)
main_sizer.AddWindow(splitter_window, flag=wx.GROW)
-
+
# Add TreeCtrl for functions and function blocks library in splitter
# window
self.Tree = wx.TreeCtrl(splitter_window,
- size=wx.Size(0, 0),
+ size=wx.Size(0, 0),
style=wx.TR_HAS_BUTTONS|
wx.TR_SINGLE|
wx.SUNKEN_BORDER|
@@ -95,35 +95,35 @@
# tree to start a drag'n drop
if enable_drag:
self.Bind(wx.EVT_TREE_BEGIN_DRAG, self.OnTreeBeginDrag, self.Tree)
-
+
# Add TextCtrl for function and function block informations
- self.Comment = wx.TextCtrl(splitter_window, size=wx.Size(0, 80),
+ self.Comment = wx.TextCtrl(splitter_window, size=wx.Size(0, 80),
style=wx.TE_READONLY|wx.TE_MULTILINE)
-
+
splitter_window.SplitHorizontally(self.Tree, self.Comment, -80)
-
+
self.SetSizer(main_sizer)
-
+
# Reference to the project controller
self.Controller = None
-
+
# Variable storing functions and function blocks library to display
self.BlockList = None
-
+
def __del__(self):
"""
Destructor
"""
# Remove reference to project controller
self.Controller = None
-
+
def SetController(self, controller):
"""
Set reference to project controller
@param controller: Reference to project controller
"""
self.Controller = controller
-
+
def SetBlockList(self, blocklist):
"""
Set function and function block library to display in TreeCtrl
@@ -133,15 +133,15 @@
self.BlockList = blocklist
# Refresh TreeCtrl values
self.RefreshTree()
-
+
def SetFocus(self):
"""
Called to give focus to LibraryPanel
- Override wx.Window SetFocus method
+ Override wx.Window SetFocus method
"""
# Give focus to SearchCtrl
self.SearchCtrl.SetFocus()
-
+
def ResetTree(self):
"""
Reset LibraryPanel values displayed in controls
@@ -150,7 +150,7 @@
self.SearchCtrl.SetValue("")
self.Tree.DeleteAllItems()
self.Comment.SetValue("")
-
+
def RefreshTree(self):
"""
Refresh LibraryPanel values displayed in controls
@@ -160,13 +160,13 @@
if blocktypes is None and self.Controller is not None:
# Get library from project controller if not defined
blocktypes = self.Controller.GetBlockTypes()
-
+
# Refresh TreeCtrl values if a library is defined
if blocktypes is not None:
# List that will contain tree items to be deleted when TreeCtrl
# will be refreshed
items_to_delete = []
-
+
# Get current selected item for selected it when values refreshed
selected_item = self.Tree.GetSelection()
selected_pydata = (self.Tree.GetPyData(selected_item)
@@ -179,16 +179,16 @@
if selected_pydata is not None and
selected_pydata["type"] == BLOCK
else (None, None))
-
+
# Get TreeCtrl root item (hidden)
root = self.Tree.GetRootItem()
if not root.IsOk():
# Create root if not present
root = self.Tree.AddRoot("")
-
+
# Iterate over functions and function blocks library categories and
# add a tree item to root item for each of them
-
+
# Get first child under root item
category_item, root_cookie = self.Tree.GetFirstChild(root)
for category in blocktypes:
@@ -196,11 +196,11 @@
# extracting translated strings for gettext to consider "name"
# to be translated
category_name = category["name"]
-
+
# Tree item already exists, set item label
if category_item.IsOk():
self.Tree.SetItemText(category_item, _(category_name))
-
+
# Tree item doesn't exist, add new one to root
else:
category_item = self.Tree.AppendItem(root, _(category_name))
@@ -209,24 +209,24 @@
if wx.Platform != '__WXMSW__':
category_item, root_cookie = \
self.Tree.GetNextChild(root, root_cookie)
-
- # Set data associated to tree item (only save that item is a
+
+ # Set data associated to tree item (only save that item is a
# category)
self.Tree.SetPyData(category_item, {"type" : CATEGORY})
-
+
# Iterate over functions and function blocks defined in library
- # category add a tree item to category tree item for each of
+ # category add a tree item to category tree item for each of
# them
-
+
# Get first child under category tree item
blocktype_item, category_cookie = \
self.Tree.GetFirstChild(category_item)
for blocktype in category["list"]:
-
+
# Tree item already exists, set item label
if blocktype_item.IsOk():
self.Tree.SetItemText(blocktype_item, blocktype["name"])
-
+
# Tree item doesn't exist, add new one to category item
else:
blocktype_item = self.Tree.AppendItem(
@@ -234,58 +234,58 @@
# See comment when adding category
if wx.Platform != '__WXMSW__':
blocktype_item, category_cookie = \
- self.Tree.GetNextChild(category_item,
+ self.Tree.GetNextChild(category_item,
category_cookie)
-
+
# Define data to associate to block tree item
comment = blocktype["comment"]
- block_data = {"type" : BLOCK,
- "block_type" : blocktype["type"],
- "inputs" : tuple([type
+ block_data = {"type" : BLOCK,
+ "block_type" : blocktype["type"],
+ "inputs" : tuple([type
for name, type, modifier
- in blocktype["inputs"]]),
+ in blocktype["inputs"]]),
"extension" : (len(blocktype["inputs"])
if blocktype["extensible"]
else None),
- "comment": _(comment) +
+ "comment": _(comment) +
blocktype.get("usage", "")}
self.Tree.SetPyData(blocktype_item, block_data)
-
+
# Select block tree item in tree if it corresponds to
# previously selected one
- if selected_infos == (blocktype["name"],
+ if selected_infos == (blocktype["name"],
blocktype["inputs"]):
self.Tree.SelectItem(blocktype_item)
-
+
# Update TextCtrl value
self.Comment.SetValue(block_data["comment"])
-
+
# Get next block tree item under category tree item
blocktype_item, category_cookie = \
self.Tree.GetNextChild(category_item, category_cookie)
-
+
# Add every remaining tree item under category tree item after
# updating all block items to the list of items to delete
while blocktype_item.IsOk():
items_to_delete.append(blocktype_item)
blocktype_item, category_cookie = \
self.Tree.GetNextChild(category_item, category_cookie)
-
+
# Get next category tree item under root item
category_item, root_cookie = \
self.Tree.GetNextChild(root, root_cookie)
-
- # Add every remaining tree item under root item after updating all
+
+ # Add every remaining tree item under root item after updating all
# category items to the list of items to delete
while category_item.IsOk():
items_to_delete.append(category_item)
category_item, root_cookie = \
self.Tree.GetNextChild(root, root_cookie)
-
+
# Remove all items in list of items to delete from TreeCtrl
for item in items_to_delete:
self.Tree.Delete(item)
-
+
def GetSelectedBlock(self):
"""
Get selected block informations
@@ -298,17 +298,17 @@
if selected_item.IsOk() and
selected_item != self.Tree.GetRootItem()
else None)
-
+
# Return value is None if selected tree item is root or a category
- return ({"type": self.Tree.GetItemText(selected_item),
+ return ({"type": self.Tree.GetItemText(selected_item),
"inputs": selected_pydata["inputs"]}
- if selected_pydata is not None and
+ if selected_pydata is not None and
selected_pydata["type"] == BLOCK
else None)
-
+
def SelectTreeItem(self, name, inputs):
"""
- Select Tree item corresponding to block informations given
+ Select Tree item corresponding to block informations given
@param name: Block type name
@param inputs: List of block inputs type [input_type,...]
"""
@@ -318,7 +318,7 @@
# Select tree item found
self.Tree.SelectItem(item)
self.Tree.EnsureVisible(item)
-
+
def FindTreeItem(self, item, name, inputs = None):
"""
Find Tree item corresponding to block informations given
@@ -330,12 +330,12 @@
# Return immediately if item isn't valid
if not item.IsOk():
return None
-
+
# Get data associated to item to test
item_pydata = self.Tree.GetPyData(item)
if item_pydata is not None and item_pydata["type"] == BLOCK:
# Only test item corresponding to block
-
+
# Test if block inputs type are the same than those given
type_inputs = item_pydata.get("inputs", None)
type_extension = item_pydata.get("extension", None)
@@ -351,11 +351,11 @@
True)
else:
same_inputs = True
-
+
# Return item if block data corresponds to informations given
if self.Tree.GetItemText(item) == name and same_inputs:
return item
-
+
# Test item children if item doesn't correspond
child, child_cookie = self.Tree.GetFirstChild(item)
while child.IsOk():
@@ -363,9 +363,9 @@
if result:
return result
child, child_cookie = self.Tree.GetNextChild(item, child_cookie)
-
+
return None
-
+
def SearchInTree(self, value, mode="first"):
"""
Search in Tree and select item that name contains string given
@@ -378,13 +378,13 @@
root = self.Tree.GetRootItem()
if not root.IsOk():
return False
-
+
# Set function to navigate in Tree item sibling according to search
- # mode defined
+ # mode defined
sibling_function = (self.Tree.GetPrevSibling
if mode == "previous"
else self.Tree.GetNextSibling)
-
+
# Get current selected item (for next and previous mode)
item = self.Tree.GetSelection()
if not item.IsOk() or mode == "first":
@@ -392,29 +392,29 @@
selected = None
else:
selected = item
-
+
# Navigate through tree items until one matching found or reach tree
# starting or ending
while item.IsOk():
-
+
# Get item data to get item type
item_pydata = self.Tree.GetPyData(item)
-
+
# Item is a block category
if (item == root) or item_pydata["type"] == CATEGORY:
-
- # Get category first or last child according to search mode
+
+ # Get category first or last child according to search mode
# defined
child = (self.Tree.GetLastChild(item)
if mode == "previous"
else self.Tree.GetFirstChild(item)[0])
-
+
# If category has no child, go to sibling category
item = (child if child.IsOk() else sibling_function(item))
-
+
# Item is a block
else:
-
+
# Extract item block name
name = self.Tree.GetItemText(item)
# Test if block name contains string given
@@ -428,17 +428,17 @@
self.Tree.SelectItem(item)
self.Tree.EnsureVisible(item)
return True
-
+
# Go to next item sibling if block not found
next = sibling_function(item)
-
+
# If category has no other child, go to next category sibling
item = (next
if next.IsOk()
else sibling_function(self.Tree.GetItemParent(item)))
-
+
return False
-
+
def OnSearchCtrlChanged(self, event):
"""
Called when SearchCtrl text control value changed
@@ -447,7 +447,7 @@
# Search for block containing SearchCtrl value in 'first' mode
self.SearchInTree(self.SearchCtrl.GetValue())
event.Skip()
-
+
def OnSearchButtonClick(self, event):
"""
Called when SearchCtrl search button was clicked
@@ -456,7 +456,7 @@
# Search for block containing SearchCtrl value in 'next' mode
self.SearchInTree(self.SearchCtrl.GetValue(), "next")
event.Skip()
-
+
def OnTreeItemSelected(self, event):
"""
Called when tree item is selected
@@ -468,13 +468,13 @@
item_pydata["comment"]
if item_pydata is not None and item_pydata["type"] == BLOCK
else "")
-
+
# Call extra function defined when tree item is selected
if getattr(self, "_OnTreeItemSelected", None) is not None:
self._OnTreeItemSelected(event)
-
+
event.Skip()
-
+
def OnTreeBeginDrag(self, event):
"""
Called when a drag is started in tree
@@ -482,19 +482,19 @@
"""
selected_item = event.GetItem()
item_pydata = self.Tree.GetPyData(selected_item)
-
+
# Item dragged is a block
if item_pydata is not None and item_pydata["type"] == BLOCK:
# Start a drag'n drop
data = wx.TextDataObject(str(
- (self.Tree.GetItemText(selected_item),
- item_pydata["block_type"],
- "",
+ (self.Tree.GetItemText(selected_item),
+ item_pydata["block_type"],
+ "",
item_pydata["inputs"])))
dragSource = wx.DropSource(self.Tree)
dragSource.SetData(data)
dragSource.DoDragDrop()
-
+
def OnKeyDown(self, event):
"""
Called when key is pressed in SearchCtrl text control
@@ -503,17 +503,17 @@
# Get event keycode and value in SearchCtrl
keycode = event.GetKeyCode()
search_value = self.SearchCtrl.GetValue()
-
+
# Up key was pressed and SearchCtrl isn't empty, search for block in
- # 'previous' mode
+ # 'previous' mode
if keycode == wx.WXK_UP and search_value != "":
self.SearchInTree(search_value, "previous")
-
+
# Down key was pressed and SearchCtrl isn't empty, search for block in
- # 'next' mode
+ # 'next' mode
elif keycode == wx.WXK_DOWN and search_value != "":
self.SearchInTree(search_value, "next")
-
+
# Handle key normally
else:
event.Skip()
--- a/controls/LocationCellEditor.py Fri Aug 11 15:18:19 2017 +0300
+++ b/controls/LocationCellEditor.py Mon Aug 14 19:13:01 2017 +0300
@@ -27,31 +27,31 @@
from dialogs.BrowseLocationsDialog import BrowseLocationsDialog
class LocationCellControl(wx.PyControl):
-
+
'''
Custom cell editor control with a text box and a button that launches
the BrowseLocationsDialog.
'''
def __init__(self, parent):
wx.Control.__init__(self, parent)
-
+
main_sizer = wx.FlexGridSizer(cols=2, hgap=0, rows=1, vgap=0)
main_sizer.AddGrowableCol(0)
main_sizer.AddGrowableRow(0)
-
+
# create location text control
- self.Location = wx.TextCtrl(self, size=wx.Size(0, -1),
+ self.Location = wx.TextCtrl(self, size=wx.Size(0, -1),
style=wx.TE_PROCESS_ENTER)
self.Location.Bind(wx.EVT_KEY_DOWN, self.OnLocationChar)
main_sizer.AddWindow(self.Location, flag=wx.GROW)
-
+
# create browse button
self.BrowseButton = wx.Button(self, label='...', size=wx.Size(30, -1))
self.BrowseButton.Bind(wx.EVT_BUTTON, self.OnBrowseButtonClick)
main_sizer.AddWindow(self.BrowseButton, flag=wx.GROW)
-
+
self.Bind(wx.EVT_SIZE, self.OnSize)
-
+
self.SetSizer(main_sizer)
self.Controller = None
@@ -73,7 +73,7 @@
def SetValue(self, value):
self.Default = value
self.Location.SetValue(value)
-
+
def GetValue(self):
return self.Location.GetValue()
@@ -88,14 +88,14 @@
else:
infos = None
dialog.Destroy()
-
+
if infos is not None:
location = infos["location"]
# set the location
if not infos["location"].startswith("%"):
- dialog = wx.SingleChoiceDialog(self,
- _("Select a variable class:"), _("Variable class"),
- [_("Input"), _("Output"), _("Memory")],
+ dialog = wx.SingleChoiceDialog(self,
+ _("Select a variable class:"), _("Variable class"),
+ [_("Input"), _("Output"), _("Memory")],
wx.DEFAULT_DIALOG_STYLE|wx.OK|wx.CANCEL)
if dialog.ShowModal() == wx.ID_OK:
selected = dialog.GetSelection()
@@ -111,7 +111,7 @@
location = "%Q" + location
else:
location = "%M" + location
-
+
self.Location.SetValue(location)
self.VarType = infos["IEC_type"]
@@ -129,7 +129,7 @@
def SetInsertionPoint(self, i):
self.Location.SetInsertionPoint(i)
-
+
def SetFocus(self):
self.Location.SetFocus()
@@ -139,14 +139,14 @@
'''
def __init__(self, table, controller):
wx.grid.PyGridCellEditor.__init__(self)
-
+
self.Table = table
self.Controller = controller
def __del__(self):
self.CellControl = None
self.Controller = None
-
+
def Create(self, parent, id, evt_handler):
self.CellControl = LocationCellControl(parent)
self.SetControl(self.CellControl)
@@ -169,15 +169,15 @@
self.Table.SetValueByName(row, 'Type', self.CellControl.GetVarType())
self.CellControl.Disable()
return changed
-
+
if wx.VERSION >= (3, 0, 0):
def EndEdit(self, row, col, grid, oldval):
return self.EndEditInternal(row, col, grid, oldval)
else:
def EndEdit(self, row, col, grid):
- old_loc = self.Table.GetValueByName(row, 'Location')
+ old_loc = self.Table.GetValueByName(row, 'Location')
return self.EndEditInternal(row, col, grid, old_loc)
-
+
def SetSize(self, rect):
self.CellControl.SetDimensions(rect.x + 1, rect.y,
rect.width, rect.height,
@@ -185,4 +185,3 @@
def Clone(self):
return LocationCellEditor(self.Table, self.Controller)
-
--- a/controls/PouInstanceVariablesPanel.py Fri Aug 11 15:18:19 2017 +0300
+++ b/controls/PouInstanceVariablesPanel.py Mon Aug 14 19:13:01 2017 +0300
@@ -59,14 +59,14 @@
w, h = self.GetClientSize()
total_h = self.GetLineHeight(item)
r_image_w, r_image_h = self._imageListRight.GetSize(rightimages[0])
-
+
bbox_width = (r_image_w + 4) * len(rightimages) + 4
bbox_height = r_image_h + 8
bbox_x = w - bbox_width
bbox_y = item.GetY() + ((total_h > r_image_h) and [(total_h-r_image_h)/2] or [0])[0]
-
+
return wx.Rect(bbox_x, bbox_y, bbox_width, bbox_height)
-
+
return None
def IsOverItemRightImage(self, item, point):
@@ -75,30 +75,30 @@
point = self.CalcUnscrolledPosition(point)
r_image_w, r_image_h = self._imageListRight.GetSize(rightimages[0])
images_bbx = self.GetItemRightImagesBBox(item)
-
+
rect = wx.Rect(images_bbx.x + 4, images_bbx.y + 4,
r_image_w, r_image_h)
for r_image in rightimages:
if rect.Inside(point):
return r_image
rect.x += r_image_w + 4
-
+
return None
-
+
def PaintItem(self, item, dc, level, align):
CT.CustomTreeCtrl.PaintItem(self, item, dc, level, align)
-
+
rightimages = item.GetRightImages()
if len(rightimages) > 0:
images_bbx = self.GetItemRightImagesBBox(item)
r_image_w, r_image_h = self._imageListRight.GetSize(rightimages[0])
-
+
dc.SetBrush(wx.TRANSPARENT_BRUSH)
dc.SetPen(wx.TRANSPARENT_PEN)
-
+
bg_width = (r_image_w + 4) * len(rightimages) + 4
bg_height = r_image_h + 8
- dc.DrawRectangle(images_bbx.x, images_bbx.y,
+ dc.DrawRectangle(images_bbx.x, images_bbx.y,
images_bbx.width, images_bbx.height)
x_pos = images_bbx.x + 4
for r_image in rightimages:
@@ -106,7 +106,7 @@
r_image, dc, x_pos, images_bbx.y + 4,
wx.IMAGELIST_DRAW_TRANSPARENT)
x_pos += r_image_w + 4
-
+
_ButtonCallbacks = namedtuple("ButtonCallbacks", ["leftdown", "dclick"])
from PLCControler import ITEMS_VARIABLE, ITEM_CONFIGURATION, ITEM_RESOURCE, ITEM_POU, ITEM_TRANSITION, ITEM_ACTION
@@ -115,26 +115,26 @@
class PouInstanceVariablesPanel(wx.Panel):
def __init__(self, parent, window, controller, debug):
- wx.Panel.__init__(self, name='PouInstanceTreePanel',
- parent=parent, pos=wx.Point(0, 0),
+ 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(self,
bitmap=GetBitmap("top"), size=wx.Size(28, 28), style=wx.NO_BORDER)
self.ParentButton.SetToolTipString(_("Parent instance"))
- self.Bind(wx.EVT_BUTTON, self.OnParentButtonClick,
+ self.Bind(wx.EVT_BUTTON, self.OnParentButtonClick,
self.ParentButton)
-
+
self.InstanceChoice = wx.ComboBox(self, size=wx.Size(0, 0), style=wx.CB_READONLY)
self.Bind(wx.EVT_COMBOBOX, self.OnInstanceChoiceChanged,
self.InstanceChoice)
-
- self.DebugButton = wx.lib.buttons.GenBitmapButton(self,
+
+ self.DebugButton = wx.lib.buttons.GenBitmapButton(self,
bitmap=GetBitmap("debug_instance"), size=wx.Size(28, 28), style=wx.NO_BORDER)
self.DebugButton.SetToolTipString(_("Debug instance"))
- self.Bind(wx.EVT_BUTTON, self.OnDebugButtonClick,
+ self.Bind(wx.EVT_BUTTON, self.OnDebugButtonClick,
self.DebugButton)
-
+
self.VariablesList = CustomTreeCtrlWithRightImage(self,
style=wx.SUNKEN_BORDER,
agwStyle=CT.TR_NO_BUTTONS|
@@ -150,54 +150,54 @@
self.OnVariablesListItemActivated)
self.VariablesList.Bind(wx.EVT_LEFT_DOWN, self.OnVariablesListLeftDown)
self.VariablesList.Bind(wx.EVT_KEY_DOWN, self.OnVariablesListKeyDown)
-
+
self.TreeRightImageList = wx.ImageList(24, 24)
self.EditImage = self.TreeRightImageList.Add(GetBitmap("edit"))
self.DebugInstanceImage = self.TreeRightImageList.Add(GetBitmap("debug_instance"))
self.VariablesList.SetRightImageList(self.TreeRightImageList)
-
+
self.ButtonCallBacks = {
self.EditImage: _ButtonCallbacks(
self.EditButtonCallback, None),
self.DebugInstanceImage: _ButtonCallbacks(
self.DebugButtonCallback, self.DebugButtonDClickCallback)}
-
+
buttons_sizer = wx.FlexGridSizer(cols=3, hgap=0, rows=1, vgap=0)
buttons_sizer.AddWindow(self.ParentButton)
buttons_sizer.AddWindow(self.InstanceChoice, flag=wx.GROW)
buttons_sizer.AddWindow(self.DebugButton)
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, flag=wx.GROW)
main_sizer.AddWindow(self.VariablesList, 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):
if self.Controller is not None:
if tagname == "Project":
@@ -206,7 +206,7 @@
tagname = self.Controller.ComputeConfigurationName(config_name)
if pou_instance is not None:
self.PouInstance = pou_instance
-
+
if self.PouTagName != tagname:
self.PouTagName = tagname
self.RefreshView()
@@ -214,20 +214,20 @@
self.RefreshInstanceChoice()
else:
self.RefreshView()
-
+
def ResetView(self):
self.Controller = None
-
+
self.PouTagName = None
self.PouInfos = None
self.PouInstance = None
-
+
self.RefreshView()
-
+
def RefreshView(self):
self.Freeze()
self.VariablesList.DeleteAllItems()
-
+
if self.Controller is not None and self.PouTagName is not None:
if self.PouTagName.split('::')[0] in ['A', 'T']:
self.PouInfos = self.Controller.GetPouVariables('P::%s' % self.PouTagName.split('::')[1], self.Debug)
@@ -244,24 +244,24 @@
text = "%s (%s)" % (var_infos.name, var_infos.type)
else:
text = var_infos.name
-
+
right_images = []
if var_infos.edit:
right_images.append(self.EditImage)
-
+
if var_infos.debug and self.Debug:
right_images.append(self.DebugInstanceImage)
-
+
item = self.VariablesList.AppendItem(root, text)
item.SetRightImages(right_images)
self.VariablesList.SetItemImage(item, self.ParentWindow.GetTreeImage(var_infos.var_class))
self.VariablesList.SetPyData(item, var_infos)
-
+
self.RefreshInstanceChoice()
self.RefreshButtons()
-
+
self.Thaw()
-
+
def RefreshInstanceChoice(self):
self.InstanceChoice.Clear()
self.InstanceChoice.SetValue("")
@@ -279,12 +279,12 @@
else:
self.PouInstance = None
self.InstanceChoice.SetValue(_("Select an instance"))
-
+
def RefreshButtons(self):
enabled = self.InstanceChoice.GetSelection() != -1
self.ParentButton.Enable(enabled and self.PouInfos.var_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)
@@ -295,12 +295,12 @@
if child.GetName() != "edit":
child.Enable(enabled)
item, item_cookie = self.VariablesList.GetNextChild(root, item_cookie)
-
+
def EditButtonCallback(self, infos):
var_class = infos.var_class
if var_class == ITEM_RESOURCE:
tagname = self.Controller.ComputeConfigurationResourceName(
- self.InstanceChoice.GetStringSelection(),
+ self.InstanceChoice.GetStringSelection(),
infos.name)
elif var_class == ITEM_TRANSITION:
tagname = self.Controller.ComputePouTransitionName(
@@ -314,7 +314,7 @@
var_class = ITEM_POU
tagname = self.Controller.ComputePouName(infos.type)
self.ParentWindow.EditProjectElement(var_class, tagname)
-
+
def DebugButtonCallback(self, infos):
if self.InstanceChoice.GetSelection() != -1:
var_class = infos.var_class
@@ -344,16 +344,16 @@
var_class,
var_path,
self.Controller.ComputePouName(infos.type))
-
+
def DebugButtonDClickCallback(self, infos):
if self.InstanceChoice.GetSelection() != -1:
if infos.var_class in ITEMS_VARIABLE:
self.ParentWindow.AddDebugVariable(
- "%s.%s" % (self.InstanceChoice.GetStringSelection(),
- infos.name),
+ "%s.%s" % (self.InstanceChoice.GetStringSelection(),
+ infos.name),
force=True,
graph=True)
-
+
def ShowInstanceChoicePopup(self):
self.InstanceChoice.SetFocusFromKbd()
size = self.InstanceChoice.GetSize()
@@ -364,7 +364,7 @@
#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]
@@ -373,11 +373,11 @@
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(
@@ -385,26 +385,26 @@
self.InstanceChoice.GetStringSelection(),
self.PouTagName)
event.Skip()
-
+
def OnVariablesListItemActivated(self, event):
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:
-
+
item_button = self.VariablesList.IsOverItemRightImage(
selected_item, event.GetPoint())
if item_button is not None:
callback = self.ButtonCallBacks[item_button].dclick
if callback is not None:
callback(item_infos)
-
+
elif item_infos.var_class not in ITEMS_VARIABLE:
instance_path = self.InstanceChoice.GetStringSelection()
if item_infos.var_class == ITEM_RESOURCE:
if instance_path != "":
tagname = self.Controller.ComputeConfigurationResourceName(
- instance_path,
+ instance_path,
item_infos.name)
else:
tagname = None
@@ -424,7 +424,7 @@
self.SetPouType(tagname, item_path)
self.ParentWindow.SelectProjectTreeItem(tagname)
event.Skip()
-
+
def OnVariablesListLeftDown(self, event):
if self.InstanceChoice.GetSelection() == -1:
wx.CallAfter(self.ShowInstanceChoicePopup)
@@ -434,15 +434,15 @@
if item is not None:
item_infos = self.VariablesList.GetPyData(item)
if item_infos is not None:
-
+
item_button = self.VariablesList.IsOverItemRightImage(
item, event.GetPosition())
if item_button is not None:
callback = self.ButtonCallBacks[item_button].leftdown
if callback is not None:
callback(item_infos)
-
- elif (flags & CT.TREE_HITTEST_ONITEMLABEL and
+
+ elif (flags & CT.TREE_HITTEST_ONITEMLABEL and
item_infos.var_class in ITEMS_VARIABLE):
self.ParentWindow.EnsureTabVisible(
self.ParentWindow.DebugVariablePanel)
@@ -457,4 +457,3 @@
keycode = event.GetKeyCode()
if keycode != wx.WXK_LEFT:
event.Skip()
-
--- a/controls/ProjectPropertiesPanel.py Fri Aug 11 15:18:19 2017 +0300
+++ b/controls/ProjectPropertiesPanel.py Mon Aug 14 19:13:01 2017 +0300
@@ -31,7 +31,7 @@
REQUIRED_PARAMS = ["projectName", "productName", "productVersion", "companyName"]
-[TITLE, EDITORTOOLBAR, FILEMENU, EDITMENU, DISPLAYMENU, PROJECTTREE,
+[TITLE, EDITORTOOLBAR, FILEMENU, EDITMENU, DISPLAYMENU, PROJECTTREE,
POUINSTANCEVARIABLESPANEL, LIBRARYTREE, SCALING, PAGETITLES
] = range(10)
@@ -40,7 +40,7 @@
#-------------------------------------------------------------------------------
class ProjectPropertiesPanel(wx.Notebook):
-
+
def AddSizerParams(self, parent, sizer, params):
for idx, (name, label) in enumerate(params):
border = 0
@@ -48,17 +48,17 @@
border |= wx.TOP
elif idx == len(params) - 1:
border |= wx.BOTTOM
-
+
st = wx.StaticText(parent, label=label)
- sizer.AddWindow(st, border=10,
+ sizer.AddWindow(st, border=10,
flag=wx.ALIGN_CENTER_VERTICAL|border|wx.LEFT)
-
+
tc = wx.TextCtrl(parent, style=wx.TE_PROCESS_ENTER)
setattr(self, name, tc)
callback = self.GetTextCtrlChangedFunction(tc, name)
self.Bind(wx.EVT_TEXT_ENTER, callback, tc)
tc.Bind(wx.EVT_KILL_FOCUS, callback)
- sizer.AddWindow(tc, border=10,
+ sizer.AddWindow(tc, border=10,
flag=wx.GROW|border|wx.RIGHT)
def __init__(self, parent, controller=None, window=None, enable_required=True):
@@ -67,36 +67,36 @@
self.Controller = controller
self.ParentWindow = window
self.Values = None
-
+
# Project Panel elements
self.ProjectPanel = wx.Panel(self, style=wx.TAB_TRAVERSAL)
projectpanel_sizer = wx.FlexGridSizer(cols=2, hgap=5, rows=5, vgap=15)
projectpanel_sizer.AddGrowableCol(1)
self.ProjectPanel.SetSizer(projectpanel_sizer)
-
+
self.AddSizerParams(self.ProjectPanel, projectpanel_sizer,
[("projectName", _('Project Name (required):')),
("projectVersion", _('Project Version (optional):')),
("productName", _('Product Name (required):')),
("productVersion", _('Product Version (required):')),
("productRelease", _('Product Release (optional):'))])
-
+
self.AddPage(self.ProjectPanel, _("Project"))
-
+
# Author Panel elements
self.AuthorPanel = wx.Panel(self, style=wx.TAB_TRAVERSAL)
authorpanel_sizer = wx.FlexGridSizer(cols=2, hgap=5, rows=4, vgap=15)
authorpanel_sizer.AddGrowableCol(1)
self.AuthorPanel.SetSizer(authorpanel_sizer)
-
+
self.AddSizerParams(self.AuthorPanel, authorpanel_sizer,
[("companyName", _('Company Name (required):')),
("companyURL", _('Company URL (optional):')),
("authorName", _('Author Name (optional):')),
("organization", _('Organization (optional):'))])
-
+
self.AddPage(self.AuthorPanel, _("Author"))
# Graphics Panel elements
@@ -106,47 +106,47 @@
graphicpanel_sizer.AddGrowableCol(0)
graphicpanel_sizer.AddGrowableRow(3)
self.GraphicsPanel.SetSizer(graphicpanel_sizer)
-
+
pageSize_st = wx.StaticText(self.GraphicsPanel,
label=_('Page Size (optional):'))
- graphicpanel_sizer.AddWindow(pageSize_st, border=10,
+ graphicpanel_sizer.AddWindow(pageSize_st, border=10,
flag=wx.ALIGN_CENTER_VERTICAL|wx.TOP|wx.LEFT|wx.RIGHT)
-
+
pageSize_sizer = wx.FlexGridSizer(cols=2, hgap=5, rows=2, vgap=5)
pageSize_sizer.AddGrowableCol(1)
- graphicpanel_sizer.AddSizer(pageSize_sizer, border=10,
+ graphicpanel_sizer.AddSizer(pageSize_sizer, border=10,
flag=wx.GROW|wx.LEFT|wx.RIGHT)
-
+
for name, label in [('PageWidth', _('Width:')),
('PageHeight', _('Height:'))]:
st = wx.StaticText(self.GraphicsPanel, label=label)
- pageSize_sizer.AddWindow(st, border=12,
+ pageSize_sizer.AddWindow(st, border=12,
flag=wx.ALIGN_CENTER_VERTICAL|wx.LEFT)
-
- sp = wx.SpinCtrl(self.GraphicsPanel,
+
+ sp = wx.SpinCtrl(self.GraphicsPanel,
min=0, max=2**16, style=wx.TE_PROCESS_ENTER)
setattr(self, name, sp)
callback = self.GetPageSizeChangedFunction(sp, name)
self.Bind(wx.EVT_TEXT_ENTER, callback, sp)
sp.Bind(wx.EVT_KILL_FOCUS, callback)
pageSize_sizer.AddWindow(sp, flag=wx.GROW)
-
+
scaling_st = wx.StaticText(self.GraphicsPanel,
label=_('Grid Resolution:'))
- graphicpanel_sizer.AddWindow(scaling_st, border=10,
+ graphicpanel_sizer.AddWindow(scaling_st, border=10,
flag=wx.GROW|wx.LEFT|wx.RIGHT)
-
+
scaling_nb = wx.Notebook(self.GraphicsPanel)
- graphicpanel_sizer.AddWindow(scaling_nb, border=10,
+ graphicpanel_sizer.AddWindow(scaling_nb, border=10,
flag=wx.GROW|wx.BOTTOM|wx.LEFT|wx.RIGHT)
-
+
self.Scalings = {}
for language, translation in [("FBD",_("FBD")), ("LD",_("LD")), ("SFC",_("SFC"))]:
scaling_panel = wx.Panel(scaling_nb, style=wx.TAB_TRAVERSAL)
scalingpanel_sizer = wx.FlexGridSizer(cols=2, hgap=5, rows=2, vgap=5)
scalingpanel_sizer.AddGrowableCol(1)
scaling_panel.SetSizer(scalingpanel_sizer)
-
+
scaling_controls = []
for idx, (name, label) in enumerate([('XScale', _('Horizontal:')),
('YScale', _('Vertical:'))]):
@@ -154,67 +154,67 @@
border = wx.TOP
else:
border = wx.BOTTOM
-
+
st = wx.StaticText(scaling_panel, label=label)
- scalingpanel_sizer.AddWindow(st, border=10,
+ scalingpanel_sizer.AddWindow(st, border=10,
flag=wx.ALIGN_CENTER_VERTICAL|border|wx.LEFT)
-
- sp = wx.SpinCtrl(scaling_panel,
+
+ sp = wx.SpinCtrl(scaling_panel,
min=0, max=2**16, style=wx.TE_PROCESS_ENTER)
scaling_controls.append(sp)
callback = self.GetScalingChangedFunction(sp, language, name)
self.Bind(wx.EVT_TEXT_ENTER, callback, sp)
sp.Bind(wx.EVT_KILL_FOCUS, callback)
- scalingpanel_sizer.AddWindow(sp, border=10,
+ scalingpanel_sizer.AddWindow(sp, border=10,
flag=wx.GROW|border|wx.RIGHT)
-
+
self.Scalings[language] = scaling_controls
scaling_nb.AddPage(scaling_panel, translation)
-
+
self.AddPage(self.GraphicsPanel, _("Graphics"))
# Miscellaneous Panel elements
- self.MiscellaneousPanel = wx.Panel(id=-1, parent=self,
+ self.MiscellaneousPanel = wx.Panel(id=-1, parent=self,
name='MiscellaneousPanel', pos=wx.Point(0, 0),
size=wx.Size(0, 0), style=wx.TAB_TRAVERSAL)
miscellaneouspanel_sizer = wx.FlexGridSizer(cols=2, hgap=5, rows=2, vgap=15)
miscellaneouspanel_sizer.AddGrowableCol(1)
miscellaneouspanel_sizer.AddGrowableRow(1)
self.MiscellaneousPanel.SetSizer(miscellaneouspanel_sizer)
-
+
language_label = wx.StaticText(self.MiscellaneousPanel,
label=_('Language (optional):'))
- miscellaneouspanel_sizer.AddWindow(language_label, border=10,
+ miscellaneouspanel_sizer.AddWindow(language_label, border=10,
flag=wx.ALIGN_CENTER_VERTICAL|wx.TOP|wx.LEFT)
-
- self.Language = wx.ComboBox(self.MiscellaneousPanel,
+
+ self.Language = wx.ComboBox(self.MiscellaneousPanel,
style=wx.CB_READONLY)
self.Bind(wx.EVT_COMBOBOX, self.OnLanguageChanged, self.Language)
- miscellaneouspanel_sizer.AddWindow(self.Language, border=10,
+ miscellaneouspanel_sizer.AddWindow(self.Language, border=10,
flag=wx.GROW|wx.TOP|wx.RIGHT)
-
+
description_label = wx.StaticText(self.MiscellaneousPanel,
label=_('Content Description (optional):'))
- miscellaneouspanel_sizer.AddWindow(description_label, border=10,
+ miscellaneouspanel_sizer.AddWindow(description_label, border=10,
flag=wx.BOTTOM|wx.LEFT)
-
- self.ContentDescription = wx.TextCtrl(self.MiscellaneousPanel,
+
+ self.ContentDescription = wx.TextCtrl(self.MiscellaneousPanel,
size=wx.Size(240,150), style=wx.TE_MULTILINE|wx.TE_PROCESS_ENTER)
- self.Bind(wx.EVT_TEXT_ENTER, self.OnContentDescriptionChanged,
+ self.Bind(wx.EVT_TEXT_ENTER, self.OnContentDescriptionChanged,
self.ContentDescription)
- self.ContentDescription.Bind(wx.EVT_KILL_FOCUS,
+ self.ContentDescription.Bind(wx.EVT_KILL_FOCUS,
self.OnContentDescriptionChanged)
- miscellaneouspanel_sizer.AddWindow(self.ContentDescription, border=10,
+ miscellaneouspanel_sizer.AddWindow(self.ContentDescription, border=10,
flag=wx.GROW|wx.BOTTOM|wx.RIGHT)
-
+
self.AddPage(self.MiscellaneousPanel, _("Miscellaneous"))
-
+
for param in REQUIRED_PARAMS:
getattr(self, param).Enable(enable_required)
-
+
languages = ["", "en-US", "fr-FR", "zh-CN", "ru-RU"]
-
+
for language in languages:
self.Language.Append(language)
@@ -241,13 +241,13 @@
tc = getattr(self, item, None)
if tc is not None:
tc.SetValue(value)
-
+
def GetValues(self):
values = {}
for param in ["projectName", "projectVersion",
"productName", "productVersion",
"productRelease", "companyName",
- "companyURL", "authorName",
+ "companyURL", "authorName",
"organization"]:
value = getattr(self, param).GetValue()
if param in REQUIRED_PARAMS or value != "":
@@ -270,7 +270,7 @@
values["scaling"][language] = (self.Scalings[language][0].GetValue(),
self.Scalings[language][1].GetValue())
return values
-
+
def GetTextCtrlChangedFunction(self, textctrl, name):
def TextCtrlChangedFunction(event):
if self.Controller is not None and self.Values is not None:
@@ -304,7 +304,7 @@
wx.CallAfter(self.RefreshView)
event.Skip()
return PageSizeChangedFunction
-
+
def GetScalingChangedFunction(self, spinctrl, language, name):
def ScalingChangedFunction(event):
if self.Controller is not None:
@@ -324,7 +324,7 @@
wx.CallAfter(self.RefreshView)
event.Skip()
return ScalingChangedFunction
-
+
def OnLanguageChanged(self, event):
if self.Controller is not None:
if self.Values is not None:
@@ -339,7 +339,7 @@
self.ParentWindow._Refresh(TITLE, FILEMENU, EDITMENU, PAGETITLES)
wx.CallAfter(self.RefreshView)
event.Skip()
-
+
def OnContentDescriptionChanged(self, event):
if self.Controller is not None:
if self.Values is not None:
--- a/controls/SearchResultPanel.py Fri Aug 11 15:18:19 2017 +0300
+++ b/controls/SearchResultPanel.py Mon Aug 14 19:13:01 2017 +0300
@@ -45,7 +45,7 @@
#-------------------------------------------------------------------------------
[ID_SEARCHRESULTPANEL, ID_SEARCHRESULTPANELHEADERLABEL,
- ID_SEARCHRESULTPANELSEARCHRESULTSTREE, ID_SEARCHRESULTPANELRESETBUTTON,
+ ID_SEARCHRESULTPANELSEARCHRESULTSTREE, ID_SEARCHRESULTPANELRESETBUTTON,
] = [wx.NewId() for _init_ctrls in range(4)]
class SearchResultPanel(wx.Panel):
@@ -60,7 +60,7 @@
def _init_coll_MainSizer_Items(self, parent):
parent.AddSizer(self.HeaderSizer, 0, border=0, flag=wx.GROW)
parent.AddWindow(self.SearchResultsTree, 1, border=0, flag=wx.GROW)
-
+
def _init_coll_MainSizer_Growables(self, parent):
parent.AddGrowableCol(0)
parent.AddGrowableRow(1)
@@ -68,18 +68,18 @@
def _init_coll_HeaderSizer_Items(self, parent):
parent.AddWindow(self.HeaderLabel, 1, border=5, flag=wx.LEFT|wx.RIGHT|wx.ALIGN_CENTER_VERTICAL)
parent.AddWindow(self.ResetButton, 0, border=0, flag=0)
-
+
def _init_coll_HeaderSizer_Growables(self, parent):
parent.AddGrowableCol(0)
-
+
def _init_sizers(self):
self.MainSizer = wx.FlexGridSizer(cols=1, hgap=0, rows=2, vgap=0)
self.HeaderSizer = wx.BoxSizer(wx.HORIZONTAL)
-
+
self._init_coll_MainSizer_Items(self.MainSizer)
self._init_coll_MainSizer_Growables(self.MainSizer)
self._init_coll_HeaderSizer_Items(self.HeaderSizer)
-
+
self.SetSizer(self.MainSizer)
def _init_ctrls(self, prnt):
@@ -90,7 +90,7 @@
self.HeaderLabel = wx.StaticText(id=ID_SEARCHRESULTPANELHEADERLABEL,
name='HeaderLabel', parent=self,
pos=wx.Point(0, 0), size=wx.Size(0, 17), style=0)
-
+
search_results_tree_style = CT.TR_HAS_BUTTONS|CT.TR_NO_LINES|CT.TR_HAS_VARIABLE_ROW_HEIGHT
self.SearchResultsTree = CT.CustomTreeCtrl(id=ID_SEARCHRESULTPANELSEARCHRESULTSTREE,
name="SearchResultsTree", parent=self,
@@ -99,23 +99,23 @@
self.SearchResultsTree.SetAGWWindowStyleFlag(search_results_tree_style)
self.Bind(wx.EVT_TREE_ITEM_ACTIVATED, self.OnSearchResultsTreeItemActivated,
id=ID_SEARCHRESULTPANELSEARCHRESULTSTREE)
-
+
self.ResetButton = wx.lib.buttons.GenBitmapButton(self,
bitmap=GetBitmap("reset"), size=wx.Size(28, 28), style=wx.NO_BORDER)
self.ResetButton.SetToolTipString(_("Reset search result"))
self.Bind(wx.EVT_BUTTON, self.OnResetButton, self.ResetButton)
-
+
self._init_sizers()
def __init__(self, parent, window):
self.ParentWindow = window
-
+
self._init_ctrls(parent)
-
+
# Define Tree item icon list
self.TreeImageList = wx.ImageList(16, 16)
self.TreeImageDict = {}
-
+
# Icons for other items
for imgname, itemtype in [
#editables
@@ -129,40 +129,40 @@
("IL", "IL"),
("ST", "ST")]:
self.TreeImageDict[itemtype] = self.TreeImageList.Add(GetBitmap(imgname))
-
+
for itemtype in ["function", "functionBlock", "program",
"comment", "block", "io_variable",
"connector", "contact", "coil",
- "step", "transition", "jump",
- "var_local", "var_input",
+ "step", "transition", "jump",
+ "var_local", "var_input",
"var_inout", "var_output"]:
self.TreeImageDict[itemtype] = self.TreeImageList.Add(GetBitmap(itemtype.upper()))
-
+
# Assign icon list to TreeCtrl
self.SearchResultsTree.SetImageList(self.TreeImageList)
-
+
self.ResetSearchResults()
def SetSearchResults(self, criteria, search_results):
self.Criteria = criteria
self.SearchResults = {}
self.ElementsOrder = []
-
+
for infos, start, end, text in search_results:
if infos[0] not in self.ElementsOrder:
self.ElementsOrder.append(infos[0])
-
+
results = self.SearchResults.setdefault(infos[0], [])
results.append((infos, start, end, text))
-
+
self.RefreshView()
-
+
def ResetSearchResults(self):
self.Criteria = None
self.ElementsOrder = []
self.SearchResults = {}
self.RefreshView()
-
+
def RefreshView(self):
self.SearchResultsTree.DeleteAllItems()
if self.Criteria is None:
@@ -180,19 +180,19 @@
for tagname in self.ElementsOrder:
results = self.SearchResults.get(tagname, [])
matches_number += len(results)
-
+
words = tagname.split("::")
-
+
element_type = self.ParentWindow.Controler.GetElementType(tagname)
if element_type == ITEM_POU:
element_type = self.ParentWindow.Controler.GetPouType(words[1])
-
+
element_infos = {"name": words[-1],
"type": element_type,
"data": tagname,
"text": None,
"matches": len(results)}
-
+
children = element_infos.setdefault("children", [])
for infos, start, end, text in results:
if infos[1] == "name" or element_type == ITEM_DATATYPE:
@@ -223,7 +223,7 @@
"children": [],
}
children.append(child_infos)
-
+
if len(words) > 2:
for _element_infos in search_results_tree_children:
if _element_infos["name"] == words[1]:
@@ -234,41 +234,41 @@
search_results_tree_children.append(element_infos)
else:
search_results_tree_children.append(element_infos)
-
+
if matches_number < 2:
header_format = _("'{a1}' - {a2} match in project")
else:
header_format = _("'{a1}' - {a2} matches in project")
-
+
self.HeaderLabel.SetLabel(header_format.format(a1 = self.Criteria["find_pattern"], a2 = matches_number))
self.ResetButton.Enable(True)
-
+
if matches_number > 0:
root = self.SearchResultsTree.GetRootItem()
if root is None:
root = self.SearchResultsTree.AddRoot(search_results_tree_infos["name"])
self.GenerateSearchResultsTreeBranch(root, search_results_tree_infos)
self.SearchResultsTree.Expand(root)
-
+
def GetTextCtrlClickFunction(self, item):
def OnTextCtrlClick(event):
self.SearchResultsTree.SelectItem(item)
event.Skip()
return OnTextCtrlClick
-
+
def GetTextCtrlDClickFunction(self, item):
def OnTextCtrlDClick(event):
self.ShowSearchResults(item)
event.Skip()
return OnTextCtrlDClick
-
+
def GenerateSearchResultsTreeBranch(self, root, infos):
to_delete = []
if infos["name"] == "body":
item_name = "%d:" % infos["data"][1][0]
else:
item_name = infos["name"]
-
+
self.SearchResultsTree.SetItemText(root, item_name)
self.SearchResultsTree.SetPyData(root, infos["data"])
self.SearchResultsTree.SetItemBackgroundColour(root, wx.WHITE)
@@ -278,7 +278,7 @@
self.SearchResultsTree.SetItemImage(root, self.TreeImageDict[self.ParentWindow.Controler.GetPouType(infos["name"])])
else:
self.SearchResultsTree.SetItemImage(root, self.TreeImageDict[infos["type"]])
-
+
text = None
if infos["text"] is not None:
text = infos["text"]
@@ -291,12 +291,12 @@
text = _("(%d matches)") % infos["matches"]
start_idx, end_idx = 0, len(text)
style = wx.TextAttr(wx.Colour(0, 127, 174))
-
+
if text is not None:
text_ctrl_style = wx.BORDER_NONE|wx.TE_READONLY|wx.TE_RICH2
if wx.Platform != '__WXMSW__' or len(text.splitlines()) > 1:
text_ctrl_style |= wx.TE_MULTILINE
- text_ctrl = wx.TextCtrl(id=-1, parent=self.SearchResultsTree, pos=wx.Point(0, 0),
+ text_ctrl = wx.TextCtrl(id=-1, parent=self.SearchResultsTree, pos=wx.Point(0, 0),
value=text, style=text_ctrl_style)
width, height = text_ctrl.GetTextExtent(text)
text_ctrl.SetClientSize(wx.Size(width + 1, height))
@@ -306,7 +306,7 @@
text_ctrl.SetInsertionPoint(0)
text_ctrl.SetStyle(start_idx, end_idx, style)
self.SearchResultsTree.SetItemWindow(root, text_ctrl)
-
+
if wx.VERSION >= (2, 6, 0):
item, root_cookie = self.SearchResultsTree.GetFirstChild(root)
else:
@@ -317,7 +317,7 @@
item, root_cookie = self.SearchResultsTree.GetNextChild(root, root_cookie)
self.GenerateSearchResultsTreeBranch(item, child)
item, root_cookie = self.SearchResultsTree.GetNextChild(root, root_cookie)
-
+
def ShowSearchResults(self, item):
data = self.SearchResultsTree.GetPyData(item)
if isinstance(data, TupleType):
@@ -327,11 +327,11 @@
self.ParentWindow.ClearHighlights(SEARCH_RESULT_HIGHLIGHT)
for infos, start, end, text in search_results:
self.ParentWindow.ShowSearchResult(infos, start, end)
-
+
def OnSearchResultsTreeItemActivated(self, event):
self.ShowSearchResults(event.GetItem())
event.Skip()
-
+
def OnResetButton(self, event):
self.ResetSearchResults()
self.ParentWindow.ClearSearchResults()
--- a/controls/VariablePanel.py Fri Aug 11 15:18:19 2017 +0300
+++ b/controls/VariablePanel.py Mon Aug 14 19:13:01 2017 +0300
@@ -533,7 +533,7 @@
self.ColFixedSizeFlag=[True,False, True, False, True, True, False]
self.PanelWidthMin = sum(self.ColSizes)
-
+
self.ElementType = element_type
self.BodyType = None
@@ -643,7 +643,7 @@
panel_width = window.Parent.ScreenRect.Width - 35
if panel_width > self.PanelWidthMin:
stretch_cols_width = panel_width
- stretch_cols_sum = 0
+ stretch_cols_sum = 0
for col in range(len(self.ColFixedSizeFlag)):
if self.ColFixedSizeFlag[col]:
stretch_cols_width -= self.ColSizes[col]
@@ -759,7 +759,7 @@
dialog = wx.MessageDialog(self, message, _("Error"), wx.OK|wx.ICON_ERROR)
dialog.ShowModal()
dialog.Destroy()
-
+
def OnVariablesGridCellChange(self, event):
row, col = event.GetRow(), event.GetCol()
colname = self.Table.GetColLabelValue(col, False)
@@ -793,7 +793,7 @@
if message is not None:
wx.CallAfter(self.ShowErrorMessage, message)
- event.Veto()
+ event.Veto()
else:
event.Skip()
--- a/dialogs/ActionBlockDialog.py Fri Aug 11 15:18:19 2017 +0300
+++ b/dialogs/ActionBlockDialog.py Mon Aug 14 19:13:01 2017 +0300
@@ -47,7 +47,7 @@
#-------------------------------------------------------------------------------
class ActionTable(CustomTable):
-
+
def GetValue(self, row, col):
if row < self.GetNumberRows():
colname = self.GetColLabelValue(col, False)
@@ -55,7 +55,7 @@
if colname == "Type":
return _(value)
return value
-
+
def SetValue(self, row, col, value):
if col < len(self.colnames):
colname = self.GetColLabelValue(col, False)
@@ -64,7 +64,7 @@
elif colname == "Qualifier" and not self.Parent.DurationList[value]:
self.data[row].duration = ""
setattr(self.data[row], colname.lower(), value)
-
+
def _updateColAttrs(self, grid):
"""
wx.Grid -> update the column attributes to add the
@@ -72,7 +72,7 @@
Otherwise default to the default renderer.
"""
-
+
for row in range(self.GetNumberRows()):
for col in range(self.GetNumberCols()):
editor = None
@@ -103,11 +103,11 @@
elif colname == "Indicator":
editor = wx.grid.GridCellChoiceEditor()
editor.SetParameters(self.Parent.VariableList)
-
+
grid.SetCellEditor(row, col, editor)
grid.SetCellRenderer(row, col, renderer)
grid.SetReadOnly(row, col, readonly)
-
+
grid.SetCellBackgroundColour(row, col, wx.WHITE)
self.ResizeRow(grid, row)
@@ -116,56 +116,56 @@
#-------------------------------------------------------------------------------
class ActionBlockDialog(wx.Dialog):
-
+
def __init__(self, parent):
wx.Dialog.__init__(self, parent, title=_('Edit action block properties'))
-
+
main_sizer = wx.FlexGridSizer(cols=1, hgap=0, rows=3, vgap=10)
main_sizer.AddGrowableCol(0)
main_sizer.AddGrowableRow(1)
-
+
top_sizer = wx.FlexGridSizer(cols=5, hgap=5, rows=1, vgap=0)
top_sizer.AddGrowableCol(0)
top_sizer.AddGrowableRow(0)
main_sizer.AddSizer(top_sizer, border=20,
flag=wx.GROW|wx.TOP|wx.LEFT|wx.RIGHT)
-
+
actions_label = wx.StaticText(self, label=_('Actions:'))
top_sizer.AddWindow(actions_label, flag=wx.ALIGN_BOTTOM)
-
+
for name, bitmap, help in [
("AddButton", "add_element", _("Add action")),
("DeleteButton", "remove_element", _("Remove action")),
("UpButton", "up", _("Move action up")),
("DownButton", "down", _("Move action down"))]:
- button = wx.lib.buttons.GenBitmapButton(self, bitmap=GetBitmap(bitmap),
+ button = wx.lib.buttons.GenBitmapButton(self, bitmap=GetBitmap(bitmap),
size=wx.Size(28, 28), style=wx.NO_BORDER)
button.SetToolTipString(help)
setattr(self, name, button)
top_sizer.AddWindow(button)
-
+
self.ActionsGrid = CustomGrid(self, size=wx.Size(-1, 250), style=wx.VSCROLL)
self.ActionsGrid.DisableDragGridSize()
self.ActionsGrid.EnableScrolling(False, True)
- self.ActionsGrid.Bind(wx.grid.EVT_GRID_CELL_CHANGE,
+ self.ActionsGrid.Bind(wx.grid.EVT_GRID_CELL_CHANGE,
self.OnActionsGridCellChange)
main_sizer.AddSizer(self.ActionsGrid, border=20,
flag=wx.GROW|wx.LEFT|wx.RIGHT)
-
+
button_sizer = self.CreateButtonSizer(wx.OK|wx.CANCEL|wx.CENTRE)
self.Bind(wx.EVT_BUTTON, self.OnOK, button_sizer.GetAffirmativeButton())
- main_sizer.AddSizer(button_sizer, border=20,
+ main_sizer.AddSizer(button_sizer, border=20,
flag=wx.ALIGN_RIGHT|wx.BOTTOM|wx.LEFT|wx.RIGHT)
-
+
self.SetSizer(main_sizer)
-
+
self.Table = ActionTable(self, [], GetActionTableColnames())
- typelist = GetTypeList()
+ typelist = GetTypeList()
self.TypeList = ",".join(map(_,typelist))
self.TranslateType = dict([(_(value), value) for value in typelist])
self.ColSizes = [60, 90, 130, 200, 50]
self.ColAlignements = [wx.ALIGN_LEFT, wx.ALIGN_LEFT, wx.ALIGN_LEFT, wx.ALIGN_LEFT, wx.ALIGN_LEFT]
-
+
self.ActionsGrid.SetTable(self.Table)
self.ActionsGrid.SetDefaultValue(_ActionInfos("N", "Action", "", "", ""))
self.ActionsGrid.SetButtons({"Add": self.AddButton,
@@ -173,19 +173,19 @@
"Up": self.UpButton,
"Down": self.DownButton})
self.ActionsGrid.SetRowLabelSize(0)
-
+
for col in range(self.Table.GetNumberCols()):
attr = wx.grid.GridCellAttr()
attr.SetAlignment(self.ColAlignements[col], wx.ALIGN_CENTRE)
self.ActionsGrid.SetColAttr(col, attr)
self.ActionsGrid.SetColMinimalWidth(col, self.ColSizes[col])
self.ActionsGrid.AutoSizeColumn(col, False)
-
+
self.Table.ResetView(self.ActionsGrid)
self.ActionsGrid.SetFocus()
self.ActionsGrid.RefreshButtons()
self.Fit()
-
+
def OnOK(self, event):
self.ActionsGrid.CloseEditControl()
self.EndModal(wx.ID_OK)
@@ -193,14 +193,14 @@
def OnActionsGridCellChange(self, event):
wx.CallAfter(self.Table.ResetView, self.ActionsGrid)
event.Skip()
-
+
def SetQualifierList(self, list):
self.QualifierList = ",".join(list)
self.DurationList = list
def SetVariableList(self, list):
self.VariableList = "," + ",".join([variable.Name for variable in list])
-
+
def SetActionList(self, list):
self.ActionList = "," + ",".join(list)
@@ -218,7 +218,7 @@
if len(actions) > 0:
self.ActionsGrid.SetGridCursor(0, 0)
self.ActionsGrid.RefreshButtons()
-
+
def GetValues(self):
actions = self.Table.GetData()
for action in actions:
--- a/dialogs/ArrayTypeDialog.py Fri Aug 11 15:18:19 2017 +0300
+++ b/dialogs/ArrayTypeDialog.py Mon Aug 14 19:13:01 2017 +0300
@@ -39,56 +39,56 @@
#-------------------------------------------------------------------------------
class ArrayTypeDialog(wx.Dialog):
-
+
def __init__(self, parent, datatypes, infos):
wx.Dialog.__init__(self, parent, title=_('Edit array type properties'))
-
+
main_sizer = wx.FlexGridSizer(cols=1, hgap=0, rows=3, vgap=10)
main_sizer.AddGrowableCol(0)
main_sizer.AddGrowableRow(1)
-
+
top_sizer = wx.BoxSizer(wx.HORIZONTAL)
- main_sizer.AddSizer(top_sizer, border=20,
+ main_sizer.AddSizer(top_sizer, border=20,
flag=wx.GROW|wx.TOP|wx.LEFT|wx.RIGHT)
-
+
basetype_label = wx.StaticText(self, label=_('Base Type:'))
top_sizer.AddWindow(basetype_label, 1, flag=wx.ALIGN_BOTTOM)
-
+
self.BaseType = wx.ComboBox(self, style=wx.CB_READONLY)
top_sizer.AddWindow(self.BaseType, 1, flag=wx.GROW)
-
- self.Dimensions = CustomEditableListBox(self, label=_("Dimensions:"),
+
+ self.Dimensions = CustomEditableListBox(self, label=_("Dimensions:"),
style=wx.gizmos.EL_ALLOW_NEW|
wx.gizmos.EL_ALLOW_EDIT|
wx.gizmos.EL_ALLOW_DELETE)
- for func in ["_OnLabelEndEdit",
- "_OnAddButton",
- "_OnDelButton",
- "_OnUpButton",
+ for func in ["_OnLabelEndEdit",
+ "_OnAddButton",
+ "_OnDelButton",
+ "_OnUpButton",
"_OnDownButton"]:
setattr(self.Dimensions, func, self.OnDimensionsChanged)
- main_sizer.AddSizer(self.Dimensions, border=20,
+ main_sizer.AddSizer(self.Dimensions, border=20,
flag=wx.GROW|wx.LEFT|wx.RIGHT)
-
+
button_sizer = self.CreateButtonSizer(wx.OK|wx.CANCEL|wx.CENTRE)
self.Bind(wx.EVT_BUTTON, self.OnOK, button_sizer.GetAffirmativeButton())
- main_sizer.AddSizer(button_sizer, border=20,
+ main_sizer.AddSizer(button_sizer, border=20,
flag=wx.ALIGN_RIGHT|wx.BOTTOM|wx.LEFT|wx.RIGHT)
-
+
self.SetSizer(main_sizer)
-
+
for datatype in datatypes:
self.BaseType.Append(datatype)
-
+
if isinstance(infos, TupleType) and infos[0] == "array":
self.BaseType.SetStringSelection(infos[1])
self.Dimensions.SetStrings(map(lambda x : "..".join(x), infos[2]))
elif infos in datatypes:
self.BaseType.SetStringSelection(infos)
-
+
self.BaseType.SetFocus()
self.Fit()
-
+
def GetDimensions(self):
message = None
dimensions_list = []
@@ -113,14 +113,14 @@
dlg.Destroy()
return None
return dimensions_list
-
+
def OnDimensionsChanged(self, event):
wx.CallAfter(self.GetDimensions)
event.Skip()
-
+
def OnOK(self, event):
if self.GetDimensions() is not None:
self.EndModal(wx.ID_OK)
-
+
def GetValue(self):
return "array", self.BaseType.GetStringSelection(), self.GetDimensions()
--- a/dialogs/BlockPreviewDialog.py Fri Aug 11 15:18:19 2017 +0300
+++ b/dialogs/BlockPreviewDialog.py Mon Aug 14 19:13:01 2017 +0300
@@ -38,7 +38,7 @@
"""
class BlockPreviewDialog(wx.Dialog):
-
+
def __init__(self, parent, controller, tagname, title):
"""
Constructor
@@ -48,50 +48,50 @@
@param title: Title of dialog frame
"""
wx.Dialog.__init__(self, parent, title=title)
-
+
# Save reference to
self.Controller = controller
self.TagName = tagname
-
+
# Label for preview
self.PreviewLabel = wx.StaticText(self, label=_('Preview:'))
-
+
# Create Preview panel
self.Preview = wx.Panel(self, style=wx.SIMPLE_BORDER)
self.Preview.SetBackgroundColour(wx.WHITE)
-
+
# Add function to preview panel so that it answers to graphic elements
# like Viewer
setattr(self.Preview, "GetDrawingMode", lambda:FREEDRAWING_MODE)
setattr(self.Preview, "GetScaling", lambda:None)
setattr(self.Preview, "GetBlockType", controller.GetBlockType)
setattr(self.Preview, "IsOfType", controller.IsOfType)
-
+
# Bind paint event on Preview panel
self.Preview.Bind(wx.EVT_PAINT, self.OnPaint)
-
+
# Add default dialog buttons sizer
self.ButtonSizer = self.CreateButtonSizer(wx.OK|wx.CANCEL|wx.CENTRE)
- self.Bind(wx.EVT_BUTTON, self.OnOK,
+ self.Bind(wx.EVT_BUTTON, self.OnOK,
self.ButtonSizer.GetAffirmativeButton())
-
+
self.Element = None # Graphic element to display in preview
self.MinElementSize = None # Graphic element minimal size
-
+
# Variable containing the graphic element name when dialog is opened
self.DefaultElementName = None
self.Fit()
-
+
# List of variables defined in POU {var_name: (var_class, var_type),...}
self.VariableList = {}
-
+
def __del__(self):
"""
Destructor
"""
# Remove reference to project controller
self.Controller = None
-
+
def _init_sizers(self, main_rows, main_growable_row,
left_rows, left_growable_row,
right_rows, right_growable_row):
@@ -108,44 +108,44 @@
None if no row is growable
"""
# Create dialog main sizer
- self.MainSizer = wx.FlexGridSizer(cols=1, hgap=0,
+ self.MainSizer = wx.FlexGridSizer(cols=1, hgap=0,
rows=main_rows, vgap=10)
self.MainSizer.AddGrowableCol(0)
if main_growable_row is not None:
self.MainSizer.AddGrowableRow(main_growable_row)
-
+
# Create a sizer for dividing parameters in two columns
self.ColumnSizer = wx.BoxSizer(wx.HORIZONTAL)
- self.MainSizer.AddSizer(self.ColumnSizer, border=20,
+ self.MainSizer.AddSizer(self.ColumnSizer, border=20,
flag=wx.GROW|wx.TOP|wx.LEFT|wx.RIGHT)
-
+
# Create a sizer for left column
- self.LeftGridSizer = wx.FlexGridSizer(cols=1, hgap=0,
+ self.LeftGridSizer = wx.FlexGridSizer(cols=1, hgap=0,
rows=left_rows, vgap=5)
self.LeftGridSizer.AddGrowableCol(0)
if left_growable_row is not None:
self.LeftGridSizer.AddGrowableRow(left_growable_row)
- self.ColumnSizer.AddSizer(self.LeftGridSizer, 1, border=5,
+ self.ColumnSizer.AddSizer(self.LeftGridSizer, 1, border=5,
flag=wx.GROW|wx.RIGHT|wx.EXPAND)
-
+
# Create a sizer for right column
- self.RightGridSizer = wx.FlexGridSizer(cols=1, hgap=0,
+ self.RightGridSizer = wx.FlexGridSizer(cols=1, hgap=0,
rows=right_rows, vgap=0)
self.RightGridSizer.AddGrowableCol(0)
if right_growable_row is not None:
self.RightGridSizer.AddGrowableRow(right_growable_row)
- self.ColumnSizer.AddSizer(self.RightGridSizer, 1, border=5,
+ self.ColumnSizer.AddSizer(self.RightGridSizer, 1, border=5,
flag=wx.GROW|wx.LEFT)
-
+
self.SetSizer(self.MainSizer)
-
+
def SetMinElementSize(self, size):
"""
Define minimal graphic element size
@param size: Tuple containing minimal size (width, height)
"""
self.MinElementSize = size
-
+
def GetMinElementSize(self):
"""
Get minimal graphic element size
@@ -155,16 +155,16 @@
"""
if self.Element is None:
return None
-
+
return self.Element.GetMinSize()
-
+
def SetPreviewFont(self, font):
"""
Set font of Preview panel
@param font: wx.Font object containing font style
"""
self.Preview.SetFont(font)
-
+
def RefreshVariableList(self):
"""
Extract list of variables defined in POU
@@ -175,20 +175,20 @@
for var in self.Controller.GetEditedElementInterfaceVars(
self.TagName)
if var.Edit}
-
- # Add POU name to variable list if POU is a function
+
+ # Add POU name to variable list if POU is a function
returntype = self.Controller.GetEditedElementInterfaceReturnType(
self.TagName)
if returntype is not None:
self.VariableList[
self.Controller.GetEditedElementName(self.TagName)] = \
("Output", returntype)
-
+
# Add POU name if POU is a transition
words = self.TagName.split("::")
if words[0] == "T":
self.VariableList[words[2]] = ("Output", "BOOL")
-
+
def TestElementName(self, element_name):
"""
Test displayed graphic element name
@@ -198,47 +198,47 @@
message_format = None
# Get graphic element name in upper case
uppercase_element_name = element_name.upper()
-
+
# Test if graphic element name is a valid identifier
if not TestIdentifier(element_name):
message_format = _("\"%s\" is not a valid identifier!")
-
+
# Test that graphic element name isn't a keyword
elif uppercase_element_name in IEC_KEYWORDS:
message_format = _("\"%s\" is a keyword. It can't be used!")
-
+
# Test that graphic element name isn't a POU name
elif uppercase_element_name in self.Controller.GetProjectPouNames():
message_format = _("\"%s\" pou already exists!")
-
+
# Test that graphic element name isn't already used in POU by a variable
# or another graphic element
- elif ((self.DefaultElementName is None or
- self.DefaultElementName.upper() != uppercase_element_name) and
+ elif ((self.DefaultElementName is None or
+ self.DefaultElementName.upper() != uppercase_element_name) and
uppercase_element_name in self.Controller.\
GetEditedElementVariables(self.TagName)):
message_format = _("\"%s\" element for this pou already exists!")
-
+
# If an error have been identify, show error message dialog
if message_format is not None:
self.ShowErrorMessage(message_format % element_name)
# Test failed
return False
-
+
# Test succeed
return True
-
+
def ShowErrorMessage(self, message):
"""
Show an error message dialog over this dialog
@param message: Error message to display
"""
- dialog = wx.MessageDialog(self, message,
- _("Error"),
+ dialog = wx.MessageDialog(self, message,
+ _("Error"),
wx.OK|wx.ICON_ERROR)
dialog.ShowModal()
dialog.Destroy()
-
+
def OnOK(self, event):
"""
Called when dialog OK button is pressed
@@ -248,7 +248,7 @@
"""
# Close dialog
self.EndModal(wx.ID_OK)
-
+
def RefreshPreview(self):
"""
Refresh preview panel of graphic element
@@ -258,42 +258,42 @@
dc = wx.ClientDC(self.Preview)
dc.SetFont(self.Preview.GetFont())
dc.Clear()
-
+
# Return immediately if no graphic element defined
if self.Element is None:
return
-
+
# Calculate block size according to graphic element min size due to its
# parameters and graphic element min size defined
min_width, min_height = self.GetMinElementSize()
width = max(self.MinElementSize[0], min_width)
height = max(self.MinElementSize[1], min_height)
self.Element.SetSize(width, height)
-
+
# Get element position and bounding box to center in preview
posx, posy = self.Element.GetPosition()
bbox = self.Element.GetBoundingBox()
-
+
# Get Preview panel size
client_size = self.Preview.GetClientSize()
-
+
# If graphic element is too big to be displayed in preview panel,
# calculate preview panel scale so that graphic element fit inside
- scale = (max(float(bbox.width) / client_size.width,
+ scale = (max(float(bbox.width) / client_size.width,
float(bbox.height) / client_size.height) * 1.1
- if bbox.width * 1.1 > client_size.width or
+ if bbox.width * 1.1 > client_size.width or
bbox.height * 1.1 > client_size.height
else 1.0)
dc.SetUserScale(1.0 / scale, 1.0 / scale)
-
+
# Center graphic element in preview panel
x = int(client_size.width * scale - bbox.width) / 2 + posx - bbox.x
y = int(client_size.height * scale - bbox.height) / 2 + posy - bbox.y
self.Element.SetPosition(x, y)
-
+
# Draw graphic element
self.Element.Draw(dc)
-
+
def OnPaint(self, event):
"""
Called when Preview panel need to be redraw
@@ -301,4 +301,3 @@
"""
self.RefreshPreview()
event.Skip()
-
--- a/dialogs/BrowseLocationsDialog.py Fri Aug 11 15:18:19 2017 +0300
+++ b/dialogs/BrowseLocationsDialog.py Mon Aug 14 19:13:01 2017 +0300
@@ -37,16 +37,16 @@
def GetDirFilterChoiceOptions():
_ = lambda x : x
- return [(_("All"), [LOCATION_VAR_INPUT, LOCATION_VAR_OUTPUT, LOCATION_VAR_MEMORY]),
- (_("Input"), [LOCATION_VAR_INPUT]),
- (_("Output"), [LOCATION_VAR_OUTPUT]),
+ return [(_("All"), [LOCATION_VAR_INPUT, LOCATION_VAR_OUTPUT, LOCATION_VAR_MEMORY]),
+ (_("Input"), [LOCATION_VAR_INPUT]),
+ (_("Output"), [LOCATION_VAR_OUTPUT]),
(_("Memory"), [LOCATION_VAR_MEMORY])]
DIRFILTERCHOICE_OPTIONS = dict([(_(option), filter) for option, filter in GetDirFilterChoiceOptions()])
def GetTypeFilterChoiceOptions():
_ = lambda x : x
- return [_("All"),
- _("Type and derivated"),
+ return [_("All"),
+ _("Type and derivated"),
_("Type strict")]
# turn LOCATIONDATATYPES inside-out
@@ -60,81 +60,81 @@
#-------------------------------------------------------------------------------
class BrowseLocationsDialog(wx.Dialog):
-
+
def __init__(self, parent, var_type, controller):
wx.Dialog.__init__(self, parent, title=_('Browse Locations'),
style=wx.DEFAULT_DIALOG_STYLE|wx.RESIZE_BORDER)
-
+
main_sizer = wx.FlexGridSizer(cols=1, hgap=0, rows=3, vgap=10)
main_sizer.AddGrowableCol(0)
main_sizer.AddGrowableRow(1)
-
+
locations_label = wx.StaticText(self, label=_('Locations available:'))
- main_sizer.AddWindow(locations_label, border=20,
+ main_sizer.AddWindow(locations_label, border=20,
flag=wx.TOP|wx.LEFT|wx.RIGHT|wx.GROW)
-
- self.LocationsTree = wx.TreeCtrl(self,
+
+ self.LocationsTree = wx.TreeCtrl(self,
style=wx.TR_HAS_BUTTONS|wx.TR_SINGLE|wx.SUNKEN_BORDER|wx.TR_HIDE_ROOT|wx.TR_LINES_AT_ROOT)
self.LocationsTree.SetInitialSize(wx.Size(-1, 300))
- self.Bind(wx.EVT_TREE_ITEM_ACTIVATED, self.OnLocationsTreeItemActivated,
+ self.Bind(wx.EVT_TREE_ITEM_ACTIVATED, self.OnLocationsTreeItemActivated,
self.LocationsTree)
- main_sizer.AddWindow(self.LocationsTree, border=20,
+ main_sizer.AddWindow(self.LocationsTree, border=20,
flag=wx.LEFT|wx.RIGHT|wx.GROW)
-
+
button_gridsizer = wx.FlexGridSizer(cols=5, hgap=5, rows=1, vgap=0)
button_gridsizer.AddGrowableCol(1)
button_gridsizer.AddGrowableCol(3)
button_gridsizer.AddGrowableRow(0)
- main_sizer.AddSizer(button_gridsizer, border=20,
+ main_sizer.AddSizer(button_gridsizer, border=20,
flag=wx.BOTTOM|wx.LEFT|wx.RIGHT|wx.GROW)
-
+
direction_label = wx.StaticText(self, label=_('Direction:'))
button_gridsizer.AddWindow(direction_label,
flag=wx.ALIGN_CENTER_VERTICAL)
-
+
self.DirFilterChoice = wx.ComboBox(self, style=wx.CB_READONLY)
self.Bind(wx.EVT_COMBOBOX, self.OnFilterChoice, self.DirFilterChoice)
button_gridsizer.AddWindow(self.DirFilterChoice,
flag=wx.GROW|wx.ALIGN_CENTER_VERTICAL)
-
+
filter_label = wx.StaticText(self, label=_('Type:'))
button_gridsizer.AddWindow(filter_label,
flag=wx.ALIGN_CENTER_VERTICAL)
-
+
self.TypeFilterChoice = wx.ComboBox(self, style=wx.CB_READONLY)
self.Bind(wx.EVT_COMBOBOX, self.OnFilterChoice, self.TypeFilterChoice)
button_gridsizer.AddWindow(self.TypeFilterChoice,
flag=wx.GROW|wx.ALIGN_CENTER_VERTICAL)
-
+
button_sizer = self.CreateButtonSizer(wx.OK|wx.CANCEL|wx.CENTRE)
self.Bind(wx.EVT_BUTTON, self.OnOK, button_sizer.GetAffirmativeButton())
button_gridsizer.AddSizer(button_sizer, flag=wx.ALIGN_RIGHT)
-
+
self.SetSizer(main_sizer)
-
+
self.Controller = controller
self.VarType = var_type
self.BaseVarType = self.Controller.GetBaseType(self.VarType)
self.VarTypeSize = LOCATION_SIZES[self.BaseVarType]
self.Locations = self.Controller.GetVariableLocationTree()
-
+
# Define Tree item icon list
self.TreeImageList = wx.ImageList(16, 16)
self.TreeImageDict = {}
-
+
# Icons for items
for imgname, itemtype in [
- ("CONFIGURATION", LOCATION_CONFNODE),
- ("RESOURCE", LOCATION_MODULE),
- ("PROGRAM", LOCATION_GROUP),
- ("VAR_INPUT", LOCATION_VAR_INPUT),
- ("VAR_OUTPUT", LOCATION_VAR_OUTPUT),
+ ("CONFIGURATION", LOCATION_CONFNODE),
+ ("RESOURCE", LOCATION_MODULE),
+ ("PROGRAM", LOCATION_GROUP),
+ ("VAR_INPUT", LOCATION_VAR_INPUT),
+ ("VAR_OUTPUT", LOCATION_VAR_OUTPUT),
("VAR_LOCAL", LOCATION_VAR_MEMORY)]:
self.TreeImageDict[itemtype]=self.TreeImageList.Add(GetBitmap(imgname))
-
+
# Assign icon list to TreeCtrls
self.LocationsTree.SetImageList(self.TreeImageList)
-
+
# Set a options for the choice
for option, filter in GetDirFilterChoiceOptions():
self.DirFilterChoice.Append(_(option))
@@ -143,34 +143,34 @@
self.TypeFilterChoice.Append(_(option))
self.TypeFilterChoice.SetStringSelection(_("All"))
self.RefreshFilters()
-
+
self.RefreshLocationsTree()
self.Fit()
-
+
def RefreshFilters(self):
self.DirFilter = DIRFILTERCHOICE_OPTIONS[self.DirFilterChoice.GetStringSelection()]
self.TypeFilter = self.TypeFilterChoice.GetSelection()
-
+
def RefreshLocationsTree(self):
root = self.LocationsTree.GetRootItem()
if not root.IsOk():
root = self.LocationsTree.AddRoot("")
self.GenerateLocationsTreeBranch(root, self.Locations)
-
+
def FilterType(self, location_type, location_size):
if self.TypeFilter == 0:
return True
-
+
if location_size != self.VarTypeSize:
return False
-
+
if self.TypeFilter == 1:
return self.Controller.IsOfType(location_type, self.BaseVarType)
elif self.TypeFilter == 2:
return location_type == self.VarType
-
+
return True
-
+
def GenerateLocationsTreeBranch(self, root, locations):
to_delete = []
item, root_cookie = self.LocationsTree.GetFirstChild(root)
@@ -194,21 +194,21 @@
item, root_cookie = self.LocationsTree.GetNextChild(root, root_cookie)
for item in to_delete:
self.LocationsTree.Delete(item)
-
+
def OnLocationsTreeItemActivated(self, event):
infos = self.LocationsTree.GetPyData(event.GetItem())
if infos["type"] not in [LOCATION_CONFNODE, LOCATION_MODULE, LOCATION_GROUP]:
wx.CallAfter(self.EndModal, wx.ID_OK)
event.Skip()
-
+
def OnFilterChoice(self, event):
self.RefreshFilters()
self.RefreshLocationsTree()
-
+
def GetValues(self):
selected = self.LocationsTree.GetSelection()
return self.LocationsTree.GetPyData(selected)
-
+
def OnOK(self, event):
selected = self.LocationsTree.GetSelection()
var_infos = None
--- a/dialogs/BrowseValuesLibraryDialog.py Fri Aug 11 15:18:19 2017 +0300
+++ b/dialogs/BrowseValuesLibraryDialog.py Mon Aug 14 19:13:01 2017 +0300
@@ -29,7 +29,7 @@
class BrowseValuesLibraryDialog(wx.Dialog):
"""
Modal dialog that helps in selecting predefined XML attributes sets out of hierarchically organized list
- """
+ """
def __init__(self, parent, name, library, default=None):
wx.Dialog.__init__(self,
@@ -40,27 +40,27 @@
self.staticText1 = wx.StaticText(
label=_('Choose a value for %s:') % name, name='staticText1', parent=self,
pos=wx.Point(0, 0), size=wx.DefaultSize, style=0)
-
+
self.ValuesLibrary = wx.TreeCtrl(
name='ValuesLibrary', parent=self, pos=wx.Point(0, 0),
size=wx.Size(400, 200), style=wx.TR_HAS_BUTTONS|wx.TR_SINGLE|wx.SUNKEN_BORDER|wx.TR_HIDE_ROOT|wx.TR_LINES_AT_ROOT)
-
+
self.ButtonSizer = self.CreateButtonSizer(wx.OK|wx.CANCEL|wx.CENTRE)
self.Bind(wx.EVT_BUTTON, self.OnOK, id=self.ButtonSizer.GetAffirmativeButton().GetId())
-
+
self.flexGridSizer1 = wx.FlexGridSizer(cols=1, hgap=0, rows=3, vgap=10)
-
+
self.flexGridSizer1.AddWindow(self.staticText1, 0, border=20, flag=wx.GROW|wx.TOP|wx.LEFT|wx.RIGHT)
self.flexGridSizer1.AddWindow(self.ValuesLibrary, 0, border=20, flag=wx.GROW|wx.LEFT|wx.RIGHT)
self.flexGridSizer1.AddSizer(self.ButtonSizer, 0, border=20, flag=wx.ALIGN_RIGHT|wx.BOTTOM|wx.LEFT|wx.RIGHT)
-
+
self.flexGridSizer1.AddGrowableCol(0)
self.flexGridSizer1.AddGrowableRow(1)
-
+
self.SetSizer(self.flexGridSizer1)
self.Fit()
-
+
root = self.ValuesLibrary.AddRoot("")
self.GenerateValuesLibraryBranch(root, library, default)
@@ -85,4 +85,3 @@
message.Destroy()
else:
self.EndModal(wx.ID_OK)
-
--- a/dialogs/ConnectionDialog.py Fri Aug 11 15:18:19 2017 +0300
+++ b/dialogs/ConnectionDialog.py Mon Aug 14 19:13:01 2017 +0300
@@ -39,7 +39,7 @@
"""
class ConnectionDialog(BlockPreviewDialog):
-
+
def __init__(self, parent, controller, tagname, apply_button=False):
"""
Constructor
@@ -49,49 +49,49 @@
@param apply_button: Enable button for applying connector modification
to all connector having the same name in POU (default: False)
"""
- BlockPreviewDialog.__init__(self, parent, controller, tagname,
+ BlockPreviewDialog.__init__(self, parent, controller, tagname,
title=_('Connection Properties'))
-
+
# Init common sizers
self._init_sizers(2, 0, 7, 1, 0, None)
-
+
# Create label for connection type
type_label = wx.StaticText(self, label=_('Type:'))
self.LeftGridSizer.AddWindow(type_label, flag=wx.GROW)
-
+
# Create radio buttons for selecting connection type
self.TypeRadioButtons = {}
first = True
for type, label in [(CONNECTOR, _('Connector')),
(CONTINUATION, _('Continuation'))]:
- radio_button = wx.RadioButton(self, label=label,
+ radio_button = wx.RadioButton(self, label=label,
style=(wx.RB_GROUP if first else 0))
radio_button.SetValue(first)
self.Bind(wx.EVT_RADIOBUTTON, self.OnTypeChanged, radio_button)
self.LeftGridSizer.AddWindow(radio_button, flag=wx.GROW)
self.TypeRadioButtons[type] = radio_button
first = False
-
+
# Create label for connection name
name_label = wx.StaticText(self, label=_('Name:'))
self.LeftGridSizer.AddWindow(name_label, flag=wx.GROW)
-
+
# Create text control for defining connection name
self.ConnectionName = wx.TextCtrl(self)
self.ConnectionName.SetMinSize(wx.Size(200,-1))
self.Bind(wx.EVT_TEXT, self.OnNameChanged, self.ConnectionName)
self.LeftGridSizer.AddWindow(self.ConnectionName, flag=wx.GROW)
-
+
# Add preview panel and associated label to sizers
self.Preview.SetMinSize(wx.Size(-1,100))
self.LeftGridSizer.AddWindow(self.PreviewLabel, flag=wx.GROW)
self.LeftGridSizer.AddWindow(self.Preview, flag=wx.GROW)
-
+
# Add buttons sizer to sizers
- self.MainSizer.AddSizer(self.ButtonSizer, border=20,
+ self.MainSizer.AddSizer(self.ButtonSizer, border=20,
flag=wx.ALIGN_RIGHT|wx.BOTTOM|wx.LEFT|wx.RIGHT)
self.ColumnSizer.RemoveSizer(self.RightGridSizer)
-
+
# Add button for applying connection name modification to all connection
# of POU
if apply_button:
@@ -105,10 +105,10 @@
controller.GenerateNewName(
tagname, None, "Connection%d", 0))
self.Fit()
-
+
# Connector radio button is default control having keyboard focus
self.TypeRadioButtons[CONNECTOR].SetFocus()
-
+
def GetConnectionType(self):
"""
Return type selected for connection
@@ -117,7 +117,7 @@
return (CONNECTOR
if self.TypeRadioButtons[CONNECTOR].GetValue()
else CONTINUATION)
-
+
def SetValues(self, values):
"""
Set default connection parameters
@@ -125,18 +125,18 @@
"""
# For each parameters defined, set corresponding control value
for name, value in values.items():
-
+
# Parameter is connection type
if name == "type":
self.TypeRadioButtons[value].SetValue(True)
-
+
# Parameter is connection name
elif name == "name":
self.ConnectionName.SetValue(value)
-
+
# Refresh preview panel
self.RefreshPreview()
-
+
def GetValues(self):
"""
Return connection parameters defined in dialog
@@ -154,23 +154,23 @@
@return: True if connection name is valid
"""
message = None
-
+
# Get connection name typed by user
connection_name = self.ConnectionName.GetValue()
-
+
# Test that a name have been defined
if connection_name == "":
message = _("Form isn't complete. Name must be filled!")
-
+
# If an error have been identify, show error message dialog
if message is not None:
self.ShowErrorMessage(message)
# Test failed
return False
-
+
# Return result of element name test
return self.TestElementName(connection_name)
-
+
def OnOK(self, event):
"""
Called when dialog OK button is pressed
@@ -206,17 +206,16 @@
"""
self.RefreshPreview()
event.Skip()
-
+
def RefreshPreview(self):
"""
Refresh preview panel of graphic element
Override BlockPreviewDialog function
"""
# Set graphic element displayed, creating a FBD connection element
- self.Element = FBD_Connector(self.Preview,
+ self.Element = FBD_Connector(self.Preview,
self.GetConnectionType(),
self.ConnectionName.GetValue())
-
+
# Call BlockPreviewDialog function
BlockPreviewDialog.RefreshPreview(self)
-
--- a/dialogs/DiscoveryDialog.py Fri Aug 11 15:18:19 2017 +0300
+++ b/dialogs/DiscoveryDialog.py Mon Aug 14 19:13:01 2017 +0300
@@ -38,56 +38,56 @@
wx.ListCtrl.__init__(self, parent, id, pos, size, style, name=name)
listmix.ListCtrlAutoWidthMixin.__init__(self)
-[ID_DISCOVERYDIALOG, ID_DISCOVERYDIALOGSTATICTEXT1,
- ID_DISCOVERYDIALOGSERVICESLIST, ID_DISCOVERYDIALOGREFRESHBUTTON,
- ID_DISCOVERYDIALOGLOCALBUTTON, ID_DISCOVERYDIALOGIPBUTTON,
+[ID_DISCOVERYDIALOG, ID_DISCOVERYDIALOGSTATICTEXT1,
+ ID_DISCOVERYDIALOGSERVICESLIST, ID_DISCOVERYDIALOGREFRESHBUTTON,
+ ID_DISCOVERYDIALOGLOCALBUTTON, ID_DISCOVERYDIALOGIPBUTTON,
] = [wx.NewId() for _init_ctrls in range(6)]
class DiscoveryDialog(wx.Dialog, listmix.ColumnSorterMixin):
-
+
def _init_coll_MainSizer_Items(self, parent):
parent.AddWindow(self.staticText1, 0, border=20, flag=wx.TOP|wx.LEFT|wx.RIGHT|wx.GROW)
parent.AddWindow(self.ServicesList, 0, border=20, flag=wx.LEFT|wx.RIGHT|wx.GROW)
parent.AddSizer(self.ButtonGridSizer, 0, border=20, flag=wx.LEFT|wx.RIGHT|wx.BOTTOM|wx.GROW)
-
+
def _init_coll_MainSizer_Growables(self, parent):
parent.AddGrowableCol(0)
parent.AddGrowableRow(1)
-
+
def _init_coll_ButtonGridSizer_Items(self, parent):
parent.AddWindow(self.RefreshButton, 0, border=0, flag=0)
parent.AddWindow(self.LocalButton, 0, border=0, flag=0)
parent.AddWindow(self.IpButton, 0, border=0, flag=0)
parent.AddSizer(self.ButtonSizer, 0, border=0, flag=0)
-
+
def _init_coll_ButtonGridSizer_Growables(self, parent):
parent.AddGrowableCol(0)
parent.AddGrowableCol(1)
parent.AddGrowableRow(0)
-
+
def _init_sizers(self):
self.MainSizer = wx.FlexGridSizer(cols=1, hgap=0, rows=3, vgap=10)
self.ButtonGridSizer = wx.FlexGridSizer(cols=4, hgap=5, rows=1, vgap=0)
-
+
self._init_coll_MainSizer_Items(self.MainSizer)
self._init_coll_MainSizer_Growables(self.MainSizer)
self._init_coll_ButtonGridSizer_Items(self.ButtonGridSizer)
self._init_coll_ButtonGridSizer_Growables(self.ButtonGridSizer)
-
+
self.SetSizer(self.MainSizer)
-
+
def _init_ctrls(self, prnt):
- wx.Dialog.__init__(self, id=ID_DISCOVERYDIALOG,
+ wx.Dialog.__init__(self, id=ID_DISCOVERYDIALOG,
name='DiscoveryDialog', parent=prnt, style=wx.DEFAULT_DIALOG_STYLE,
title=_('Service Discovery'))
-
+
self.staticText1 = wx.StaticText(id=ID_DISCOVERYDIALOGSTATICTEXT1,
label=_('Services available:'), name='staticText1', parent=self,
pos=wx.Point(0, 0), size=wx.DefaultSize, style=0)
-
+
# Set up list control
self.ServicesList = AutoWidthListCtrl(id=ID_DISCOVERYDIALOGSERVICESLIST,
- name='ServicesList', parent=self, pos=wx.Point(0, 0), size=wx.Size(0, 0),
+ name='ServicesList', parent=self, pos=wx.Point(0, 0), size=wx.Size(0, 0),
style=wx.LC_REPORT|wx.LC_EDIT_LABELS|wx.LC_SORT_ASCENDING|wx.LC_SINGLE_SEL)
self.ServicesList.InsertColumn(0, _('NAME'))
self.ServicesList.InsertColumn(1, _('TYPE'))
@@ -100,14 +100,14 @@
self.ServicesList.SetInitialSize(wx.Size(-1, 300))
self.Bind(wx.EVT_LIST_ITEM_SELECTED, self.OnItemSelected, id=ID_DISCOVERYDIALOGSERVICESLIST)
self.Bind(wx.EVT_LIST_ITEM_ACTIVATED, self.OnItemActivated, id=ID_DISCOVERYDIALOGSERVICESLIST)
-
+
listmix.ColumnSorterMixin.__init__(self, 4)
-
+
self.RefreshButton = wx.Button(id=ID_DISCOVERYDIALOGREFRESHBUTTON,
label=_('Refresh'), name='RefreshButton', parent=self,
pos=wx.Point(0, 0), size=wx.DefaultSize, style=0)
self.Bind(wx.EVT_BUTTON, self.OnRefreshButton, id=ID_DISCOVERYDIALOGREFRESHBUTTON)
-
+
self.LocalButton = wx.Button(id=ID_DISCOVERYDIALOGLOCALBUTTON,
label=_('Local'), name='LocalButton', parent=self,
pos=wx.Point(0, 0), size=wx.DefaultSize, style=0)
@@ -117,29 +117,29 @@
label=_('Add IP'), name='IpButton', parent=self,
pos=wx.Point(0, 0), size=wx.DefaultSize, style=0)
self.Bind(wx.EVT_BUTTON, self.OnIpButton, id=ID_DISCOVERYDIALOGIPBUTTON)
-
+
self.ButtonSizer = self.CreateButtonSizer(wx.OK|wx.CANCEL|wx.CENTER)
-
+
self._init_sizers()
self.Fit()
-
+
def __init__(self, parent):
self._init_ctrls(parent)
-
+
self.itemDataMap = {}
self.nextItemId = 0
-
+
self.URI = None
self.Browser = None
-
+
self.ZeroConfInstance = Zeroconf()
self.RefreshList()
self.LatestSelection=None
-
+
def __del__(self):
if self.Browser is not None : self.Browser.cancel()
self.ZeroConfInstance.close()
-
+
def RefreshList(self):
if self.Browser is not None : self.Browser.cancel()
self.Browser = ServiceBrowser(self.ZeroConfInstance, service_type, self)
@@ -181,18 +181,18 @@
# connect_type = self.getColumnText(idx, 1)
# connect_address = self.getColumnText(idx, 2)
# connect_port = self.getColumnText(idx, 3)
-#
+#
# self.URI = "%s://%s:%s"%(connect_type, connect_address, connect_port)
def SetURI(self, idx):
self.LatestSelection = idx
- svcname = self.getColumnText(idx, 0)
+ svcname = self.getColumnText(idx, 0)
connect_type = self.getColumnText(idx, 1)
self.URI = "%s://%s"%(connect_type, svcname + '.' + service_type)
-
+
def GetURI(self):
return self.URI
-
+
def removeService(self, zeroconf, _type, name):
wx.CallAfter(self._removeService, name)
@@ -201,7 +201,7 @@
'''
called when a service with the desired type goes offline.
'''
-
+
# loop through the list items looking for the service that went offline
for idx in xrange(self.ServicesList.GetItemCount()):
# this is the unique identifier assigned to the item
@@ -213,7 +213,7 @@
if item_name == name:
self.ServicesList.DeleteItem(idx)
break
-
+
def addService(self, zeroconf, _type, name):
wx.CallAfter(self._addService, _type, name)
@@ -240,7 +240,7 @@
# we assign every list item a unique id (that won't change when items
# are added or removed)
self.ServicesList.SetItemData(new_item, self.nextItemId)
-
+
# the value of each column has to be stored in the itemDataMap
# so that ColumnSorterMixin knows how to sort the column.
@@ -249,4 +249,3 @@
self.itemDataMap[self.nextItemId] = [ svcname, typename, ip, port, name ]
self.nextItemId += 1
-
--- a/dialogs/DurationEditorDialog.py Fri Aug 11 15:18:19 2017 +0300
+++ b/dialogs/DurationEditorDialog.py Mon Aug 14 19:13:01 2017 +0300
@@ -57,43 +57,43 @@
def __init__(self, parent):
wx.Dialog.__init__(self, parent, title=_('Edit Duration'))
-
+
main_sizer = wx.FlexGridSizer(cols=1, hgap=0, rows=2, vgap=10)
main_sizer.AddGrowableCol(0)
main_sizer.AddGrowableRow(0)
-
+
controls_sizer = wx.FlexGridSizer(cols=len(CONTROLS), hgap=10, rows=2, vgap=10)
- main_sizer.AddSizer(controls_sizer, border=20,
+ main_sizer.AddSizer(controls_sizer, border=20,
flag=wx.TOP|wx.LEFT|wx.RIGHT|wx.GROW)
-
+
controls = []
for i, (name, label) in enumerate(CONTROLS):
controls_sizer.AddGrowableCol(i)
-
+
st = wx.StaticText(self, label=label)
txtctrl = wx.TextCtrl(self, value='0', style=wx.TE_PROCESS_ENTER)
- self.Bind(wx.EVT_TEXT_ENTER,
- self.GetControlValueTestFunction(txtctrl),
+ self.Bind(wx.EVT_TEXT_ENTER,
+ self.GetControlValueTestFunction(txtctrl),
txtctrl)
setattr(self, name, txtctrl)
-
+
controls.append((st, txtctrl))
-
+
for st, txtctrl in controls:
controls_sizer.AddWindow(st, flag=wx.GROW)
-
+
for st, txtctrl in controls:
controls_sizer.AddWindow(txtctrl, flag=wx.GROW)
-
+
button_sizer = self.CreateButtonSizer(wx.OK|wx.CANCEL|wx.CENTRE)
self.Bind(wx.EVT_BUTTON, self.OnOK, button_sizer.GetAffirmativeButton())
- main_sizer.AddSizer(button_sizer, border=20,
+ main_sizer.AddSizer(button_sizer, border=20,
flag=wx.ALIGN_RIGHT|wx.BOTTOM|wx.LEFT|wx.RIGHT)
-
+
self.SetSizer(main_sizer)
self.Fit()
self.Days.SetFocus()
-
+
def SetDuration(self, value):
result = IEC_TIME_MODEL.match(value.upper())
if result is not None:
@@ -112,7 +112,7 @@
else:
self.Milliseconds.SetValue("0")
self.Microseconds.SetValue("0")
-
+
def GetControlValueTestFunction(self, control):
def OnValueChanged(event):
try:
@@ -130,29 +130,29 @@
for control, factor in [(self.Days, DAY), (self.Hours, HOUR),
(self.Minutes, MINUTE), (self.Seconds, SECOND),
(self.Milliseconds, MILLISECONDS), (self.Microseconds, MICROSECONDS)]:
-
+
milliseconds += float(control.GetValue()) * factor
-
+
not_null = False
duration = "T#"
for value, format in [(int(milliseconds) / DAY, "%dd"),
((int(milliseconds) % DAY) / HOUR, "%dh"),
((int(milliseconds) % HOUR) / MINUTE, "%dm"),
((int(milliseconds) % MINUTE) / SECOND, "%ds")]:
-
+
if value > 0 or not_null:
duration += format % value
not_null = True
-
+
duration += "%gms" % (milliseconds % SECOND)
return duration
-
+
def OnOK(self, event):
self.OnCloseDialog()
def OnCloseDialog(self):
errors = []
- for control, name in [(self.Days, _("days")), (self.Hours, _("hours")),
+ for control, name in [(self.Days, _("days")), (self.Hours, _("hours")),
(self.Minutes, _("minutes")), (self.Seconds, _("seconds")),
(self.Milliseconds, _("milliseconds"))]:
try:
--- a/dialogs/FBDBlockDialog.py Fri Aug 11 15:18:19 2017 +0300
+++ b/dialogs/FBDBlockDialog.py Mon Aug 14 19:13:01 2017 +0300
@@ -48,7 +48,7 @@
"""
class FBDBlockDialog(BlockPreviewDialog):
-
+
def __init__(self, parent, controller, tagname):
"""
Constructor
@@ -58,83 +58,83 @@
"""
BlockPreviewDialog.__init__(self, parent, controller, tagname,
title=_('Block Properties'))
-
+
# Init common sizers
self._init_sizers(2, 0, 1, 0, 3, 2)
-
+
# Create static box around library panel
type_staticbox = wx.StaticBox(self, label=_('Type:'))
left_staticboxsizer = wx.StaticBoxSizer(type_staticbox, wx.VERTICAL)
self.LeftGridSizer.AddSizer(left_staticboxsizer, border=5, flag=wx.GROW)
-
+
# Create Library panel and add it to static box
self.LibraryPanel = LibraryPanel(self)
self.LibraryPanel.SetInitialSize(wx.Size(-1, 400))
-
+
# Set function to call when selection in Library panel changed
- setattr(self.LibraryPanel, "_OnTreeItemSelected",
+ setattr(self.LibraryPanel, "_OnTreeItemSelected",
self.OnLibraryTreeItemSelected)
- left_staticboxsizer.AddWindow(self.LibraryPanel, 1, border=5,
+ left_staticboxsizer.AddWindow(self.LibraryPanel, 1, border=5,
flag=wx.GROW|wx.TOP)
-
+
# Create sizer for other block parameters
top_right_gridsizer = wx.FlexGridSizer(cols=2, hgap=0, rows=4, vgap=5)
top_right_gridsizer.AddGrowableCol(1)
self.RightGridSizer.AddSizer(top_right_gridsizer, flag=wx.GROW)
-
+
# Create label for block name
name_label = wx.StaticText(self, label=_('Name:'))
- top_right_gridsizer.AddWindow(name_label,
+ top_right_gridsizer.AddWindow(name_label,
flag=wx.ALIGN_CENTER_VERTICAL)
-
+
# Create text control for defining block name
self.BlockName = wx.TextCtrl(self)
self.Bind(wx.EVT_TEXT, self.OnNameChanged, self.BlockName)
top_right_gridsizer.AddWindow(self.BlockName, flag=wx.GROW)
-
+
# Create label for extended block input number
inputs_label = wx.StaticText(self, label=_('Inputs:'))
- top_right_gridsizer.AddWindow(inputs_label,
+ top_right_gridsizer.AddWindow(inputs_label,
flag=wx.ALIGN_CENTER_VERTICAL)
-
+
# Create spin control for defining extended block input number
self.Inputs = wx.SpinCtrl(self, min=2, max=20,
style=wx.SP_ARROW_KEYS)
self.Bind(wx.EVT_SPINCTRL, self.OnInputsChanged, self.Inputs)
top_right_gridsizer.AddWindow(self.Inputs, flag=wx.GROW)
-
+
# Create label for block execution order
- execution_order_label = wx.StaticText(self,
+ execution_order_label = wx.StaticText(self,
label=_('Execution Order:'))
- top_right_gridsizer.AddWindow(execution_order_label,
+ top_right_gridsizer.AddWindow(execution_order_label,
flag=wx.ALIGN_CENTER_VERTICAL)
-
+
# Create spin control for defining block execution order
self.ExecutionOrder = wx.SpinCtrl(self, min=0, style=wx.SP_ARROW_KEYS)
- self.Bind(wx.EVT_SPINCTRL, self.OnExecutionOrderChanged,
+ self.Bind(wx.EVT_SPINCTRL, self.OnExecutionOrderChanged,
self.ExecutionOrder)
top_right_gridsizer.AddWindow(self.ExecutionOrder, flag=wx.GROW)
-
+
# Create label for block execution control
- execution_control_label = wx.StaticText(self,
+ execution_control_label = wx.StaticText(self,
label=_('Execution Control:'))
- top_right_gridsizer.AddWindow(execution_control_label,
+ top_right_gridsizer.AddWindow(execution_control_label,
flag=wx.ALIGN_CENTER_VERTICAL)
-
+
# Create check box to enable block execution control
self.ExecutionControl = wx.CheckBox(self)
- self.Bind(wx.EVT_CHECKBOX, self.OnExecutionOrderChanged,
+ self.Bind(wx.EVT_CHECKBOX, self.OnExecutionOrderChanged,
self.ExecutionControl)
top_right_gridsizer.AddWindow(self.ExecutionControl, flag=wx.GROW)
-
+
# Add preview panel and associated label to sizers
self.RightGridSizer.AddWindow(self.PreviewLabel, flag=wx.GROW)
self.RightGridSizer.AddWindow(self.Preview, flag=wx.GROW)
-
+
# Add buttons sizer to sizers
- self.MainSizer.AddSizer(self.ButtonSizer, border=20,
+ self.MainSizer.AddSizer(self.ButtonSizer, border=20,
flag=wx.ALIGN_RIGHT|wx.BOTTOM|wx.LEFT|wx.RIGHT)
-
+
# Dictionary containing correspondence between parameter exchanged and
# control to fill with parameter value
self.ParamsControl = {
@@ -142,20 +142,20 @@
"executionOrder": self.ExecutionOrder,
"executionControl": self.ExecutionControl
}
-
+
# Init controls value and sensibility
self.BlockName.SetValue("")
self.BlockName.Enable(False)
self.Inputs.Enable(False)
-
+
# Variable containing last name typed
self.CurrentBlockName = None
-
+
# Refresh Library panel values
self.LibraryPanel.SetBlockList(controller.GetBlockTypes(tagname))
self.Fit()
self.LibraryPanel.SetFocus()
-
+
def SetValues(self, values):
"""
Set default block parameters
@@ -163,38 +163,38 @@
"""
# Extract block type defined in parameters
blocktype = values.get("type", None)
-
- # Select block type in library panel
+
+ # Select block type in library panel
if blocktype is not None:
- self.LibraryPanel.SelectTreeItem(blocktype,
+ self.LibraryPanel.SelectTreeItem(blocktype,
values.get("inputs", None))
-
+
# Define regular expression for determine if block name is block
# default name
default_name_model = GetBlockTypeDefaultNameModel(blocktype)
-
+
# For each parameters defined, set corresponding control value
for name, value in values.items():
-
+
# Parameter is block name
if name == "name":
if value != "":
# Set default graphic element name for testing
self.DefaultElementName = value
-
+
# Test if block name is type default block name and save
# block name if not (name have been typed by user)
if default_name_model.match(value) is None:
self.CurrentBlockName = value
-
+
self.BlockName.ChangeValue(value)
-
+
# Set value of other controls
else:
control = self.ParamsControl.get(name, None)
if control is not None:
control.SetValue(value)
-
+
# Refresh preview panel
self.RefreshPreview()
@@ -211,7 +211,7 @@
name: control.GetValue()
for name, control in self.ParamsControl.iteritems()})
return values
-
+
def OnOK(self, event):
"""
Called when dialog OK button is pressed
@@ -219,31 +219,31 @@
@param event: wx.Event from OK button
"""
message = None
-
+
# Get block type selected
selected = self.LibraryPanel.GetSelectedBlock()
-
+
# Get block type name and if block is a function block
block_name = self.BlockName.GetValue()
name_enabled = self.BlockName.IsEnabled()
-
+
# Test that a type has been selected for block
if selected is None:
message = _("Form isn't complete. Valid block type must be selected!")
-
+
# Test, if block is a function block, that a name have been defined
elif name_enabled and block_name == "":
message = _("Form isn't complete. Name must be filled!")
-
+
# Show error message if an error is detected
if message is not None:
self.ShowErrorMessage(message)
-
+
# Test block name validity if necessary
elif not name_enabled or self.TestElementName(block_name):
# Call BlockPreviewDialog function
BlockPreviewDialog.OnOK(self, event)
-
+
def OnLibraryTreeItemSelected(self, event):
"""
Called when block type selected in library panel
@@ -251,12 +251,12 @@
"""
# Get type selected in library panel
values = self.LibraryPanel.GetSelectedBlock()
-
+
# Get block type informations
- blocktype = (self.Controller.GetBlockType(values["type"],
+ blocktype = (self.Controller.GetBlockType(values["type"],
values["inputs"])
if values is not None else None)
-
+
# Set input number spin control according to block type informations
if blocktype is not None:
self.Inputs.SetValue(len(blocktype["inputs"]))
@@ -264,12 +264,12 @@
else:
self.Inputs.SetValue(2)
self.Inputs.Enable(False)
-
+
# Update block name with default value if block type is a function and
# current block name wasn't typed by user
if blocktype is not None and blocktype["type"] != "function":
self.BlockName.Enable(True)
-
+
if self.CurrentBlockName is None:
# Generate new block name according to block type, taking
# default element name if it was already a default name for this
@@ -277,21 +277,21 @@
default_name_model = GetBlockTypeDefaultNameModel(values["type"])
block_name = (
self.DefaultElementName
- if (self.DefaultElementName is not None and
+ if (self.DefaultElementName is not None and
default_name_model.match(self.DefaultElementName))
else self.Controller.GenerateNewName(
self.TagName, None, values["type"]+"%d", 0))
else:
block_name = self.CurrentBlockName
-
+
self.BlockName.ChangeValue(block_name)
else:
self.BlockName.Enable(False)
self.BlockName.ChangeValue("")
-
+
# Refresh preview panel
self.RefreshPreview()
-
+
def OnNameChanged(self, event):
"""
Called when block name value changed
@@ -302,7 +302,7 @@
self.CurrentBlockName = self.BlockName.GetValue()
self.RefreshPreview()
event.Skip()
-
+
def OnInputsChanged(self, event):
"""
Called when block inputs number changed
@@ -311,7 +311,7 @@
if self.Inputs.IsEnabled():
self.RefreshPreview()
event.Skip()
-
+
def OnExecutionOrderChanged(self, event):
"""
Called when block execution order value changed
@@ -319,7 +319,7 @@
"""
self.RefreshPreview()
event.Skip()
-
+
def OnExecutionControlChanged(self, event):
"""
Called when block execution control value changed
@@ -327,7 +327,7 @@
"""
self.RefreshPreview()
event.Skip()
-
+
def RefreshPreview(self):
"""
Refresh preview panel of graphic element
@@ -335,22 +335,22 @@
"""
# Get type selected in library panel
values = self.LibraryPanel.GetSelectedBlock()
-
+
# If a block type is selected in library panel
if values is not None:
# Set graphic element displayed, creating a FBD block element
- self.Element = FBD_Block(self.Preview, values["type"],
+ self.Element = FBD_Block(self.Preview, values["type"],
(self.BlockName.GetValue()
if self.BlockName.IsEnabled()
- else ""),
- extension = self.Inputs.GetValue(),
- inputs = values["inputs"],
- executionControl = self.ExecutionControl.GetValue(),
+ else ""),
+ extension = self.Inputs.GetValue(),
+ inputs = values["inputs"],
+ executionControl = self.ExecutionControl.GetValue(),
executionOrder = self.ExecutionOrder.GetValue())
-
+
# Reset graphic element displayed
else:
- self.Element = None
-
+ self.Element = None
+
# Call BlockPreviewDialog function
BlockPreviewDialog.RefreshPreview(self)
--- a/dialogs/FBDVariableDialog.py Fri Aug 11 15:18:19 2017 +0300
+++ b/dialogs/FBDVariableDialog.py Mon Aug 14 19:13:01 2017 +0300
@@ -62,69 +62,69 @@
"""
BlockPreviewDialog.__init__(self, parent, controller, tagname,
title=_('Variable Properties'))
-
+
# Init common sizers
self._init_sizers(4, 2, 4, None, 3, 2)
-
+
# Create label for variable class
class_label = wx.StaticText(self, label=_('Class:'))
self.LeftGridSizer.AddWindow(class_label, flag=wx.GROW)
-
+
# Create a combo box for defining variable class
self.Class = wx.ComboBox(self, style=wx.CB_READONLY)
self.Bind(wx.EVT_COMBOBOX, self.OnClassChanged, self.Class)
self.LeftGridSizer.AddWindow(self.Class, flag=wx.GROW)
-
+
# Create label for variable execution order
- execution_order_label = wx.StaticText(self,
+ execution_order_label = wx.StaticText(self,
label=_('Execution Order:'))
self.LeftGridSizer.AddWindow(execution_order_label, flag=wx.GROW)
-
+
# Create spin control for defining variable execution order
self.ExecutionOrder = wx.SpinCtrl(self, min=0, style=wx.SP_ARROW_KEYS)
- self.Bind(wx.EVT_SPINCTRL, self.OnExecutionOrderChanged,
+ self.Bind(wx.EVT_SPINCTRL, self.OnExecutionOrderChanged,
self.ExecutionOrder)
self.LeftGridSizer.AddWindow(self.ExecutionOrder, flag=wx.GROW)
-
+
# Create label for variable expression
name_label = wx.StaticText(self, label=_('Expression:'))
- self.RightGridSizer.AddWindow(name_label, border=5,
+ self.RightGridSizer.AddWindow(name_label, border=5,
flag=wx.GROW|wx.BOTTOM)
-
+
# Create text control for defining variable expression
self.Expression = wx.TextCtrl(self)
self.Bind(wx.EVT_TEXT, self.OnExpressionChanged, self.Expression)
self.RightGridSizer.AddWindow(self.Expression, flag=wx.GROW)
-
+
# Create a list box to selected variable expression in the list of
# variables defined in POU
self.VariableName = wx.ListBox(self, size=wx.Size(-1,120),
style=wx.LB_SINGLE|wx.LB_SORT)
self.Bind(wx.EVT_LISTBOX, self.OnNameChanged, self.VariableName)
self.RightGridSizer.AddWindow(self.VariableName, border=4, flag=wx.GROW|wx.TOP)
-
+
# Add preview panel and associated label to sizers
self.MainSizer.AddWindow(self.PreviewLabel, border=20,
flag=wx.GROW|wx.LEFT|wx.RIGHT)
self.MainSizer.AddWindow(self.Preview, border=20,
flag=wx.GROW|wx.LEFT|wx.RIGHT)
-
+
# Add buttons sizer to sizers
- self.MainSizer.AddSizer(self.ButtonSizer, border=20,
+ self.MainSizer.AddSizer(self.ButtonSizer, border=20,
flag=wx.ALIGN_RIGHT|wx.BOTTOM|wx.LEFT|wx.RIGHT)
-
+
# Set options that can be selected in class combo box
for var_class, choice in VARIABLE_CLASSES_DICT.iteritems():
if not exclude_input or var_class != INPUT:
self.Class.Append(choice)
self.Class.SetSelection(0)
-
+
# Extract list of variables defined in POU
self.RefreshVariableList()
-
+
# Refresh values in name list box
self.RefreshNameList()
-
+
self.Preview.SetInitialSize(wx.Size(-1, 60))
self.Fit()
@@ -138,32 +138,32 @@
# Get variable class to select POU variable applicable
var_class = VARIABLE_CLASSES_DICT_REVERSE[
self.Class.GetStringSelection()]
-
+
# Refresh names in name list box by selecting variables in POU variables
# list that can be applied to variable class
self.VariableName.Clear()
for name, (var_type, value_type) in self.VariableList.iteritems():
if var_type != "Input" or var_class == INPUT:
self.VariableName.Append(name)
-
+
# Get variable expression and select corresponding value in name list
# box if it exists
selected = self.Expression.GetValue()
- if (selected != "" and
+ if (selected != "" and
self.VariableName.FindString(selected) != wx.NOT_FOUND):
self.VariableName.SetStringSelection(selected)
else:
self.VariableName.SetSelection(wx.NOT_FOUND)
-
+
# Disable name list box if no name present inside
self.VariableName.Enable(self.VariableName.GetCount() > 0)
-
+
def SetValues(self, values):
"""
Set default variable parameters
@param values: Variable parameters values
"""
-
+
# Get class parameter value
var_class = values.get("class", None)
if var_class is not None:
@@ -171,10 +171,10 @@
self.Class.SetStringSelection(VARIABLE_CLASSES_DICT[var_class])
# Refresh names in name list box according to var class
self.RefreshNameList()
-
+
# For each parameters defined, set corresponding control value
for name, value in values.items():
-
+
# Parameter is variable expression
if name == "expression":
# Set expression text control value
@@ -184,15 +184,15 @@
self.VariableName.SetStringSelection(value)
else:
self.VariableName.SetSelection(wx.NOT_FOUND)
-
+
# Parameter is variable execution order
elif name == "executionOrder":
self.ExecutionOrder.SetValue(value)
-
+
# Refresh preview panel
self.RefreshPreview()
self.Fit()
-
+
def GetValues(self):
"""
Return block parameters defined in dialog
@@ -215,16 +215,16 @@
@param event: wx.Event from OK button
"""
message = None
-
+
# Test that an expression have been selected or typed by user
value = self.Expression.GetValue()
if value == "":
message = _("At least a variable or an expression must be selected!")
-
+
# Show error message if an error is detected
if message is not None:
self.ShowErrorMessage(message)
-
+
else:
# Call BlockPreviewDialog function
BlockPreviewDialog.OnOK(self, event)
@@ -236,7 +236,7 @@
"""
# Refresh name list box values
self.RefreshNameList()
-
+
self.RefreshPreview()
event.Skip()
@@ -249,10 +249,10 @@
# list box if value selected is valid
if self.VariableName.GetSelection() != wx.NOT_FOUND:
self.Expression.ChangeValue(self.VariableName.GetStringSelection())
-
- self.RefreshPreview()
- event.Skip()
-
+
+ self.RefreshPreview()
+ event.Skip()
+
def OnExpressionChanged(self, event):
"""
Called when expression text control is changed by user
@@ -261,10 +261,10 @@
# Select the corresponding value in name list box if it exists
self.VariableName.SetSelection(
self.VariableName.FindString(self.Expression.GetValue()))
-
- self.RefreshPreview()
- event.Skip()
-
+
+ self.RefreshPreview()
+ event.Skip()
+
def OnExecutionOrderChanged(self, event):
"""
Called when block execution control value changed
@@ -272,7 +272,7 @@
"""
self.RefreshPreview()
event.Skip()
-
+
def RefreshPreview(self):
"""
Refresh preview panel of graphic element
@@ -280,16 +280,14 @@
"""
# Get expression value to put in FBD variable element
name = self.Expression.GetValue()
-
+
# Set graphic element displayed, creating a FBD variable element
- self.Element = FBD_Variable(self.Preview,
+ self.Element = FBD_Variable(self.Preview,
VARIABLE_CLASSES_DICT_REVERSE[
- self.Class.GetStringSelection()],
- name,
- self.VariableList.get(name, ("", ""))[1],
+ self.Class.GetStringSelection()],
+ name,
+ self.VariableList.get(name, ("", ""))[1],
executionOrder = self.ExecutionOrder.GetValue())
-
+
# Call BlockPreviewDialog function
BlockPreviewDialog.RefreshPreview(self)
-
-
--- a/dialogs/FindInPouDialog.py Fri Aug 11 15:18:19 2017 +0300
+++ b/dialogs/FindInPouDialog.py Mon Aug 14 19:13:01 2017 +0300
@@ -32,80 +32,80 @@
if parent and parent.icon:
self.SetIcon(parent.icon)
-
+
def __init__(self, parent):
- wx.Dialog.__init__(self, parent, title=_("Find"),
+ wx.Dialog.__init__(self, parent, title=_("Find"),
style=wx.CAPTION|wx.CLOSE_BOX|wx.CLIP_CHILDREN|wx.RESIZE_BORDER)
-
+
self._init_icon(parent)
panel = wx.Panel(self, style=wx.TAB_TRAVERSAL)
-
+
main_sizer = wx.FlexGridSizer(cols=1, hgap=5, rows=2, vgap=5)
main_sizer.AddGrowableCol(0)
main_sizer.AddGrowableRow(0)
-
+
controls_sizer = wx.BoxSizer(wx.VERTICAL)
- main_sizer.AddSizer(controls_sizer, border=20,
+ main_sizer.AddSizer(controls_sizer, border=20,
flag=wx.GROW|wx.TOP|wx.LEFT|wx.RIGHT)
-
+
patterns_sizer = wx.FlexGridSizer(cols=2, hgap=5, rows=1, vgap=5)
patterns_sizer.AddGrowableCol(1)
controls_sizer.AddSizer(patterns_sizer, border=5, flag=wx.GROW|wx.BOTTOM)
-
+
find_label = wx.StaticText(panel, label=_("Find:"))
patterns_sizer.AddWindow(find_label, flag=wx.ALIGN_CENTER_VERTICAL)
-
+
self.FindPattern = wx.TextCtrl(panel)
self.Bind(wx.EVT_TEXT, self.OnFindPatternChanged, self.FindPattern)
self.Bind(wx.EVT_CHAR_HOOK, self.OnEscapeKey)
patterns_sizer.AddWindow(self.FindPattern, flag=wx.GROW)
-
+
params_sizer = wx.BoxSizer(wx.HORIZONTAL)
controls_sizer.AddSizer(params_sizer, border=5, flag=wx.GROW|wx.BOTTOM)
-
+
direction_staticbox = wx.StaticBox(panel, label=_("Direction"))
direction_staticboxsizer = wx.StaticBoxSizer(
direction_staticbox, wx.VERTICAL)
- params_sizer.AddSizer(direction_staticboxsizer, 1, border=5,
+ params_sizer.AddSizer(direction_staticboxsizer, 1, border=5,
flag=wx.GROW|wx.RIGHT)
-
- self.Forward = wx.RadioButton(panel, label=_("Forward"),
+
+ self.Forward = wx.RadioButton(panel, label=_("Forward"),
style=wx.RB_GROUP)
- direction_staticboxsizer.AddWindow(self.Forward, border=5,
+ direction_staticboxsizer.AddWindow(self.Forward, border=5,
flag=wx.ALL|wx.GROW)
-
+
self.Backward = wx.RadioButton(panel, label=_("Backward"))
- direction_staticboxsizer.AddWindow(self.Backward, border=5,
+ direction_staticboxsizer.AddWindow(self.Backward, border=5,
flag=wx.ALL|wx.GROW)
-
+
options_staticbox = wx.StaticBox(panel, label=_("Options"))
options_staticboxsizer = wx.StaticBoxSizer(
options_staticbox, wx.VERTICAL)
params_sizer.AddSizer(options_staticboxsizer, 1, flag=wx.GROW)
-
+
self.CaseSensitive = wx.CheckBox(panel, label=_("Case sensitive"))
self.CaseSensitive.SetValue(True)
- options_staticboxsizer.AddWindow(self.CaseSensitive, border=5,
+ options_staticboxsizer.AddWindow(self.CaseSensitive, border=5,
flag=wx.ALL|wx.GROW)
-
+
self.WrapSearch = wx.CheckBox(panel, label=_("Wrap search"))
self.WrapSearch.SetValue(True)
- options_staticboxsizer.AddWindow(self.WrapSearch, border=5,
+ options_staticboxsizer.AddWindow(self.WrapSearch, border=5,
flag=wx.LEFT|wx.RIGHT|wx.BOTTOM|wx.GROW)
-
+
self.RegularExpressions = wx.CheckBox(panel, label=_("Regular expressions"))
- options_staticboxsizer.AddWindow(self.RegularExpressions, border=5,
+ options_staticboxsizer.AddWindow(self.RegularExpressions, border=5,
flag=wx.LEFT|wx.RIGHT|wx.BOTTOM|wx.GROW)
-
+
buttons_sizer = wx.BoxSizer(wx.HORIZONTAL)
- main_sizer.AddSizer(buttons_sizer, border=20,
+ main_sizer.AddSizer(buttons_sizer, border=20,
flag=wx.LEFT|wx.RIGHT|wx.BOTTOM|wx.ALIGN_RIGHT)
-
+
self.FindButton = wx.Button(panel, label=_("Find"))
self.FindButton.SetDefault()
self.Bind(wx.EVT_BUTTON, self.OnFindButton, self.FindButton)
buttons_sizer.AddWindow(self.FindButton, border=5, flag=wx.RIGHT)
-
+
self.CloseButton = wx.Button(panel, label=_("Close"))
self.Bind(wx.EVT_BUTTON, self.OnCloseButton, self.CloseButton)
buttons_sizer.AddWindow(self.CloseButton)
@@ -115,30 +115,30 @@
self.RegExpSyntaxErrMsg = _("Syntax error in regular expression of pattern to search!")
self.StatusLabel = wx.StaticText(panel, label= self.RegExpSyntaxErrMsg)
controls_sizer.AddWindow(self.StatusLabel, flag=wx.ALIGN_CENTER_VERTICAL)
-
+
panel.SetSizer(main_sizer)
main_sizer.Fit(self)
# clear message after dialog size calculation
self.SetStatusText("")
-
+
self.ParentWindow = parent
-
+
self.Bind(wx.EVT_CLOSE, self.OnCloseFrame)
self.infosPrev = {}
self.criteria = {}
self.FindPattern.SetFocus()
self.RefreshButtonsState()
-
+
def RefreshButtonsState(self):
find_pattern = self.FindPattern.GetValue()
self.FindButton.Enable(find_pattern != "")
-
+
def OnCloseFrame(self, event):
self.Hide()
event.Veto()
-
+
def OnCloseButton(self, event):
self.Hide()
event.Skip()
@@ -157,7 +157,7 @@
def SetStatusText(self, msg):
self.StatusLabel.SetLabel(msg)
self.Layout()
-
+
def OnFindButton(self, event):
infos = {
"find_pattern": self.FindPattern.GetValue(),
--- a/dialogs/ForceVariableDialog.py Fri Aug 11 15:18:19 2017 +0300
+++ b/dialogs/ForceVariableDialog.py Mon Aug 14 19:13:01 2017 +0300
@@ -34,7 +34,7 @@
"B" : ["SINT", "USINT", "BYTE", "STRING"],
"W" : ["INT", "UINT", "WORD", "WSTRING"],
"D" : ["DINT", "UDINT", "REAL", "DWORD"],
- "L" : ["LINT", "ULINT", "LREAL", "LWORD"]}
+ "L" : ["LINT", "ULINT", "LREAL", "LWORD"]}
def gen_get_function(f):
def get_function(v):
@@ -68,7 +68,7 @@
IEC_DATETIME_MODEL = re.compile("(?:(?:DT|DATE_AND_TIME)#)?([0-9]{4})-([0-9]{2})-([0-9]{2})-([0-9]{2}):([0-9]{2}):([0-9]{2}(?:\.[0-9]+)?)$")
IEC_TIMEOFDAY_MODEL = re.compile("(?:(?:TOD|TIME_OF_DAY)#)?([0-9]{2}):([0-9]{2}):([0-9]{2}(?:\.[0-9]+)?)$")
-def gettime(v):
+def gettime(v):
result = IEC_TIME_MODEL.match(v.upper())
if result is not None:
negative, days, hours, minutes, seconds, milliseconds = result.groups()
@@ -87,8 +87,8 @@
if negative is not None:
microseconds = -microseconds
return datetime.timedelta(microseconds=microseconds)
-
- else:
+
+ else:
return None
def getdate(v):
@@ -101,7 +101,7 @@
return None
base_date = datetime.datetime(1970, 1, 1)
return date - base_date
- else:
+ else:
return None
def getdatetime(v):
@@ -114,7 +114,7 @@
return None
base_date = datetime.datetime(1970, 1, 1)
return date - base_date
- else:
+ else:
return None
def gettimeofday(v):
@@ -159,13 +159,13 @@
class ForceVariableDialog(wx.TextEntryDialog):
def __init__(self, parent, iec_type, defaultValue=""):
- wx.TextEntryDialog.__init__(self, parent, message = _("Forcing Variable Value"),
- caption = _("Please enter value for a \"%s\" variable:") % iec_type, defaultValue = defaultValue,
+ wx.TextEntryDialog.__init__(self, parent, message = _("Forcing Variable Value"),
+ caption = _("Please enter value for a \"%s\" variable:") % iec_type, defaultValue = defaultValue,
style = wx.OK|wx.CANCEL|wx.CENTRE, pos = wx.DefaultPosition)
-
- self.IEC_Type = iec_type
-
- self.Bind(wx.EVT_BUTTON, self.OnOK,
+
+ self.IEC_Type = iec_type
+
+ self.Bind(wx.EVT_BUTTON, self.OnOK,
self.GetSizer().GetItem(2).GetSizer().GetItem(1).GetSizer().GetAffirmativeButton())
self.ValueTextCtrl=self.GetSizer().GetItem(1).GetWindow()
if self.IEC_Type == "BOOL":
--- a/dialogs/LDElementDialog.py Fri Aug 11 15:18:19 2017 +0300
+++ b/dialogs/LDElementDialog.py Mon Aug 14 19:13:01 2017 +0300
@@ -41,7 +41,7 @@
"""
class LDElementDialog(BlockPreviewDialog):
-
+
def __init__(self, parent, controller, tagname, type):
"""
Constructor
@@ -50,24 +50,24 @@
@param tagname: Tagname of project POU edited
@param type: Type of LD element ('contact or 'coil')
"""
- BlockPreviewDialog.__init__(self, parent, controller, tagname,
+ BlockPreviewDialog.__init__(self, parent, controller, tagname,
title=(_("Edit Contact Values")
if type == "contact"
else _("Edit Coil Values")))
-
+
# Init common sizers
- self._init_sizers(2, 0,
+ self._init_sizers(2, 0,
(7 if type == "contact" else 9), None, 2, 1)
-
+
# Create label for LD element modifier
modifier_label = wx.StaticText(self, label=_('Modifier:'))
- self.LeftGridSizer.AddWindow(modifier_label, border=5,
+ self.LeftGridSizer.AddWindow(modifier_label, border=5,
flag=wx.GROW|wx.BOTTOM)
-
+
# Create radio buttons for selecting LD element modifier
self.ModifierRadioButtons = {}
first = True
- element_modifiers = ([CONTACT_NORMAL, CONTACT_REVERSE,
+ element_modifiers = ([CONTACT_NORMAL, CONTACT_REVERSE,
CONTACT_RISING, CONTACT_FALLING]
if type == "contact"
else [COIL_NORMAL, COIL_REVERSE, COIL_SET,
@@ -75,55 +75,55 @@
modifiers_label = [_("Normal"), _("Negated")] + \
([_("Set"), _("Reset")] if type == "coil" else []) + \
[_("Rising Edge"), _("Falling Edge")]
-
+
for modifier, label in zip(element_modifiers, modifiers_label):
- radio_button = wx.RadioButton(self, label=label,
+ radio_button = wx.RadioButton(self, label=label,
style=(wx.RB_GROUP if first else 0))
radio_button.SetValue(first)
self.Bind(wx.EVT_RADIOBUTTON, self.OnModifierChanged, radio_button)
self.LeftGridSizer.AddWindow(radio_button, flag=wx.GROW)
self.ModifierRadioButtons[modifier] = radio_button
first = False
-
+
# Create label for LD element variable
element_variable_label = wx.StaticText(self, label=_('Variable:'))
self.LeftGridSizer.AddWindow(element_variable_label, border=5,
flag=wx.GROW|wx.TOP)
-
+
# Create a combo box for defining LD element variable
self.ElementVariable = wx.ComboBox(self, style=wx.CB_SORT)
- self.Bind(wx.EVT_COMBOBOX, self.OnVariableChanged,
+ self.Bind(wx.EVT_COMBOBOX, self.OnVariableChanged,
self.ElementVariable)
- self.Bind(wx.EVT_TEXT, self.OnVariableChanged,
- self.ElementVariable)
+ self.Bind(wx.EVT_TEXT, self.OnVariableChanged,
+ self.ElementVariable)
self.LeftGridSizer.AddWindow(self.ElementVariable, border=5,
flag=wx.GROW|wx.TOP)
-
+
# Add preview panel and associated label to sizers
self.RightGridSizer.AddWindow(self.PreviewLabel, flag=wx.GROW)
self.RightGridSizer.AddWindow(self.Preview, flag=wx.GROW)
-
+
# Add buttons sizer to sizers
- self.MainSizer.AddSizer(self.ButtonSizer, border=20,
+ self.MainSizer.AddSizer(self.ButtonSizer, border=20,
flag=wx.ALIGN_RIGHT|wx.BOTTOM|wx.LEFT|wx.RIGHT)
-
+
# Save LD element class
self.ElementClass = (LD_Contact if type == "contact" else LD_Coil)
-
+
# Extract list of variables defined in POU
self.RefreshVariableList()
-
+
# Set values in ElementVariable
for name, (var_type, value_type) in self.VariableList.iteritems():
# Only select BOOL variable and avoid input for coil
if (type == "contact" or var_type != "Input") and \
value_type == "BOOL":
self.ElementVariable.Append(name)
-
+
self.Fit()
# Normal radio button is default control having keyboard focus
self.ModifierRadioButtons[element_modifiers[0]].SetFocus()
-
+
def GetElementModifier(self):
"""
Return modifier selected for LD element
@@ -143,15 +143,15 @@
"""
# For each parameters defined, set corresponding control value
for name, value in values.items():
-
+
# Parameter is LD element variable
if name == "variable":
self.ElementVariable.SetValue(value)
-
+
# Set value of other controls
elif name == "modifier":
self.ModifierRadioButtons[value].SetValue(True)
-
+
# Refresh preview panel
self.RefreshPreview()
@@ -188,20 +188,19 @@
Override BlockPreviewDialog function
"""
value = self.ElementVariable.GetValue()
-
+
# Set graphic element displayed, creating a LD element
self.Element = self.ElementClass(
- self.Preview,
+ self.Preview,
self.GetElementModifier(),
value)
button = self.ButtonSizer.GetAffirmativeButton()
button.Enable(value != "")
-
+
# Call BlockPreviewDialog function
BlockPreviewDialog.RefreshPreview(self)
-
+
def OnOK(self, event):
if self.ElementVariable.GetValue() != "":
self.EndModal(wx.ID_OK)
-
--- a/dialogs/LDPowerRailDialog.py Fri Aug 11 15:18:19 2017 +0300
+++ b/dialogs/LDPowerRailDialog.py Mon Aug 14 19:13:01 2017 +0300
@@ -39,7 +39,7 @@
"""
class LDPowerRailDialog(BlockPreviewDialog):
-
+
def __init__(self, parent, controller, tagname):
"""
Constructor
@@ -49,50 +49,50 @@
"""
BlockPreviewDialog.__init__(self, parent, controller, tagname,
title=_('Power Rail Properties'))
-
+
# Init common sizers
self._init_sizers(2, 0, 5, None, 2, 1)
-
+
# Create label for connection type
type_label = wx.StaticText(self, label=_('Type:'))
self.LeftGridSizer.AddWindow(type_label, flag=wx.GROW)
-
+
# Create radio buttons for selecting power rail type
self.TypeRadioButtons = {}
first = True
for type, label in [(LEFTRAIL, _('Left PowerRail')),
(RIGHTRAIL, _('Right PowerRail'))]:
- radio_button = wx.RadioButton(self, label=label,
+ radio_button = wx.RadioButton(self, label=label,
style=(wx.RB_GROUP if first else 0))
radio_button.SetValue(first)
self.Bind(wx.EVT_RADIOBUTTON, self.OnTypeChanged, radio_button)
self.LeftGridSizer.AddWindow(radio_button, flag=wx.GROW)
self.TypeRadioButtons[type] = radio_button
first = False
-
+
# Create label for power rail pin number
pin_number_label = wx.StaticText(self, label=_('Pin number:'))
self.LeftGridSizer.AddWindow(pin_number_label, flag=wx.GROW)
-
+
# Create spin control for defining power rail pin number
self.PinNumber = wx.SpinCtrl(self, min=1, max=50,
style=wx.SP_ARROW_KEYS)
self.PinNumber.SetValue(1)
self.Bind(wx.EVT_SPINCTRL, self.OnPinNumberChanged, self.PinNumber)
self.LeftGridSizer.AddWindow(self.PinNumber, flag=wx.GROW)
-
+
# Add preview panel and associated label to sizers
self.RightGridSizer.AddWindow(self.PreviewLabel, flag=wx.GROW)
self.RightGridSizer.AddWindow(self.Preview, flag=wx.GROW)
-
+
# Add buttons sizer to sizers
- self.MainSizer.AddSizer(self.ButtonSizer, border=20,
+ self.MainSizer.AddSizer(self.ButtonSizer, border=20,
flag=wx.ALIGN_RIGHT|wx.BOTTOM|wx.LEFT|wx.RIGHT)
self.Fit()
-
+
# Left Power Rail radio button is default control having keyboard focus
self.TypeRadioButtons[LEFTRAIL].SetFocus()
-
+
def GetMinElementSize(self):
"""
Get minimal graphic element size
@@ -100,7 +100,7 @@
element defined
"""
return self.Element.GetMinSize(True)
-
+
def GetPowerRailType(self):
"""
Return type selected for power rail
@@ -109,7 +109,7 @@
return (LEFTRAIL
if self.TypeRadioButtons[LEFTRAIL].GetValue()
else RIGHTRAIL)
-
+
def SetValues(self, values):
"""
Set default power rail parameters
@@ -117,11 +117,11 @@
"""
# For each parameters defined, set corresponding control value
for name, value in values.items():
-
+
# Parameter is power rail type
if name == "type":
self.TypeRadioButtons[value].SetValue(True)
-
+
# Parameter is power rail pin number
elif name == "pin_number":
self.PinNumber.SetValue(value)
@@ -158,11 +158,11 @@
Refresh preview panel of graphic element
Override BlockPreviewDialog function
"""
-
+
# Set graphic element displayed, creating a power rail element
- self.Element = LD_PowerRail(self.Preview,
- self.GetPowerRailType(),
+ self.Element = LD_PowerRail(self.Preview,
+ self.GetPowerRailType(),
connectors = self.PinNumber.GetValue())
-
+
# Call BlockPreviewDialog function
BlockPreviewDialog.RefreshPreview(self)
--- a/dialogs/PouActionDialog.py Fri Aug 11 15:18:19 2017 +0300
+++ b/dialogs/PouActionDialog.py Mon Aug 14 19:13:01 2017 +0300
@@ -33,48 +33,48 @@
ACTION_LANGUAGES_DICT = dict([(_(language), language) for language in GetActionLanguages()])
class PouActionDialog(wx.Dialog):
-
+
def __init__(self, parent):
wx.Dialog.__init__(self, parent, title=_('Create a new action'))
-
+
main_sizer = wx.FlexGridSizer(cols=1, hgap=0, rows=2, vgap=10)
main_sizer.AddGrowableCol(0)
main_sizer.AddGrowableRow(0)
-
+
infos_sizer = wx.FlexGridSizer(cols=2, hgap=5, rows=3, vgap=15)
infos_sizer.AddGrowableCol(1)
- main_sizer.AddSizer(infos_sizer, border=20,
+ main_sizer.AddSizer(infos_sizer, border=20,
flag=wx.GROW|wx.TOP|wx.LEFT|wx.RIGHT)
-
+
actionname_label = wx.StaticText(self, label=_('Action Name:'))
- infos_sizer.AddWindow(actionname_label, border=4,
+ infos_sizer.AddWindow(actionname_label, border=4,
flag=wx.ALIGN_CENTER_VERTICAL|wx.TOP)
-
+
self.ActionName = wx.TextCtrl(self, size=wx.Size(180,-1))
infos_sizer.AddWindow(self.ActionName, flag=wx.GROW)
-
+
language_label = wx.StaticText(self, label=_('Language:'))
- infos_sizer.AddWindow(language_label, border=4,
+ infos_sizer.AddWindow(language_label, border=4,
flag=wx.ALIGN_CENTER_VERTICAL|wx.TOP)
-
+
self.Language = wx.ComboBox(self, style=wx.CB_READONLY)
infos_sizer.AddWindow(self.Language, flag=wx.GROW)
-
+
button_sizer = self.CreateButtonSizer(wx.OK|wx.CANCEL|wx.CENTRE)
- self.Bind(wx.EVT_BUTTON, self.OnOK,
+ self.Bind(wx.EVT_BUTTON, self.OnOK,
button_sizer.GetAffirmativeButton())
- main_sizer.AddSizer(button_sizer, border=20,
+ main_sizer.AddSizer(button_sizer, border=20,
flag=wx.ALIGN_RIGHT|wx.BOTTOM|wx.LEFT|wx.RIGHT)
-
+
self.SetSizer(main_sizer)
-
+
for option in GetActionLanguages():
self.Language.Append(_(option))
-
+
self.Fit()
self.PouNames = []
self.PouElementNames = []
-
+
def OnOK(self, event):
error = []
action_name = self.ActionName.GetValue()
@@ -91,7 +91,7 @@
elif i == len(error) - 1:
text += _(" and %s")%item
else:
- text += _(", %s")%item
+ text += _(", %s")%item
message = _("Form isn't complete. %s must be filled!") % text
elif not TestIdentifier(action_name):
message = _("\"%s\" is not a valid identifier!") % action_name
@@ -107,23 +107,22 @@
dialog.Destroy()
else:
self.EndModal(wx.ID_OK)
-
+
def SetPouNames(self, pou_names):
self.PouNames = [pou_name.upper() for pou_name in pou_names]
-
+
def SetPouElementNames(self, element_names):
self.PouElementNames = [element_name.upper() for element_name in element_names]
-
+
def SetValues(self, values):
for item, value in values.items():
if item == "actionName":
self.ActionName.SetValue(value)
elif item == "language":
self.Language.SetStringSelection(_(value))
-
+
def GetValues(self):
values = {}
values["actionName"] = self.ActionName.GetValue()
values["language"] = ACTION_LANGUAGES_DICT[self.Language.GetStringSelection()]
return values
-
--- a/dialogs/PouNameDialog.py Fri Aug 11 15:18:19 2017 +0300
+++ b/dialogs/PouNameDialog.py Mon Aug 14 19:13:01 2017 +0300
@@ -30,15 +30,15 @@
class PouNameDialog(wx.TextEntryDialog):
- def __init__(self, parent, message, caption = "Please enter text", defaultValue = "",
+ def __init__(self, parent, message, caption = "Please enter text", defaultValue = "",
style = wx.OK|wx.CANCEL|wx.CENTRE, pos = wx.DefaultPosition):
wx.TextEntryDialog.__init__(self, parent, message, caption, defaultValue, style, pos)
-
+
self.PouNames = []
-
- self.Bind(wx.EVT_BUTTON, self.OnOK,
+
+ self.Bind(wx.EVT_BUTTON, self.OnOK,
self.GetSizer().GetItem(2).GetSizer().GetItem(1).GetSizer().GetAffirmativeButton())
-
+
def OnOK(self, event):
message = None
step_name = self.GetSizer().GetItem(1).GetWindow().GetValue()
@@ -60,4 +60,3 @@
def SetPouNames(self, pou_names):
self.PouNames = [pou_name.upper() for pou_name in pou_names]
-
--- a/dialogs/PouTransitionDialog.py Fri Aug 11 15:18:19 2017 +0300
+++ b/dialogs/PouTransitionDialog.py Mon Aug 14 19:13:01 2017 +0300
@@ -37,46 +37,46 @@
TRANSITION_LANGUAGES_DICT = dict([(_(language), language) for language in GetTransitionLanguages()])
class PouTransitionDialog(wx.Dialog):
-
+
def __init__(self, parent):
wx.Dialog.__init__(self, parent, title=_('Create a new transition'))
-
+
main_sizer = wx.FlexGridSizer(cols=1, hgap=0, rows=2, vgap=10)
main_sizer.AddGrowableCol(0)
main_sizer.AddGrowableRow(0)
-
+
infos_sizer = wx.FlexGridSizer(cols=2, hgap=5, rows=3, vgap=10)
infos_sizer.AddGrowableCol(1)
- main_sizer.AddSizer(infos_sizer, border=20,
+ main_sizer.AddSizer(infos_sizer, border=20,
flag=wx.GROW|wx.TOP|wx.LEFT|wx.RIGHT)
-
+
transitionname_label = wx.StaticText(self, label=_('Transition Name:'))
- infos_sizer.AddWindow(transitionname_label, border=4,
+ infos_sizer.AddWindow(transitionname_label, border=4,
flag=wx.ALIGN_CENTER_VERTICAL|wx.TOP)
self.TransitionName = wx.TextCtrl(self, size=wx.Size(180,-1))
infos_sizer.AddWindow(self.TransitionName, flag=wx.GROW)
language_label = wx.StaticText(self, label=_('Language:'))
- infos_sizer.AddWindow(language_label, border=4,
+ infos_sizer.AddWindow(language_label, border=4,
flag=wx.ALIGN_CENTER_VERTICAL|wx.TOP)
-
+
self.Language = wx.ComboBox(self, style=wx.CB_READONLY)
infos_sizer.AddWindow(self.Language, flag=wx.GROW)
button_sizer = self.CreateButtonSizer(wx.OK|wx.CANCEL|wx.CENTRE)
self.Bind(wx.EVT_BUTTON, self.OnOK, button_sizer.GetAffirmativeButton())
main_sizer.AddSizer(button_sizer, border=20, flag=wx.ALIGN_RIGHT|wx.BOTTOM)
-
+
self.SetSizer(main_sizer)
-
+
for language in GetTransitionLanguages():
self.Language.Append(_(language))
-
+
self.Fit()
self.PouNames = []
self.PouElementNames = []
-
+
def OnOK(self, event):
error = []
transition_name = self.TransitionName.GetValue()
@@ -93,7 +93,7 @@
elif i == len(error) - 1:
text += _(" and %s")%item
else:
- text += _(", %s")%item
+ text += _(", %s")%item
message = _("Form isn't complete. %s must be filled!") % text
elif not TestIdentifier(transition_name):
message = _("\"%s\" is not a valid identifier!") % transition_name
@@ -109,20 +109,20 @@
dialog.Destroy()
else:
self.EndModal(wx.ID_OK)
-
+
def SetPouNames(self, pou_names):
self.PouNames = [pou_name.upper() for pou_name in pou_names]
-
+
def SetPouElementNames(self, pou_names):
self.PouElementNames = [pou_name.upper() for pou_name in pou_names]
-
+
def SetValues(self, values):
for item, value in values.items():
if item == "transitionName":
self.TransitionName.SetValue(value)
elif item == "language":
self.Language.SetSelection(_(value))
-
+
def GetValues(self):
values = {}
values["transitionName"] = self.TransitionName.GetValue()
--- a/dialogs/ProjectDialog.py Fri Aug 11 15:18:19 2017 +0300
+++ b/dialogs/ProjectDialog.py Mon Aug 14 19:13:01 2017 +0300
@@ -28,29 +28,29 @@
from controls.ProjectPropertiesPanel import ProjectPropertiesPanel
class ProjectDialog(wx.Dialog):
-
+
def __init__(self, parent, enable_required=True):
- wx.Dialog.__init__(self, parent, title=_('Project properties'),
+ wx.Dialog.__init__(self, parent, title=_('Project properties'),
style=wx.DEFAULT_DIALOG_STYLE)
-
+
main_sizer = wx.FlexGridSizer(cols=1, hgap=0, rows=2, vgap=10)
main_sizer.AddGrowableCol(0)
main_sizer.AddGrowableRow(0)
-
- self.ProjectProperties = ProjectPropertiesPanel(self,
+
+ self.ProjectProperties = ProjectPropertiesPanel(self,
enable_required=enable_required)
main_sizer.AddWindow(self.ProjectProperties, flag=wx.GROW)
-
+
self.ButtonSizer = self.CreateButtonSizer(wx.OK|wx.CANCEL|wx.CENTRE)
- self.Bind(wx.EVT_BUTTON, self.OnOK,
+ self.Bind(wx.EVT_BUTTON, self.OnOK,
self.ButtonSizer.GetAffirmativeButton())
- main_sizer.AddSizer(self.ButtonSizer, border=20,
+ main_sizer.AddSizer(self.ButtonSizer, border=20,
flag=wx.ALIGN_RIGHT|wx.BOTTOM|wx.LEFT|wx.RIGHT)
-
+
self.SetSizer(main_sizer)
self.ProjectProperties.Fit()
self.Fit()
-
+
def OnOK(self, event):
values = self.ProjectProperties.GetValues()
error = []
@@ -69,8 +69,8 @@
text += _(" and %s")%item
else:
text += ", %s"%item
- dialog = wx.MessageDialog(self,
- _("Form isn't complete. %s must be filled!") % text,
+ dialog = wx.MessageDialog(self,
+ _("Form isn't complete. %s must be filled!") % text,
_("Error"), wx.OK|wx.ICON_ERROR)
dialog.ShowModal()
dialog.Destroy()
@@ -79,6 +79,6 @@
def SetValues(self, values):
self.ProjectProperties.SetValues(values)
-
+
def GetValues(self):
return self.ProjectProperties.GetValues()
--- a/dialogs/SFCDivergenceDialog.py Fri Aug 11 15:18:19 2017 +0300
+++ b/dialogs/SFCDivergenceDialog.py Mon Aug 14 19:13:01 2017 +0300
@@ -40,7 +40,7 @@
"""
class SFCDivergenceDialog(BlockPreviewDialog):
-
+
def __init__(self, parent, controller, tagname, poss_div_types = None):
"""
Constructor
@@ -51,14 +51,14 @@
"""
BlockPreviewDialog.__init__(self, parent, controller, tagname,
title=_('Create a new divergence or convergence'))
-
+
# Init common sizers
self._init_sizers(2, 0, 7, None, 2, 1)
-
+
# Create label for divergence type
type_label = wx.StaticText(self, label=_('Type:'))
self.LeftGridSizer.AddWindow(type_label, flag=wx.GROW)
-
+
# Create radio buttons for selecting divergence type
divergence_buttons = [
(SELECTION_DIVERGENCE, _('Selection Divergence')),
@@ -75,7 +75,7 @@
first = True
focusbtn = None
for type, label in poss_div_btns:
- radio_button = wx.RadioButton(self, label=label,
+ radio_button = wx.RadioButton(self, label=label,
style=(wx.RB_GROUP if first else 0))
radio_button.SetValue(first)
self.Bind(wx.EVT_RADIOBUTTON, self.OnTypeChanged, radio_button)
@@ -85,29 +85,29 @@
first = False
# Create label for number of divergence sequences
- sequences_label = wx.StaticText(self,
+ sequences_label = wx.StaticText(self,
label=_('Number of sequences:'))
self.LeftGridSizer.AddWindow(sequences_label, flag=wx.GROW)
-
+
# Create spin control for defining number of divergence sequences
self.Sequences = wx.SpinCtrl(self, min=2, max=20, initial=2)
self.Bind(wx.EVT_SPINCTRL, self.OnSequencesChanged, self.Sequences)
self.LeftGridSizer.AddWindow(self.Sequences, flag=wx.GROW)
-
+
# Add preview panel and associated label to sizers
self.RightGridSizer.AddWindow(self.PreviewLabel, flag=wx.GROW)
self.RightGridSizer.AddWindow(self.Preview, flag=wx.GROW)
-
+
# Add buttons sizer to sizers
- self.MainSizer.AddSizer(self.ButtonSizer, border=20,
+ self.MainSizer.AddSizer(self.ButtonSizer, border=20,
flag=wx.ALIGN_RIGHT|wx.BOTTOM|wx.LEFT|wx.RIGHT)
-
+
self.Fit()
# Selection divergence radio button is default control having keyboard
# focus
self.TypeRadioButtons[focusbtn].SetFocus()
-
+
def GetMinElementSize(self):
"""
Get minimal graphic element size
@@ -115,7 +115,7 @@
element defined
"""
return self.Element.GetMinSize(True)
-
+
def GetDivergenceType(self):
"""
Return type selected for SFC divergence
@@ -127,7 +127,7 @@
if control.GetValue():
return type
return None
-
+
def GetValues(self):
"""
Set default SFC divergence parameters
@@ -151,17 +151,16 @@
"""
self.RefreshPreview()
event.Skip()
-
+
def RefreshPreview(self):
"""
Refresh preview panel of graphic element
Override BlockPreviewDialog function
"""
# Set graphic element displayed, creating a SFC divergence
- self.Element = SFC_Divergence(self.Preview,
- self.GetDivergenceType(),
+ self.Element = SFC_Divergence(self.Preview,
+ self.GetDivergenceType(),
self.Sequences.GetValue())
-
+
# Call BlockPreviewDialog function
BlockPreviewDialog.RefreshPreview(self)
-
--- a/dialogs/SFCStepDialog.py Fri Aug 11 15:18:19 2017 +0300
+++ b/dialogs/SFCStepDialog.py Mon Aug 14 19:13:01 2017 +0300
@@ -38,7 +38,7 @@
"""
class SFCStepDialog(BlockPreviewDialog):
-
+
def __init__(self, parent, controller, tagname, initial=False):
"""
Constructor
@@ -47,25 +47,25 @@
@param tagname: Tagname of project POU edited
@param initial: True if step is initial (default: False)
"""
- BlockPreviewDialog.__init__(self,parent, controller, tagname,
+ BlockPreviewDialog.__init__(self,parent, controller, tagname,
title=_('Edit Step'))
-
+
# Init common sizers
self._init_sizers(2, 0, 6, None, 2, 1)
-
+
# Create label for SFC step name
name_label = wx.StaticText(self, label=_('Name:'))
self.LeftGridSizer.AddWindow(name_label, flag=wx.GROW)
-
+
# Create text control for defining SFC step name
self.StepName = wx.TextCtrl(self)
self.Bind(wx.EVT_TEXT, self.OnNameChanged, self.StepName)
self.LeftGridSizer.AddWindow(self.StepName, flag=wx.GROW)
-
+
# Create label for SFC step connectors
connectors_label = wx.StaticText(self, label=_('Connectors:'))
self.LeftGridSizer.AddWindow(connectors_label, flag=wx.GROW)
-
+
# Create check boxes for defining connectors available on SFC step
self.ConnectorsCheckBox = {}
for name, label in [("input", _("Input")),
@@ -77,27 +77,27 @@
self.Bind(wx.EVT_CHECKBOX, self.OnConnectorsChanged, check_box)
self.LeftGridSizer.AddWindow(check_box, flag=wx.GROW)
self.ConnectorsCheckBox[name] = check_box
-
+
# Add preview panel and associated label to sizers
self.RightGridSizer.AddWindow(self.PreviewLabel, flag=wx.GROW)
self.RightGridSizer.AddWindow(self.Preview, flag=wx.GROW)
-
+
# Add buttons sizer to sizers
- self.MainSizer.AddSizer(self.ButtonSizer, border=20,
+ self.MainSizer.AddSizer(self.ButtonSizer, border=20,
flag=wx.ALIGN_RIGHT|wx.BOTTOM|wx.LEFT|wx.RIGHT)
-
+
# Save flag that indicates that step is initial
self.Initial = initial
-
+
# Set default name for step
self.StepName.ChangeValue(controller.GenerateNewName(
tagname, None, "Step%d", 0))
self.Fit()
-
+
# Step name text control is default control having keyboard focus
self.StepName.SetFocus()
-
+
def SetValues(self, values):
"""
Set default block parameters
@@ -105,20 +105,20 @@
"""
# For each parameters defined, set corresponding control value
for name, value in values.items():
-
+
# Parameter is step name
if name == "name":
self.StepName.ChangeValue(value)
-
+
# Set value of other controls
else:
control = self.ConnectorsCheckBox.get(name, None)
if control is not None:
control.SetValue(value)
-
+
# Refresh preview panel
self.RefreshPreview()
-
+
def GetValues(self):
"""
Return step parameters defined in dialog
@@ -130,7 +130,7 @@
for name, control in self.ConnectorsCheckBox.iteritems()})
values["width"], values["height"] = self.Element.GetSize()
return values
-
+
def OnOK(self, event):
"""
Called when dialog OK button is pressed
@@ -138,23 +138,23 @@
@param event: wx.Event from OK button
"""
message = None
-
+
# Get step name typed by user
step_name = self.StepName.GetValue()
-
+
# Test that a name have been defined
if step_name == "":
message = _("Form isn't complete. Name must be filled!")
-
+
# If an error have been identify, show error message dialog
if message is not None:
self.ShowErrorMessage(message)
-
+
# Test step name validity
elif self.TestElementName(step_name):
# Call BlockPreviewDialog function
BlockPreviewDialog.OnOK(self, event)
-
+
def OnConnectorsChanged(self, event):
"""
Called when a step connector value changed
@@ -170,23 +170,23 @@
"""
self.RefreshPreview()
event.Skip()
-
+
def RefreshPreview(self):
"""
Refresh preview panel of graphic element
Override BlockPreviewDialog function
"""
# Set graphic element displayed, creating a SFC step element
- self.Element = SFC_Step(self.Preview,
- self.StepName.GetValue(),
+ self.Element = SFC_Step(self.Preview,
+ self.StepName.GetValue(),
self.Initial)
-
+
# Update connectors of SFC step element according to check boxes value
for name, control in self.ConnectorsCheckBox.iteritems():
if control.IsChecked():
getattr(self.Element, "Add" + name.capitalize())()
else:
getattr(self.Element, "Remove" + name.capitalize())()
-
+
# Call BlockPreviewDialog function
BlockPreviewDialog.RefreshPreview(self)
--- a/dialogs/SFCStepNameDialog.py Fri Aug 11 15:18:19 2017 +0300
+++ b/dialogs/SFCStepNameDialog.py Mon Aug 14 19:13:01 2017 +0300
@@ -30,17 +30,17 @@
class SFCStepNameDialog(wx.TextEntryDialog):
- def __init__(self, parent, message, caption = "Please enter text", defaultValue = "",
+ def __init__(self, parent, message, caption = "Please enter text", defaultValue = "",
style = wx.OK|wx.CANCEL|wx.CENTRE, pos = wx.DefaultPosition):
wx.TextEntryDialog.__init__(self, parent, message, caption, defaultValue, style, pos)
-
+
self.PouNames = []
self.Variables = []
self.StepNames = []
-
- self.Bind(wx.EVT_BUTTON, self.OnOK,
+
+ self.Bind(wx.EVT_BUTTON, self.OnOK,
self.GetSizer().GetItem(2).GetSizer().GetItem(1).GetSizer().GetAffirmativeButton())
-
+
def OnOK(self, event):
message = None
step_name = self.GetSizer().GetItem(1).GetWindow().GetValue()
--- a/dialogs/SFCTransitionDialog.py Fri Aug 11 15:18:19 2017 +0300
+++ b/dialogs/SFCTransitionDialog.py Mon Aug 14 19:13:01 2017 +0300
@@ -38,7 +38,7 @@
"""
class SFCTransitionDialog(BlockPreviewDialog):
-
+
def __init__(self, parent, controller, tagname, connection=True):
"""
Constructor
@@ -50,32 +50,32 @@
"""
BlockPreviewDialog.__init__(self, parent, controller, tagname,
title=_('Edit transition'))
-
+
# Init common sizers
self._init_sizers(2, 0, 8, None, 2, 1)
-
+
# Create label for transition type
type_label = wx.StaticText(self, label=_('Type:'))
self.LeftGridSizer.AddWindow(type_label, flag=wx.GROW)
-
+
# Create combo box for selecting reference value
reference = wx.ComboBox(self, style=wx.CB_READONLY)
reference.Append("")
for transition in controller.GetEditedElementTransitions(tagname):
reference.Append(transition)
self.Bind(wx.EVT_COMBOBOX, self.OnReferenceChanged, reference)
-
+
# Create Text control for defining inline value
inline = wx.TextCtrl(self)
self.Bind(wx.EVT_TEXT, self.OnInlineChanged, inline)
-
+
# Create radio buttons for selecting power rail type
self.TypeRadioButtons = {}
first = True
for type, label, control in [('reference', _('Reference'), reference),
('inline', _('Inline'), inline),
('connection', _('Connection'), None)]:
- radio_button = wx.RadioButton(self, label=label,
+ radio_button = wx.RadioButton(self, label=label,
style=(wx.RB_GROUP if first else 0))
radio_button.SetValue(first)
self.Bind(wx.EVT_RADIOBUTTON, self.OnTypeChanged, radio_button)
@@ -85,29 +85,29 @@
self.LeftGridSizer.AddWindow(control, flag=wx.GROW)
self.TypeRadioButtons[type] = (radio_button, control)
first = False
-
+
# Create label for transition priority
priority_label = wx.StaticText(self, label=_('Priority:'))
self.LeftGridSizer.AddWindow(priority_label, flag=wx.GROW)
-
+
# Create spin control for defining priority value
self.Priority = wx.SpinCtrl(self, min=0, style=wx.SP_ARROW_KEYS)
self.Bind(wx.EVT_TEXT, self.OnPriorityChanged, self.Priority)
self.LeftGridSizer.AddWindow(self.Priority, flag=wx.GROW)
-
+
# Add preview panel and associated label to sizers
self.RightGridSizer.AddWindow(self.PreviewLabel, flag=wx.GROW)
self.RightGridSizer.AddWindow(self.Preview, flag=wx.GROW)
-
+
# Add buttons sizer to sizers
- self.MainSizer.AddSizer(self.ButtonSizer, border=20,
+ self.MainSizer.AddSizer(self.ButtonSizer, border=20,
flag=wx.ALIGN_RIGHT|wx.BOTTOM|wx.LEFT|wx.RIGHT)
self.Fit()
-
+
# Reference radio button is default control having keyboard focus
self.TypeRadioButtons["reference"][0].SetFocus()
-
+
def GetTransitionType(self):
"""
Return type selected for SFC transition and associated value
@@ -124,7 +124,7 @@
else:
return type, None
return None, None
-
+
def SetValues(self, values):
"""
Set default SFC transition parameters
@@ -132,14 +132,14 @@
"""
# Extract transition value according to type
type_value = values.get("value", None)
-
+
# For each parameters defined, set corresponding control value
for name, value in values.items():
-
+
# Parameter is SFC transition priority
if name == "priority":
self.Priority.SetValue(values["priority"])
-
+
# Parameter is SFC transition type
elif name == "type":
for type, (radio, control) in self.TypeRadioButtons.iteritems():
@@ -152,10 +152,10 @@
control.SetStringSelection(type_value)
elif isinstance(control, wx.TextCtrl):
control.ChangeValue(type_value)
-
+
# Refresh preview panel
self.RefreshPreview()
-
+
def GetValues(self):
"""
Return SFC transition parameters defined in dialog
@@ -165,7 +165,7 @@
values["type"], values["value"] = self.GetTransitionType()
values["width"], values["height"] = self.Element.GetSize()
return values
-
+
def OnOK(self, event):
"""
Called when dialog OK button is pressed
@@ -173,18 +173,18 @@
@param event: wx.Event from OK button
"""
message = None
-
+
# Get transition type and value associated
type, value = self.GetTransitionType()
-
+
# Test that value associated to type is defined
if type != "connection" and value == "":
message = _("Form isn't complete. %s must be filled!") % type
-
+
# Show error message if an error is detected
if message is not None:
self.ShowErrorMessage(message)
-
+
else:
# Call BlockPreviewDialog function
BlockPreviewDialog.OnOK(self, event)
@@ -198,7 +198,7 @@
for type, (radio, control) in self.TypeRadioButtons.iteritems():
if control is not None:
control.Enable(radio.GetValue())
-
+
# Refresh preview panel
self.RefreshPreview()
event.Skip()
@@ -236,6 +236,6 @@
self.Element = SFC_Transition(self.Preview)
self.Element.SetType(*self.GetTransitionType())
self.Element.SetPriority(self.Priority.GetValue())
-
+
# Call BlockPreviewDialog function
BlockPreviewDialog.RefreshPreview(self)
--- a/dialogs/SearchInProjectDialog.py Fri Aug 11 15:18:19 2017 +0300
+++ b/dialogs/SearchInProjectDialog.py Mon Aug 14 19:13:01 2017 +0300
@@ -33,62 +33,62 @@
def GetElementsChoices():
_ = lambda x: x
- return [("datatype", _("Data Type")),
- ("function", _("Function")),
- ("functionBlock", _("Function Block")),
- ("program", _("Program")),
+ return [("datatype", _("Data Type")),
+ ("function", _("Function")),
+ ("functionBlock", _("Function Block")),
+ ("program", _("Program")),
("configuration", _("Configuration"))]
class SearchInProjectDialog(wx.Dialog):
-
+
def __init__(self, parent):
wx.Dialog.__init__(self, parent, title=_('Search in Project'))
-
+
main_sizer = wx.FlexGridSizer(cols=1, hgap=0, rows=3, vgap=10)
main_sizer.AddGrowableCol(0)
main_sizer.AddGrowableRow(1)
-
+
pattern_sizer = wx.FlexGridSizer(cols=2, hgap=5, rows=2, vgap=5)
pattern_sizer.AddGrowableCol(0)
- main_sizer.AddSizer(pattern_sizer, border=20,
+ main_sizer.AddSizer(pattern_sizer, border=20,
flag=wx.GROW|wx.TOP|wx.LEFT|wx.RIGHT)
-
+
pattern_label = wx.StaticText(self, label=_('Pattern to search:'))
pattern_sizer.AddWindow(pattern_label, flag=wx.ALIGN_BOTTOM)
-
+
self.CaseSensitive = wx.CheckBox(self, label=_('Case sensitive'))
pattern_sizer.AddWindow(self.CaseSensitive, flag=wx.GROW)
-
+
self.Pattern = wx.TextCtrl(self, size=wx.Size(250,-1))
self.Bind(wx.EVT_TEXT, self.FindPatternChanged, self.Pattern)
pattern_sizer.AddWindow(self.Pattern, flag=wx.GROW)
self.Bind(wx.EVT_CHAR_HOOK, self.OnEscapeKey)
self.RegularExpression = wx.CheckBox(self, label=_('Regular expression'))
pattern_sizer.AddWindow(self.RegularExpression, flag=wx.GROW)
-
+
scope_staticbox = wx.StaticBox(self, label=_('Scope'))
scope_sizer = wx.StaticBoxSizer(scope_staticbox, wx.HORIZONTAL)
- main_sizer.AddSizer(scope_sizer, border=20,
+ main_sizer.AddSizer(scope_sizer, border=20,
flag=wx.GROW|wx.LEFT|wx.RIGHT)
-
+
scope_selection_sizer = wx.BoxSizer(wx.VERTICAL)
- scope_sizer.AddSizer(scope_selection_sizer, 1, border=5,
+ scope_sizer.AddSizer(scope_selection_sizer, 1, border=5,
flag=wx.GROW|wx.TOP|wx.LEFT|wx.BOTTOM)
-
+
self.WholeProject = wx.RadioButton(self, label=_('Whole Project'), style=wx.RB_GROUP)
self.WholeProject.SetValue(True)
self.Bind(wx.EVT_RADIOBUTTON, self.OnScopeChanged, self.WholeProject)
- scope_selection_sizer.AddWindow(self.WholeProject, border=5,
+ scope_selection_sizer.AddWindow(self.WholeProject, border=5,
flag=wx.GROW|wx.BOTTOM)
-
+
self.OnlyElements = wx.RadioButton(self, label=_('Only Elements'))
self.Bind(wx.EVT_RADIOBUTTON, self.OnScopeChanged, self.OnlyElements)
self.OnlyElements.SetValue(False)
scope_selection_sizer.AddWindow(self.OnlyElements, flag=wx.GROW)
-
+
self.ElementsList = wx.CheckListBox(self)
self.ElementsList.Enable(False)
- scope_sizer.AddWindow(self.ElementsList, 1, border=5,
+ scope_sizer.AddWindow(self.ElementsList, 1, border=5,
flag=wx.GROW|wx.TOP|wx.RIGHT|wx.BOTTOM)
buttons_sizer = wx.BoxSizer(wx.HORIZONTAL)
@@ -103,9 +103,9 @@
self.CloseButton = wx.Button(self, label=_("Close"))
self.Bind(wx.EVT_BUTTON, self.OnCloseButton, self.CloseButton)
buttons_sizer.AddWindow(self.CloseButton)
-
+
self.SetSizer(main_sizer)
-
+
for name, label in GetElementsChoices():
self.ElementsList.Append(_(label))
@@ -139,7 +139,7 @@
self.OnCloseButton(event)
else:
event.Skip()
-
+
def OnFindButton(self, event):
message = None
infos = {
@@ -163,7 +163,7 @@
except:
self.criteria.clear()
message = _("Syntax error in regular expression of pattern to search!")
-
+
if message is not None:
dialog = wx.MessageDialog(self, message, _("Error"), wx.OK|wx.ICON_ERROR)
dialog.ShowModal()
--- a/editors/DebugViewer.py Fri Aug 11 15:18:19 2017 +0300
+++ b/editors/DebugViewer.py Mon Aug 14 19:13:01 2017 +0300
@@ -35,12 +35,12 @@
#-------------------------------------------------------------------------------
"""
-Class that implements common behavior of every viewers able to display debug
+Class that implements common behavior of every viewers able to display debug
values
"""
class DebugViewer:
-
+
def __init__(self, producer, debug, subscribe_tick=True):
"""
Constructor
@@ -52,49 +52,49 @@
"""
self.Debug = debug
self.SubscribeTick = subscribe_tick
-
+
# Flag indicating that consumer value update inhibited
# (DebugViewer is refreshing)
self.Inhibited = False
-
+
# List of data consumers subscribed to DataProducer
self.DataConsumers = {}
-
+
# Time stamp indicating when last refresh have been initiated
self.LastRefreshTime = gettime()
# Flag indicating that DebugViewer has acquire common debug lock
self.HasAcquiredLock = False
# Lock for access to the two preceding variable
self.AccessLock = Lock()
-
+
# Timer to refresh Debug Viewer one last time in the case that a new
# value have been received during refresh was inhibited and no one
# after refresh was activated
self.LastRefreshTimer = None
# Lock for access to the timer
self.TimerAccessLock = Lock()
-
+
# Set DataProducer and subscribe tick if needed
self.SetDataProducer(producer)
-
+
def __del__(self):
"""
Destructor
"""
# Unsubscribe all data consumers
self.UnsubscribeAllDataConsumers()
-
+
# Delete reference to DataProducer
self.DataProducer = None
-
+
# Stop last refresh timer
if self.LastRefreshTimer is not None:
self.LastRefreshTimer.cancel()
-
+
# Release Common debug lock if DebugViewer has acquired it
if self.HasAcquiredLock:
DEBUG_REFRESH_LOCK.release()
-
+
def SetDataProducer(self, producer):
"""
Set Data Producer
@@ -103,25 +103,25 @@
# In the case that tick need to be subscribed and DebugViewer is
# debugging
if self.SubscribeTick and self.Debug:
-
+
# Subscribe tick to new data producer
if producer is not None:
producer.SubscribeDebugIECVariable("__tick__", self, True)
-
+
# Unsubscribe tick from old data producer
if getattr(self, "DataProducer", None) is not None:
self.DataProducer.UnsubscribeDebugIECVariable("__tick__", self)
-
+
# Save new data producer
self.DataProducer = producer
-
+
def IsDebugging(self):
"""
Get flag indicating if Debug Viewer is debugging
@return: Debugging flag
"""
return self.Debug
-
+
def Inhibit(self, inhibit):
"""
Set consumer value update inhibit flag
@@ -130,10 +130,10 @@
# Inhibit every data consumers in list
for consumer, iec_path in self.DataConsumers.iteritems():
consumer.Inhibit(inhibit)
-
+
# Save inhibit flag
self.Inhibited = inhibit
-
+
def AddDataConsumer(self, iec_path, consumer, buffer_list=False):
"""
Subscribe data consumer to DataProducer
@@ -145,19 +145,19 @@
# Return immediately if no DataProducer defined
if self.DataProducer is None:
return None
-
+
# Subscribe data consumer to DataProducer
result = self.DataProducer.SubscribeDebugIECVariable(
iec_path, consumer, buffer_list)
if result is not None and consumer != self:
-
+
# Store data consumer if successfully subscribed and inform
# consumer of variable data type
self.DataConsumers[consumer] = iec_path
consumer.SetDataType(self.GetDataType(iec_path))
-
+
return result
-
+
def RemoveDataConsumer(self, consumer):
"""
Unsubscribe data consumer from DataProducer
@@ -165,12 +165,12 @@
"""
# Remove consumer from data consumer list
iec_path = self.DataConsumers.pop(consumer, None)
-
+
# Unsubscribe consumer from DataProducer
if iec_path is not None:
self.DataProducer.UnsubscribeDebugIECVariable(
iec_path, consumer)
-
+
def SubscribeAllDataConsumers(self):
"""
Called to Subscribe all data consumers contained in DebugViewer.
@@ -179,24 +179,24 @@
# Subscribe tick if needed
if self.SubscribeTick and self.Debug and self.DataProducer is not None:
self.DataProducer.SubscribeDebugIECVariable("__tick__", self, True)
-
+
def UnsubscribeAllDataConsumers(self, tick=True):
"""
Called to Unsubscribe all data consumers.
"""
if self.DataProducer is not None:
-
+
# Unscribe tick if needed
if self.SubscribeTick and tick and self.Debug:
self.DataProducer.UnsubscribeDebugIECVariable("__tick__", self)
-
+
# Unsubscribe all data consumers in list
for consumer, iec_path in self.DataConsumers.iteritems():
self.DataProducer.UnsubscribeDebugIECVariable(
iec_path, consumer)
-
+
self.DataConsumers = {}
-
+
def GetDataType(self, iec_path):
"""
Return variable data type.
@@ -204,20 +204,20 @@
@return: variable data type (None if not found)
"""
if self.DataProducer is not None:
-
+
# Search for variable informations in project compilation files
data_type = self.DataProducer.GetDebugIECVariableType(
iec_path.upper())
if data_type is not None:
return data_type
-
+
# Search for variable informations in project data
infos = self.DataProducer.GetInstanceInfos(iec_path)
if infos is not None:
return infos.type
-
+
return None
-
+
def IsNumType(self, data_type):
"""
Indicate if data type given is a numeric data type
@@ -226,9 +226,9 @@
"""
if self.DataProducer is not None:
return self.DataProducer.IsNumType(data_type)
-
+
return False
-
+
def ForceDataValue(self, iec_path, value):
"""
Force PLC variable value
@@ -237,7 +237,7 @@
"""
if self.DataProducer is not None:
self.DataProducer.ForceDebugIECVariable(iec_path, value)
-
+
def ReleaseDataValue(self, iec_path):
"""
Release PLC variable value
@@ -245,12 +245,12 @@
"""
if self.DataProducer is not None:
self.DataProducer.ReleaseDebugIECVariable(iec_path)
-
+
def NewDataAvailable(self, ticks):
"""
Called by DataProducer for each tick captured
@param tick: PLC tick captured
- All other parameters are passed to refresh function
+ All other parameters are passed to refresh function
"""
# Stop last refresh timer
self.TimerAccessLock.acquire()
@@ -258,27 +258,27 @@
self.LastRefreshTimer.cancel()
self.LastRefreshTimer=None
self.TimerAccessLock.release()
-
+
# Only try to refresh DebugViewer if it is visible on screen and not
# already refreshing
if self.IsShown() and not self.Inhibited:
-
+
# Try to get acquire common refresh lock if minimum period between
# two refresh has expired
if gettime() - self.LastRefreshTime > REFRESH_PERIOD and \
DEBUG_REFRESH_LOCK.acquire(False):
self.StartRefreshing()
-
+
# If common lock wasn't acquired for any reason, restart last
# refresh timer
else:
self.StartLastRefreshTimer()
-
+
# In the case that DebugViewer isn't visible on screen and has already
# acquired common refresh lock, reset DebugViewer
elif not self.IsShown() and self.HasAcquiredLock:
DebugViewer.RefreshNewData(self)
-
+
def ShouldRefresh(self):
"""
Callback function called when last refresh timer expired
@@ -286,15 +286,15 @@
"""
# Cancel if DebugViewer is not visible on screen
if self and self.IsShown():
-
+
# Try to acquire common refresh lock
if DEBUG_REFRESH_LOCK.acquire(False):
self.StartRefreshing()
-
+
# Restart last refresh timer if common refresh lock acquired failed
else:
self.StartLastRefreshTimer()
-
+
def StartRefreshing(self):
"""
Called to initiate a refresh of DebugViewer
@@ -306,13 +306,13 @@
self.HasAcquiredLock = True
self.LastRefreshTime = gettime()
self.AccessLock.release()
-
+
# Inhibit data consumer value update
self.Inhibit(True)
-
+
# Initiate DebugViewer refresh
wx.CallAfter(self.RefreshNewData)
-
+
def StartLastRefreshTimer(self):
"""
Called to start last refresh timer for the minimum time between 2
@@ -324,19 +324,19 @@
REFRESH_PERIOD, self.ShouldRefresh)
self.LastRefreshTimer.start()
self.TimerAccessLock.release()
-
+
def RefreshNewData(self):
"""
Called to refresh DebugViewer according to values received by data
consumers
May be overridden by inherited classes
Can receive any parameters depending on what is needed by inherited
- class
+ class
"""
if self:
# Activate data consumer value update
self.Inhibit(False)
-
+
# Release common refresh lock if acquired and update
# last refresh time
self.AccessLock.acquire()
--- a/editors/FileManagementPanel.py Fri Aug 11 15:18:19 2017 +0300
+++ b/editors/FileManagementPanel.py Mon Aug 14 19:13:01 2017 +0300
@@ -35,37 +35,37 @@
FILTER = _("All files (*.*)|*.*|CSV files (*.csv)|*.csv")
class FileManagementPanel(EditorPanel):
-
+
def _init_Editor(self, parent):
self.Editor = wx.Panel(parent)
-
+
main_sizer = wx.BoxSizer(wx.HORIZONTAL)
-
+
left_sizer = wx.BoxSizer(wx.VERTICAL)
main_sizer.AddSizer(left_sizer, 1, border=5, flag=wx.GROW|wx.ALL)
-
+
managed_dir_label = wx.StaticText(self.Editor, label=_(self.TagName) + ":")
left_sizer.AddWindow(managed_dir_label, border=5, flag=wx.GROW|wx.BOTTOM)
-
+
self.ManagedDir = FolderTree(self.Editor, self.Folder, FILTER)
left_sizer.AddWindow(self.ManagedDir, 1, flag=wx.GROW)
-
+
managed_treectrl = self.ManagedDir.GetTreeCtrl()
self.Bind(wx.EVT_TREE_SEL_CHANGED, self.OnTreeItemChanged, managed_treectrl)
if self.EnableDragNDrop:
self.Bind(wx.EVT_TREE_BEGIN_DRAG, self.OnTreeBeginDrag, managed_treectrl)
-
+
button_sizer = wx.BoxSizer(wx.VERTICAL)
- main_sizer.AddSizer(button_sizer, border=5,
+ main_sizer.AddSizer(button_sizer, border=5,
flag=wx.ALL|wx.ALIGN_CENTER_VERTICAL)
-
+
for idx, (name, bitmap, help) in enumerate([
("DeleteButton", "remove_element", _("Remove file from left folder")),
("LeftCopyButton", "LeftCopy", _("Copy file from right folder to left")),
("RightCopyButton", "RightCopy", _("Copy file from left folder to right")),
("EditButton", "edit", _("Edit file"))]):
- button = wx.lib.buttons.GenBitmapButton(self.Editor,
- bitmap=GetBitmap(bitmap),
+ button = wx.lib.buttons.GenBitmapButton(self.Editor,
+ bitmap=GetBitmap(bitmap),
size=wx.Size(28, 28), style=wx.NO_BORDER)
button.SetToolTipString(help)
setattr(self, name, button)
@@ -75,62 +75,62 @@
flag = 0
self.Bind(wx.EVT_BUTTON, getattr(self, "On" + name), button)
button_sizer.AddWindow(button, border=20, flag=flag)
-
+
right_sizer = wx.BoxSizer(wx.VERTICAL)
main_sizer.AddSizer(right_sizer, 1, border=5, flag=wx.GROW|wx.ALL)
-
+
if wx.Platform == '__WXMSW__':
system_dir_label = wx.StaticText(self.Editor, label=_("My Computer:"))
else:
system_dir_label = wx.StaticText(self.Editor, label=_("Home Directory:"))
right_sizer.AddWindow(system_dir_label, border=5, flag=wx.GROW|wx.BOTTOM)
-
+
self.SystemDir = FolderTree(self.Editor, self.HomeDirectory, FILTER, False)
right_sizer.AddWindow(self.SystemDir, 1, flag=wx.GROW)
-
+
system_treectrl = self.SystemDir.GetTreeCtrl()
self.Bind(wx.EVT_TREE_SEL_CHANGED, self.OnTreeItemChanged, system_treectrl)
-
+
self.Editor.SetSizer(main_sizer)
-
+
def __init__(self, parent, controler, name, folder, enable_dragndrop=False):
self.Folder = os.path.realpath(folder)
self.EnableDragNDrop = enable_dragndrop
-
+
if wx.Platform == '__WXMSW__':
self.HomeDirectory = "/"
else:
self.HomeDirectory = os.path.expanduser("~")
-
+
EditorPanel.__init__(self, parent, name, None, None)
-
+
self.Controler = controler
-
+
self.EditableFileExtensions = []
self.EditButton.Hide()
-
+
self.SetIcon(GetBitmap("FOLDER"))
-
+
def __del__(self):
self.Controler.OnCloseEditor(self)
-
+
def GetTitle(self):
return _(self.TagName)
-
+
def SetEditableFileExtensions(self, extensions):
self.EditableFileExtensions = extensions
if len(self.EditableFileExtensions) > 0:
self.EditButton.Show()
-
+
def RefreshView(self):
self.ManagedDir.RefreshTree()
self.SystemDir.RefreshTree()
self.RefreshButtonsState()
-
+
def RefreshButtonsState(self):
managed_filepath = self.ManagedDir.GetPath()
system_filepath = self.SystemDir.GetPath()
-
+
self.DeleteButton.Enable(os.path.isfile(managed_filepath))
self.LeftCopyButton.Enable(os.path.isfile(system_filepath))
self.RightCopyButton.Enable(os.path.isfile(managed_filepath))
@@ -138,22 +138,22 @@
self.EditButton.Enable(
os.path.isfile(managed_filepath) and
os.path.splitext(managed_filepath)[1] in self.EditableFileExtensions)
-
+
def OnTreeItemChanged(self, event):
self.RefreshButtonsState()
event.Skip()
-
+
def OnDeleteButton(self, event):
filepath = self.ManagedDir.GetPath()
if os.path.isfile(filepath):
folder, filename = os.path.split(filepath)
-
- dialog = wx.MessageDialog(self,
- _("Do you really want to delete the file '%s'?") % filename,
+
+ dialog = wx.MessageDialog(self,
+ _("Do you really want to delete the file '%s'?") % filename,
_("Delete File"), wx.YES_NO|wx.ICON_QUESTION)
remove = dialog.ShowModal() == wx.ID_YES
dialog.Destroy()
-
+
if remove:
os.remove(filepath)
self.ManagedDir.RefreshTree()
@@ -161,11 +161,11 @@
def OnEditButton(self, event):
filepath = self.ManagedDir.GetPath()
- if (os.path.isfile(filepath) and
+ if (os.path.isfile(filepath) and
os.path.splitext(filepath)[1] in self.EditableFileExtensions):
self.Controler._OpenView(filepath + "::")
event.Skip()
-
+
def CopyFile(self, src, dst):
if os.path.isfile(src):
src_folder, src_filename = os.path.split(src)
@@ -173,17 +173,17 @@
dst_folder, dst_filename = os.path.split(dst)
else:
dst_folder = dst
-
+
dst_filepath = os.path.join(dst_folder, src_filename)
if os.path.isfile(dst_filepath):
- dialog = wx.MessageDialog(self,
- _("The file '%s' already exist.\nDo you want to replace it?") % src_filename,
+ dialog = wx.MessageDialog(self,
+ _("The file '%s' already exist.\nDo you want to replace it?") % src_filename,
_("Replace File"), wx.YES_NO|wx.ICON_QUESTION)
copy = dialog.ShowModal() == wx.ID_YES
dialog.Destroy()
else:
copy = True
-
+
if copy:
shutil.copyfile(src, dst_filepath)
return dst_filepath
@@ -202,7 +202,7 @@
self.SystemDir.RefreshTree()
self.SystemDir.SetPath(filepath)
event.Skip()
-
+
def OnTreeBeginDrag(self, event):
filepath = self.ManagedDir.GetPath()
if os.path.isfile(filepath):
@@ -211,4 +211,3 @@
dragSource = wx.DropSource(self)
dragSource.SetData(data)
dragSource.DoDragDrop()
-
--- a/editors/LDViewer.py Fri Aug 11 15:18:19 2017 +0300
+++ b/editors/LDViewer.py Mon Aug 14 19:13:01 2017 +0300
@@ -49,7 +49,7 @@
block_list.append(next)
next_list.append(next)
current_list = next_list
-
+
def CalcBranchSize(elements, stops):
branch_size = 0
stop_list = stops
@@ -194,7 +194,7 @@
self.RungComments.insert(i, None)
else:
self.RungComments.insert(i, None)
-
+
def loadInstance(self, instance, ids, selection):
Viewer.loadInstance(self, instance, ids, selection)
if self.GetDrawingMode() != FREEDRAWING_MODE:
@@ -230,7 +230,7 @@
if len(rungs) > 1:
raise ValueError, _("Ladder element with id %d is on more than one rung.")%instance["id"]
element = self.FindElementById(instance["id"])
- element_connectors = element.GetConnectors()
+ element_connectors = element.GetConnectors()
self.Rungs[rungs[0]].SelectElement(element)
for wire, num in element_connectors["inputs"][0].GetWires():
self.Rungs[rungs[0]].SelectElement(wire)
@@ -240,7 +240,7 @@
pos = element.GetPosition()
i = 0
inserted = False
- while i < len(self.RungComments) and not inserted:
+ while i < len(self.RungComments) and not inserted:
ipos = self.RungComments[i].GetPosition()
if pos[1] < ipos[1]:
self.RungComments.insert(i, element)
@@ -248,7 +248,7 @@
i += 1
if not inserted:
self.RungComments.append(element)
-
+
#-------------------------------------------------------------------------------
# Search Element functions
#-------------------------------------------------------------------------------
@@ -262,7 +262,7 @@
def FindElement(self, event, exclude_group = False, connectors = True):
if self.GetDrawingMode() == FREEDRAWING_MODE:
return Viewer.FindElement(self, event, exclude_group, connectors)
-
+
dc = self.GetLogicalDC()
pos = event.GetLogicalPosition(dc)
if self.SelectedElement and not isinstance(self.SelectedElement, (Graphic_Group, Wire)):
@@ -286,7 +286,7 @@
def SearchElements(self, bbox):
if self.GetDrawingMode() == FREEDRAWING_MODE:
return Viewer.SearchElements(self, bbox)
-
+
elements = []
for element in self.Blocks.values() + self.Comments.values():
if element.IsInSelection(bbox):
@@ -345,7 +345,7 @@
self.SelectedElement.SetElements(elements)
self.SelectedElement.SetSelected(True)
elif self.Mode == MODE_SELECTION and self.SelectedElement:
- dc = self.GetLogicalDC()
+ dc = self.GetLogicalDC()
if not isinstance(self.SelectedElement, Graphic_Group):
if self.IsWire(self.SelectedElement):
result = self.SelectedElement.TestSegment(event.GetLogicalPosition(dc), True)
@@ -500,7 +500,7 @@
starty = bbox.y + bbox.height
starty += LD_OFFSET[1]
rung = Graphic_Group(self)
-
+
# Create comment
id = self.GetNewId()
comment = Comment(self, _("Comment"), id)
@@ -511,7 +511,7 @@
self.Controler.AddEditedElementComment(self.TagName, id)
self.RefreshCommentModel(comment)
starty += LD_COMMENT_DEFAULTSIZE[1] + LD_OFFSET[1]
-
+
# Create LeftPowerRail
id = self.GetNewId()
leftpowerrail = LD_PowerRail(self, LEFTRAIL, id)
@@ -521,7 +521,7 @@
rung.SelectElement(leftpowerrail)
self.Controler.AddEditedElementPowerRail(self.TagName, id, LEFTRAIL)
self.RefreshPowerRailModel(leftpowerrail)
-
+
# Create Coil
id = self.GetNewId()
coil = LD_Coil(self, values["type"], values["name"], id)
@@ -530,7 +530,7 @@
self.AddBlock(coil)
rung.SelectElement(coil)
self.Controler.AddEditedElementCoil(self.TagName, id)
-
+
# Create Wire between LeftPowerRail and Coil
wire = Wire(self)
start_connector = coil_connectors["inputs"][0]
@@ -541,7 +541,7 @@
wire.ConnectEndPoint(None, end_connector)
self.AddWire(wire)
rung.SelectElement(wire)
-
+
# Create RightPowerRail
id = self.GetNewId()
rightpowerrail = LD_PowerRail(self, RIGHTRAIL, id)
@@ -550,7 +550,7 @@
self.AddBlock(rightpowerrail)
rung.SelectElement(rightpowerrail)
self.Controler.AddEditedElementPowerRail(self.TagName, id, RIGHTRAIL)
-
+
# Create Wire between LeftPowerRail and Coil
wire = Wire(self)
start_connector = rightpowerrail_connectors["inputs"][0]
@@ -778,7 +778,7 @@
if left_powerrail:
powerrail = left_elements[0].GetParentBlock()
index = 0
- for left_element in left_elements:
+ for left_element in left_elements:
index = max(index, powerrail.GetConnectorIndex(left_element))
powerrail.InsertConnector(index + 1)
powerrail.RefreshModel()
@@ -810,12 +810,12 @@
values = dialog.GetValues()
powerrail = right_elements[0].GetParentBlock()
index = 0
- for right_element in right_elements:
+ for right_element in right_elements:
index = max(index, powerrail.GetConnectorIndex(right_element))
powerrail.InsertConnector(index + 1)
powerrail.RefreshModel()
connectors = powerrail.GetConnectors()
-
+
# Create Coil
id = self.GetNewId()
coil = LD_Coil(self, values["type"], values["name"], id)
@@ -825,7 +825,7 @@
rung.SelectElement(coil)
self.Controler.AddEditedElementCoil(self.TagName, id)
coil_connectors = coil.GetConnectors()
-
+
# Create Wire between LeftPowerRail and Coil
wire = Wire(self)
connectors["inputs"][index + 1].Connect((wire, 0), False)
@@ -835,7 +835,7 @@
self.AddWire(wire)
rung.SelectElement(wire)
left_elements.reverse()
-
+
for i, left_element in enumerate(left_elements):
# Create Wire between LeftPowerRail and Coil
new_wire = Wire(self)
@@ -844,7 +844,7 @@
left_element.InsertConnect(left_index[i] + 1, (new_wire, -1), False)
new_wire.ConnectStartPoint(None, coil_connectors["inputs"][0])
new_wire.ConnectEndPoint(None, left_element)
-
+
self.RefreshPosition(coil)
else:
left_elements.reverse()
@@ -1089,7 +1089,7 @@
if isinstance(element, LD_PowerRail) and element.GetType() == LEFTRAIL:
element.RefreshModel()
return
-
+
# Extract max position of the elements connected to input
connectors = element.GetConnectors()
position = element.GetPosition()
@@ -1103,7 +1103,7 @@
pos = leftblock.GetPosition()
size = leftblock.GetSize()
maxx = max(maxx, pos[0] + size[0])
-
+
# Refresh position of element
if isinstance(element, LD_Coil):
interval = LD_WIRECOIL_SIZE
@@ -1114,13 +1114,13 @@
movex = maxx + interval - position[0]
element.Move(movex, 0)
position = element.GetPosition()
-
+
# Extract blocks connected to inputs
blocks = []
for i, connector in enumerate(connectors["inputs"]):
for j, (wire, handle) in enumerate(connector.GetWires()):
blocks.append(wire.EndConnected.GetParentBlock())
-
+
for i, connector in enumerate(connectors["inputs"]):
startpoint = connector.GetPosition(False)
previous_blocks = []
@@ -1168,13 +1168,13 @@
previous_blocks.append(block)
blocks.remove(block)
ExtractNextBlocks(block, block_list)
-
+
element.RefreshModel(False)
if recursive:
for connector in connectors["outputs"]:
for wire, handle in connector.GetWires():
self.RefreshPosition(wire.StartConnected.GetParentBlock())
-
+
def RefreshRungs(self, movey, fromidx):
if movey != 0:
for i in xrange(fromidx, len(self.Rungs)):
@@ -1192,4 +1192,3 @@
def EditPowerRailContent(self, powerrail):
if self.GetDrawingMode() == FREEDRAWING_MODE:
Viewer.EditPowerRailContent(self, powerrail)
-
--- a/editors/SFCViewer.py Fri Aug 11 15:18:19 2017 +0300
+++ b/editors/SFCViewer.py Mon Aug 14 19:13:01 2017 +0300
@@ -35,7 +35,7 @@
class SFC_Viewer(Viewer):
-
+
SFC_StandardRules = {
# The key of this dict is a block that user try to connect,
# and the value is a list of blocks, that can be connected with the current block
@@ -85,7 +85,7 @@
def __init__(self, parent, tagname, window, controler, debug = False, instancepath = ""):
Viewer.__init__(self, parent, tagname, window, controler, debug, instancepath)
self.CurrentLanguage = "SFC"
-
+
def ConnectConnectors(self, start, end):
startpoint = [start.GetPosition(False), start.GetDirection()]
endpoint = [end.GetPosition(False), end.GetDirection()]
@@ -96,7 +96,7 @@
wire.ConnectStartPoint(None, start)
wire.ConnectEndPoint(None, end)
return wire
-
+
def CreateTransition(self, connector, next = None):
previous = connector.GetParentBlock()
id = self.GetNewId()
@@ -124,7 +124,7 @@
next_block.RefreshPosition()
transition.RefreshOutputModel(True)
return transition
-
+
def RemoveTransition(self, transition):
connectors = transition.GetConnectors()
input_wires = connectors["input"].GetWires()
@@ -146,7 +146,7 @@
self.Controler.RemoveEditedElementInstance(self.TagName, transition.GetId())
wire = self.ConnectConnectors(next, previous)
return wire
-
+
def CreateStep(self, name, connector, next = None):
previous = connector.GetParentBlock()
id = self.GetNewId()
@@ -289,7 +289,7 @@
self.SelectedElement.RefreshModel()
self.SelectedElement.SetSelected(True)
event.Skip()
-
+
def OnViewerRightUp(self, event):
if self.GetDrawingMode() == FREEDRAWING_MODE:
Viewer.OnViewerRightUp(self, event)
@@ -307,7 +307,7 @@
self.SelectedElement.Refresh()
wx.CallAfter(self.SetCurrentCursor, 0)
event.Skip()
-
+
def OnViewerLeftDClick(self, event):
if self.GetDrawingMode() == FREEDRAWING_MODE:
Viewer.OnViewerLeftDClick(self, event)
@@ -315,7 +315,7 @@
self.SelectedElement.OnLeftDClick(event, self.GetLogicalDC(), self.Scaling)
self.Refresh(False)
event.Skip()
-
+
def OnViewerMotion(self, event):
if self.GetDrawingMode() == FREEDRAWING_MODE:
Viewer.OnViewerMotion(self, event)
@@ -424,7 +424,7 @@
self.RefreshRect(self.GetScrolledRect(self.SelectedElement.GetRedrawRect(0, scaling[1])), False)
else:
event.Skip()
-
+
#-------------------------------------------------------------------------------
# Adding element functions
#-------------------------------------------------------------------------------
@@ -503,7 +503,7 @@
self.RefreshScrollBars()
self.Refresh(False)
dialog.Destroy()
-
+
def AddStepAction(self):
if isinstance(self.SelectedElement, SFC_Step):
connectors = self.SelectedElement.GetConnectors()
@@ -532,9 +532,9 @@
self.RefreshScrollBars()
self.Refresh(False)
dialog.Destroy()
-
+
def AddDivergence(self):
- if self.SelectedElement in self.Wires or isinstance(self.SelectedElement, Graphic_Group) or isinstance(self.SelectedElement, SFC_Step):
+ if self.SelectedElement in self.Wires or isinstance(self.SelectedElement, Graphic_Group) or isinstance(self.SelectedElement, SFC_Step):
dialog = SFCDivergenceDialog(self.ParentWindow)
dialog.SetPreviewFont(self.GetFont())
if dialog.ShowModal() == wx.ID_OK:
@@ -729,7 +729,7 @@
self.RefreshScrollBars()
self.Refresh(False)
dialog.Destroy()
-
+
def AddDivergenceBranch(self, divergence):
if isinstance(divergence, SFC_Divergence):
if self.GetDrawingMode() == FREEDRAWING_MODE:
@@ -750,7 +750,7 @@
self.RefreshBuffer()
self.RefreshScrollBars()
self.Refresh(False)
-
+
def RemoveDivergenceBranch(self, divergence):
if isinstance(divergence, SFC_Divergence):
if self.GetDrawingMode() == FREEDRAWING_MODE:
@@ -759,15 +759,15 @@
self.RefreshBuffer()
self.RefreshScrollBars()
self.Refresh(False)
-
+
def AddJump(self):
if isinstance(self.SelectedElement, SFC_Step) and not self.SelectedElement.Output:
choices = []
for block in self.Blocks:
if isinstance(block, SFC_Step):
choices.append(block.GetName())
- dialog = wx.SingleChoiceDialog(self.ParentWindow,
- _("Add a new jump"), _("Please choose a target"),
+ dialog = wx.SingleChoiceDialog(self.ParentWindow,
+ _("Add a new jump"), _("Please choose a target"),
choices, wx.DEFAULT_DIALOG_STYLE|wx.OK|wx.CANCEL)
if dialog.ShowModal() == wx.ID_OK:
value = dialog.GetStringSelection()
@@ -884,7 +884,7 @@
self.DeleteDivergence(previous_block)
else:
self.RefreshDivergenceModel(previous_block)
-
+
def DeleteTransition(self, transition):
if self.GetDrawingMode() == FREEDRAWING_MODE:
Viewer.DeleteTransition(self, transition)
@@ -919,7 +919,7 @@
self.DeleteDivergence(next_block)
else:
self.RefreshDivergenceModel(next_block)
-
+
def DeleteDivergence(self, divergence):
if self.GetDrawingMode() == FREEDRAWING_MODE:
Viewer.DeleteDivergence(self, divergence)
@@ -979,7 +979,7 @@
next_pos = next.GetPosition(False)
wire_size = GetWireSize(previous_block)
previous_block.RefreshOutputPosition((0, previous_pos.y + wire_size - next_pos.y))
- wire.SetPoints([wx.Point(previous_pos.x, previous_pos.y + wire_size),
+ wire.SetPoints([wx.Point(previous_pos.x, previous_pos.y + wire_size),
wx.Point(previous_pos.x, previous_pos.y)])
if isinstance(next_block, SFC_Divergence):
next_block.RefreshPosition()
@@ -1009,12 +1009,12 @@
next_pos = next.GetPosition(False)
wire_size = GetWireSize(previous_block)
previous_block.RefreshOutputPosition((previous_pos.x - next_pos.x, previous_pos.y + wire_size - next_pos.y))
- wire.SetPoints([wx.Point(previous_pos.x, previous_pos.y + wire_size),
+ wire.SetPoints([wx.Point(previous_pos.x, previous_pos.y + wire_size),
wx.Point(previous_pos.x, previous_pos.y)])
if isinstance(next_block, SFC_Divergence):
next_block.RefreshPosition()
previous_block.RefreshOutputModel(True)
-
+
def DeleteJump(self, jump):
if self.GetDrawingMode() == FREEDRAWING_MODE:
Viewer.DeleteJump(self, jump)
@@ -1049,7 +1049,7 @@
self.DeleteDivergence(previous_block)
else:
previous_block.RefreshModel()
-
+
def DeleteActionBlock(self, actionblock):
if self.GetDrawingMode() == FREEDRAWING_MODE:
Viewer.DeleteActionBlock(self, actionblock)
@@ -1069,7 +1069,7 @@
self.RefreshStepModel(step)
step.RefreshOutputPosition()
step.RefreshOutputModel(True)
-
+
def DeleteWire(self, wire):
if self.GetDrawingMode() == FREEDRAWING_MODE:
Viewer.DeleteWire(self, wire)
@@ -1087,4 +1087,3 @@
infos["width"], infos["height"] = block.GetSize()
infos["connectors"] = block.GetConnectors()
self.Controler.SetEditedElementBlockInfos(self.TagName, blockid, infos)
-
--- a/editors/TextViewer.py Fri Aug 11 15:18:19 2017 +0300
+++ b/editors/TextViewer.py Mon Aug 14 19:13:01 2017 +0300
@@ -263,7 +263,7 @@
if dialog.ShowModal() == wx.ID_OK:
blockname = dialog.GetValue()
else:
- event.SetDragText("")
+ event.SetDragText("")
return
dialog.Destroy()
if blockname.upper() in [name.upper() for name in self.Controler.GetProjectPouNames(self.Debug)]:
@@ -632,7 +632,7 @@
if len(self.CallStack) > 0:
current_call = self.CallStack.pop()
else:
- current_call = None
+ current_call = None
elif state == PRAGMA:
if line.endswith("}"):
self.SetStyling(current_pos - last_styled_pos, STC_PLC_EMPTY)
@@ -961,4 +961,3 @@
self.SetStyling(highlight_end_pos - highlight_start_pos, highlight_type)
self.StartStyling(highlight_start_pos, 0x00)
self.SetStyling(len(self.Editor.GetText()) - highlight_end_pos, wx.stc.STC_STYLE_DEFAULT)
-
--- a/editors/Viewer.py Fri Aug 11 15:18:19 2017 +0300
+++ b/editors/Viewer.py Mon Aug 14 19:13:01 2017 +0300
@@ -429,7 +429,7 @@
class DebugInstanceName(DebugDataConsumer):
VALUE_TRANSLATION = {True: _("Active"), False: _("Inactive")}
-
+
def __init__(self, parent):
DebugDataConsumer.__init__(self)
self.Parent = parent
@@ -437,7 +437,7 @@
self.ActionState = None
self.x_offset = 2
self.y_offset = 2
-
+
def SetValue(self, value):
self.ActionState = value
if self.ActionState != self.ActionLastState:
@@ -448,7 +448,7 @@
return _("Debug: %s") % self.Parent.InstancePath
def GetRedrawRect(self):
- x, y = self.Parent.CalcUnscrolledPosition(self.x_offset, self.y_offset)
+ x, y = self.Parent.CalcUnscrolledPosition(self.x_offset, self.y_offset)
dc = self.Parent.GetLogicalDC()
ipw, iph = dc.GetTextExtent(self.GetInstanceName())
vw, vh = 0, 0
@@ -462,13 +462,13 @@
scalex, scaley = dc.GetUserScale()
dc.SetUserScale(1, 1)
x, y = self.Parent.CalcUnscrolledPosition(self.x_offset, self.y_offset)
-
+
text = self.GetInstanceName()
if self.ActionState is not None:
text += " ("
dc.DrawText(text, x, y)
- tw, th = dc.GetTextExtent(text)
+ tw, th = dc.GetTextExtent(text)
if self.ActionState is not None:
text = self.VALUE_TRANSLATION[self.ActionState]
@@ -478,8 +478,8 @@
if self.ActionState:
dc.SetTextForeground(wx.BLACK)
tw = tw + dc.GetTextExtent(text)[0]
-
- text = ")"
+
+ text = ")"
dc.DrawText(text, x + tw, y)
dc.SetUserScale(scalex, scaley)
@@ -955,7 +955,7 @@
block.GetName() == name:
blocks.append(block)
return blocks
-
+
def GetConnectorByName(self, name):
for block in self.Blocks.itervalues():
if isinstance(block, FBD_Connector) and\
@@ -1222,7 +1222,7 @@
if self.TagName.split("::")[0] == "A" and self.Debug:
self.AddDataConsumer("%s.Q" % self.InstancePath.upper(), self.InstanceName)
-
+
for wire in self.Wires:
if not wire.IsConnectedCompatible():
wire.SetValid(False)
@@ -1526,7 +1526,7 @@
return result
def FindBlockConnectorWithError(self, pos, direction = None, exclude = None):
- error = False
+ error = False
startblock = None
for block in self.Blocks.itervalues():
connector = block.TestConnector(pos, direction, exclude)
@@ -1539,7 +1539,7 @@
error = True
return connector, error
return None, error
-
+
def FindElementById(self, id):
block = self.Blocks.get(id, None)
if block is not None:
@@ -2585,7 +2585,7 @@
break
self.AddNewElement(block, bbox, wire, connector)
self.RefreshVariablePanel()
- self.ParentWindow.RefreshPouInstanceVariablesPanel()
+ self.ParentWindow.RefreshPouInstanceVariablesPanel()
dialog.Destroy()
def AddNewVariable(self, bbox, exclude_input=False, wire=None):
@@ -2966,7 +2966,7 @@
rect = rect.Union(block.GetRedrawRect())
block.Refresh(rect)
step.SetName(new_name)
-
+
if values["input"]:
step.AddInput()
else:
@@ -3711,5 +3711,3 @@
if self.Debug:
DebugViewer.RefreshNewData(self)
event.Skip()
-
-
--- a/graphics/DebugDataConsumer.py Fri Aug 11 15:18:19 2017 +0300
+++ b/graphics/DebugDataConsumer.py Mon Aug 14 19:13:01 2017 +0300
@@ -46,7 +46,7 @@
return float(value.days * DAY + \
value.seconds * SECOND + \
value.microseconds)
- return
+ return
def generate_time(value):
"""
@@ -56,38 +56,38 @@
@return: IEC 61131 TIME literal
"""
microseconds = get_microseconds(value)
-
+
# Get absolute microseconds value and save if it was negative
negative = microseconds < 0
microseconds = abs(microseconds)
-
+
# TIME literal prefix
data = "T#"
if negative:
data += "-"
-
+
# In TIME literal format, it isn't mandatory to indicate null values
# if no greater non-null values are available. This variable is used to
# inhibit formatting until a non-null value is found
not_null = False
-
+
for val, format in [
(int(microseconds) / DAY, "%dd"), # Days
((int(microseconds) % DAY) / HOUR, "%dh"), # Hours
((int(microseconds) % HOUR) / MINUTE, "%dm"), # Minutes
((int(microseconds) % MINUTE) / SECOND, "%ds")]: # Seconds
-
- # Add value to TIME literal if value is non-null or another non-null
+
+ # Add value to TIME literal if value is non-null or another non-null
# value have already be found
if val > 0 or not_null:
data += format % val
-
+
# Update non-null variable
not_null = True
-
- # In any case microseconds have to be added to TIME literal
+
+ # In any case microseconds have to be added to TIME literal
data += "%gms" % (microseconds % SECOND / 1000.)
-
+
return data
def generate_date(value):
@@ -116,22 +116,22 @@
@return: IEC 61131 TIME_OF_DAY literal
"""
microseconds = get_microseconds(value)
-
+
# TIME_OF_DAY literal prefix
data = "TOD#"
-
+
for val, format in [
(int(microseconds) / HOUR, "%2.2d:"), # Hours
((int(microseconds) % HOUR) / MINUTE, "%2.2d:"), # Minutes
((int(microseconds) % MINUTE) / SECOND, "%2.2d."), # Seconds
(microseconds % SECOND, "%6.6d")]: # Microseconds
-
+
# Add value to TIME_OF_DAY literal
data += format % val
-
+
return data
-# Dictionary of translation functions from value send by debugger to IEC
+# Dictionary of translation functions from value send by debugger to IEC
# literal stored by type
TYPE_TRANSLATOR = {
"TIME": generate_time,
@@ -154,7 +154,7 @@
"""
class DebugDataConsumer:
-
+
def __init__(self):
"""
Constructor
@@ -162,17 +162,17 @@
# Debug value and forced flag
self.Value = None
self.Forced = False
-
+
# Store debug value and forced flag when value update is inhibited
self.LastValue = None
self.LastForced = False
-
+
# Value IEC data type
self.DataType = None
-
+
# Flag that value update is inhibited
self.Inhibited = False
-
+
def Inhibit(self, inhibit):
"""
Set flag to inhibit or activate value update
@@ -180,23 +180,23 @@
"""
# Save inhibit flag
self.Inhibited = inhibit
-
+
# When reactivated update value and forced flag with stored values
if not inhibit and self.LastValue is not None:
self.SetForced(self.LastForced)
self.SetValue(self.LastValue)
-
+
# Reset stored values
self.LastValue = None
self.LastForced = False
-
+
def SetDataType(self, data_type):
"""
Set value IEC data type
@param data_type: Value IEC data type
"""
self.DataType = data_type
-
+
def NewValues(self, tick, values, raw="BOOL"):
"""
Function called by debug thread when a new debug value is available
@@ -206,21 +206,21 @@
@param raw: Data type of values not translated (default: 'BOOL')
"""
value, forced = values
-
+
# Translate value to IEC literal
if self.DataType != raw:
value = TYPE_TRANSLATOR.get(self.DataType, str)(value)
-
+
# Store value and forced flag when value update is inhibited
if self.Inhibited:
self.LastValue = value
self.LastForced = forced
-
+
# Update value and forced flag in any other case
else:
self.SetForced(forced)
self.SetValue(value)
-
+
def SetValue(self, value):
"""
Update value.
@@ -228,14 +228,14 @@
@param value: New value
"""
self.Value = value
-
+
def GetValue(self):
"""
Return current value
@return: Current value
"""
return self.Value
-
+
def SetForced(self, forced):
"""
Update Forced flag.
@@ -243,7 +243,7 @@
@param forced: New forced flag
"""
self.Forced = forced
-
+
def IsForced(self):
"""
Indicate if current value is forced
--- a/graphics/FBD_Objects.py Fri Aug 11 15:18:19 2017 +0300
+++ b/graphics/FBD_Objects.py Mon Aug 14 19:13:01 2017 +0300
@@ -39,7 +39,7 @@
return name in ["OUT", "MN", "MX"] or name.startswith("IN") and (block_type, name) != ("EXPT", "IN2")
class FBD_Block(Graphic_Element):
-
+
# Create a new block
def __init__(self, parent, type, name, id = None, extension = 0, inputs = None, connectors = {}, executionControl = False, executionOrder = 0):
Graphic_Element.__init__(self, parent)
@@ -56,7 +56,7 @@
self.Pen = MiterPen(wx.BLACK)
self.SetType(type, extension, inputs, connectors, executionControl)
self.Highlights = {}
-
+
# Make a clone of this FBD_Block
def Clone(self, parent, id = None, name = "", pos = None):
if self.Name != "" and name == "":
@@ -70,10 +70,10 @@
block.Inputs = [input.Clone(block) for input in self.Inputs]
block.Outputs = [output.Clone(block) for output in self.Outputs]
return block
-
+
def GetConnectorTranslation(self, element):
return dict(zip(self.Inputs + self.Outputs, element.Inputs + element.Outputs))
-
+
def Flush(self):
for input in self.Inputs:
input.Flush()
@@ -81,7 +81,7 @@
for output in self.Outputs:
output.Flush()
self.Outputs = []
-
+
# Returns the RedrawRect
def GetRedrawRect(self, movex = 0, movey = 0):
rect = Graphic_Element.GetRedrawRect(self, movex, movey)
@@ -93,26 +93,26 @@
if output.IsConnected():
rect = rect.Union(output.GetConnectedRedrawRect(movex, movey))
return rect
-
+
# Delete this block by calling the appropriate method
def Delete(self):
self.Parent.DeleteBlock(self)
-
+
# Unconnect all inputs and outputs
def Clean(self):
for input in self.Inputs:
input.UnConnect(delete = True)
for output in self.Outputs:
output.UnConnect(delete = True)
-
+
# Refresh the size of text for name
def RefreshNameSize(self):
self.NameSize = self.Parent.GetTextExtent(self.Name)
-
+
# Refresh the size of text for execution order
def RefreshExecutionOrderSize(self):
self.ExecutionOrderSize = self.Parent.GetTextExtent(str(self.ExecutionOrder))
-
+
# Returns if the point given is in the bounding box
def HitTest(self, pt, connectors=True):
if self.Name != "":
@@ -121,7 +121,7 @@
test_text = False
test_block = self.GetBlockBoundingBox(connectors).InsideXY(pt.x, pt.y)
return test_text or test_block
-
+
# Returns the bounding box of the name outside the block
def GetTextBoundingBox(self):
# Calculate the size of the name outside the block
@@ -130,7 +130,7 @@
self.Pos.y - (text_height + 2),
text_width,
text_height)
-
+
# Returns the bounding box of function block without name outside
def GetBlockBoundingBox(self, connectors=True):
bbx_x, bbx_y = self.Pos.x, self.Pos.y
@@ -143,13 +143,13 @@
bbx_width = max(bbx_width, bbx_width + self.Pos.x + self.ExecutionOrderSize[0] - bbx_x - self.Size[0])
bbx_height = bbx_height + (self.ExecutionOrderSize[1] + 2)
return wx.Rect(bbx_x, bbx_y, bbx_width + 1, bbx_height + 1)
-
+
# Refresh the block bounding box
def RefreshBoundingBox(self):
self.BoundingBox = self.GetBlockBoundingBox()
if self.Name != "":
self.BoundingBox.Union(self.GetTextBoundingBox())
-
+
# Refresh the positions of the block connectors
def RefreshConnectors(self):
scaling = self.Parent.GetScaling()
@@ -170,15 +170,15 @@
self.Outputs[i].SetPosition(wx.Point(self.Size[0], ypos))
position += linesize
self.RefreshConnected()
-
+
# Refresh the positions of wires connected to inputs and outputs
def RefreshConnected(self, exclude = []):
for input in self.Inputs:
input.MoveConnected(exclude)
for output in self.Outputs:
output.MoveConnected(exclude)
-
- # Returns the block connector that starts with the point given if it exists
+
+ # Returns the block connector that starts with the point given if it exists
def GetConnector(self, position, output_name = None, input_name = None):
if input_name is not None:
# Test each input connector
@@ -193,14 +193,14 @@
if input_name is None and output_name is None:
return self.FindNearestConnector(position, self.Inputs + self.Outputs)
return None
-
+
def GetInputTypes(self):
return tuple([input.GetType(True) for input in self.Inputs if input.GetName() != "EN"])
-
+
def SetOutputValues(self, values):
for output in self.Outputs:
output.SetValue(values.get(ouput.getName(), None))
-
+
def GetConnectionResultType(self, connector, connectortype):
if not TestConnectorName(connector.GetName(), self.Type):
return connectortype
@@ -216,11 +216,11 @@
if resulttype is None or outputtype is not None and self.IsOfType(outputtype, resulttype):
resulttype = outputtype
return resulttype
-
+
# Returns all the block connectors
def GetConnectors(self):
return {"inputs" : self.Inputs, "outputs" : self.Outputs}
-
+
# Test if point given is on one of the block connectors
def TestConnector(self, pt, direction = None, exclude = True):
# Test each input connector
@@ -232,10 +232,10 @@
if output.TestPoint(pt, direction, exclude):
return output
return None
-
+
# Changes the block type
def SetType(self, type, extension, inputs = None, connectors = {}, executionControl = False):
- if type != self.Type or self.Extension != extension or executionControl != self.ExecutionControl:
+ if type != self.Type or self.Extension != extension or executionControl != self.ExecutionControl:
if type != self.Type:
self.Type = type
self.TypeSize = self.Parent.GetTextExtent(self.Type)
@@ -264,7 +264,7 @@
inputs.insert(0, ("EN","BOOL","none"))
outputs.insert(0, ("ENO","BOOL","none"))
self.Pen = MiterPen(self.Colour)
-
+
# Extract the inputs properties and create or modify the corresponding connector
input_connectors = []
for input_name, input_type, input_modifier in inputs:
@@ -284,7 +284,7 @@
for input in self.Inputs:
input.UnConnect(delete = True)
self.Inputs = input_connectors
-
+
# Extract the outputs properties and create or modify the corresponding connector
output_connectors = []
for output_name, output_type, output_modifier in outputs:
@@ -304,47 +304,47 @@
for output in self.Outputs:
output.UnConnect(delete = True)
self.Outputs = output_connectors
-
+
self.RefreshMinSize()
self.RefreshConnectors()
for output in self.Outputs:
output.RefreshWires()
self.RefreshBoundingBox()
-
+
# Returns the block type
def GetType(self):
return self.Type
-
+
# Changes the block name
def SetName(self, name):
self.Name = name
self.RefreshNameSize()
-
+
# Returs the block name
def GetName(self):
return self.Name
-
+
# Changes the extension name
def SetExtension(self, extension):
self.Extension = extension
-
+
# Returs the extension name
def GetExtension(self):
return self.Extension
-
+
# Changes the execution order
def SetExecutionOrder(self, executionOrder):
self.ExecutionOrder = executionOrder
self.RefreshExecutionOrderSize()
-
+
# Returs the execution order
def GetExecutionOrder(self):
return self.ExecutionOrder
-
+
# Returs the execution order
def GetExecutionControl(self):
return self.ExecutionControl
-
+
# Refresh the block minimum size
def RefreshMinSize(self):
# Calculate the inputs maximum width
@@ -360,25 +360,25 @@
width = max(self.TypeSize[0] + 10, max_input + max_output + 15)
height = (max(len(self.Inputs), len(self.Outputs)) + 1) * BLOCK_LINE_SIZE
self.MinSize = width, height
-
+
# Returns the block minimum size
def GetMinSize(self):
return self.MinSize
-
+
# Changes the negated property of the connector handled
def SetConnectorNegated(self, negated):
handle_type, handle = self.Handle
if handle_type == HANDLE_CONNECTOR:
handle.SetNegated(negated)
self.RefreshModel(False)
-
+
# Changes the edge property of the connector handled
def SetConnectorEdge(self, edge):
handle_type, handle = self.Handle
if handle_type == HANDLE_CONNECTOR:
handle.SetEdge(edge)
self.RefreshModel(False)
-
+
## # Method called when a Motion event have been generated
## def OnMotion(self, event, dc, scaling):
## if not event.Dragging():
@@ -390,12 +390,12 @@
## tip = wx.TipWindow(self.Parent, "Test")
## tip.SetBoundingRect(rect)
## return Graphic_Element.OnMotion(self, event, dc, scaling)
-
+
# Method called when a LeftDClick event have been generated
def OnLeftDClick(self, event, dc, scaling):
# Edit the block properties
self.Parent.EditBlockContent(self)
-
+
# Method called when a RightUp event have been generated
def OnRightUp(self, event, dc, scaling):
pos = GetScaledEventPosition(event, dc, scaling)
@@ -406,7 +406,7 @@
self.Parent.PopupBlockMenu(connector)
else:
self.Parent.PopupBlockMenu()
-
+
# Refreshes the block model
def RefreshModel(self, move=True):
self.Parent.RefreshBlockModel(self)
@@ -414,10 +414,10 @@
if move:
for output in self.Outputs:
output.RefreshWires()
-
+
def GetToolTipValue(self):
return self.Description
-
+
# Adds an highlight to the block
def AddHighlight(self, infos, start, end ,highlight_type):
if infos[0] in ["type", "name"] and start[0] == 0 and end[0] == 0:
@@ -427,7 +427,7 @@
self.Inputs[infos[1]].AddHighlight(infos[2:], start, end, highlight_type)
elif infos[0] == "output" and infos[1] < len(self.Outputs):
self.Outputs[infos[1]].AddHighlight(infos[2:], start, end, highlight_type)
-
+
# Removes an highlight from the block
def RemoveHighlight(self, infos, start, end, highlight_type):
if infos[0] in ["type", "name"]:
@@ -438,7 +438,7 @@
self.Inputs[infos[1]].RemoveHighlight(infos[2:], start, end, highlight_type)
elif infos[0] == "output" and infos[1] < len(self.Outputs):
self.Outputs[infos[1]].RemoveHighlight(infos[2:], start, end, highlight_type)
-
+
# Removes all the highlights of one particular type from the block
def ClearHighlight(self, highlight_type=None):
if highlight_type is None:
@@ -453,14 +453,14 @@
input.ClearHighlights(highlight_type)
for output in self.Outputs:
output.ClearHighlights(highlight_type)
-
+
# Draws block
def Draw(self, dc):
Graphic_Element.Draw(self, dc)
dc.SetPen(self.Pen)
dc.SetBrush(wx.WHITE_BRUSH)
dc.SetTextForeground(self.Colour)
-
+
if getattr(dc, "printing", False):
name_size = dc.GetTextExtent(self.Name)
type_size = dc.GetTextExtent(self.Type)
@@ -469,7 +469,7 @@
name_size = self.NameSize
type_size = self.TypeSize
executionorder_size = self.ExecutionOrderSize
-
+
# Draw a rectangle with the block size
dc.DrawRectangle(self.Pos.x, self.Pos.y, self.Size[0] + 1, self.Size[1] + 1)
# Draw block name and block type
@@ -488,11 +488,11 @@
# Draw block execution order
dc.DrawText(str(self.ExecutionOrder), self.Pos.x + self.Size[0] - executionorder_size[0],
self.Pos.y + self.Size[1] + 2)
-
+
if not getattr(dc, "printing", False):
DrawHighlightedText(dc, self.Name, self.Highlights.get("name", []), name_pos[0], name_pos[1])
DrawHighlightedText(dc, self.Type, self.Highlights.get("type", []), type_pos[0], type_pos[1])
-
+
#-------------------------------------------------------------------------------
# Function Block Diagram Variable
@@ -516,7 +516,7 @@
self.Output = None
self.SetType(type, value_type)
self.Highlights = []
-
+
# Make a clone of this FBD_Variable
def Clone(self, parent, id = None, pos = None):
variable = FBD_Variable(parent, self.Type, self.Name, self.ValueType, id)
@@ -530,7 +530,7 @@
if self.Output:
variable.Output = self.Output.Clone(variable)
return variable
-
+
def GetConnectorTranslation(self, element):
connectors = {}
if self.Input is not None:
@@ -538,7 +538,7 @@
if self.Output is not None:
connectors[self.Output] = element.Output
return connectors
-
+
def Flush(self):
if self.Input is not None:
self.Input.Flush()
@@ -546,7 +546,7 @@
if self.Output is not None:
self.Output.Flush()
self.Output = None
-
+
# Returns the RedrawRect
def GetRedrawRect(self, movex = 0, movey = 0):
rect = Graphic_Element.GetRedrawRect(self, movex, movey)
@@ -556,26 +556,26 @@
if self.Output and self.Output.IsConnected():
rect = rect.Union(self.Output.GetConnectedRedrawRect(movex, movey))
return rect
-
+
# Unconnect connector
def Clean(self):
if self.Input:
self.Input.UnConnect(delete = True)
if self.Output:
self.Output.UnConnect(delete = True)
-
+
# Delete this variable by calling the appropriate method
def Delete(self):
self.Parent.DeleteVariable(self)
-
+
# Refresh the size of text for name
def RefreshNameSize(self):
self.NameSize = self.Parent.GetTextExtent(self.Name)
-
+
# Refresh the size of text for execution order
def RefreshExecutionOrderSize(self):
self.ExecutionOrderSize = self.Parent.GetTextExtent(str(self.ExecutionOrder))
-
+
# Refresh the variable bounding box
def RefreshBoundingBox(self):
if self.Type in (OUTPUT, INOUT):
@@ -594,7 +594,7 @@
bbx_width = max(bbx_width, bbx_width + self.Pos.x + self.ExecutionOrderSize[0] - bbx_x - self.Size[0])
bbx_height = bbx_height + (self.ExecutionOrderSize[1] + 2)
self.BoundingBox = wx.Rect(bbx_x, self.Pos.y, bbx_width + 1, bbx_height + 1)
-
+
# Refresh the position of the variable connector
def RefreshConnectors(self):
scaling = self.Parent.GetScaling()
@@ -607,14 +607,14 @@
if self.Output:
self.Output.SetPosition(wx.Point(self.Size[0], position))
self.RefreshConnected()
-
+
# Refresh the position of wires connected to connector
def RefreshConnected(self, exclude = []):
if self.Input:
self.Input.MoveConnected(exclude)
if self.Output:
self.Output.MoveConnected(exclude)
-
+
# Test if point given is on the variable connector
def TestConnector(self, pt, direction = None, exclude=True):
if self.Input and self.Input.TestPoint(pt, direction, exclude):
@@ -622,8 +622,8 @@
if self.Output and self.Output.TestPoint(pt, direction, exclude):
return self.Output
return None
-
- # Returns the block connector that starts with the point given if it exists
+
+ # Returns the block connector that starts with the point given if it exists
def GetConnector(self, position, name = None):
# if a name is given
if name is not None:
@@ -640,8 +640,8 @@
if self.Output:
connectors.append(self.Output)
return self.FindNearestConnector(position, connectors)
-
- # Returns all the block connectors
+
+ # Returns all the block connectors
def GetConnectors(self):
connectors = {"inputs": [], "outputs": []}
if self.Input:
@@ -649,14 +649,14 @@
if self.Output:
connectors["outputs"].append(self.Output)
return connectors
-
+
# Changes the negated property of the variable connector if handled
def SetConnectorNegated(self, negated):
handle_type, handle = self.Handle
if handle_type == HANDLE_CONNECTOR:
handle.SetNegated(negated)
self.RefreshModel(False)
-
+
# Changes the variable type
def SetType(self, type, value_type):
if type != self.Type:
@@ -680,38 +680,38 @@
if self.Input:
self.Input.SetType(value_type)
if self.Output:
- self.Output.SetType(value_type)
-
+ self.Output.SetType(value_type)
+
# Returns the variable type
def GetType(self):
return self.Type
-
+
# Returns the variable value type
def GetValueType(self):
return self.ValueType
-
+
# Changes the variable name
def SetName(self, name):
self.Name = name
self.RefreshNameSize()
-
+
# Returns the variable name
def GetName(self):
return self.Name
-
+
# Changes the execution order
def SetExecutionOrder(self, executionOrder):
self.ExecutionOrder = executionOrder
self.RefreshExecutionOrderSize()
-
+
# Returs the execution order
def GetExecutionOrder(self):
return self.ExecutionOrder
-
+
# Returns the variable minimum size
def GetMinSize(self):
return self.NameSize[0] + 10, self.NameSize[1] + 10
-
+
# Set size of the variable to the minimum size
def SetBestSize(self, scaling):
if self.Type == INPUT:
@@ -720,22 +720,22 @@
return Graphic_Element.SetBestSize(self, scaling, x_factor=0.)
else:
return Graphic_Element.SetBestSize(self, scaling)
-
+
# Method called when a LeftDClick event have been generated
def OnLeftDClick(self, event, dc, scaling):
if event.ControlDown():
- # Change variable type
+ # Change variable type
types = [INPUT, OUTPUT, INOUT]
self.Parent.ChangeVariableType(self,
types[(types.index(self.Type) + 1) % len(types)])
else:
# Edit the variable properties
self.Parent.EditVariableContent(self)
-
+
# Method called when a RightUp event have been generated
def OnRightUp(self, event, dc, scaling):
self.Parent.PopupVariableMenu()
-
+
# Refreshes the variable model
def RefreshModel(self, move=True):
self.Parent.RefreshVariableModel(self)
@@ -744,35 +744,35 @@
if move and self.Type != OUTPUT:
if self.Output:
self.Output.RefreshWires()
-
+
# Adds an highlight to the variable
def AddHighlight(self, infos, start, end, highlight_type):
if infos[0] == "expression" and start[0] == 0 and end[0] == 0:
AddHighlight(self.Highlights, (start, end, highlight_type))
-
+
# Removes an highlight from the variable
def RemoveHighlight(self, infos, start, end, highlight_type):
if infos[0] == "expression":
RemoveHighlight(self.Highlights, (start, end, highlight_type))
-
+
# Removes all the highlights of one particular type from the variable
def ClearHighlight(self, highlight_type=None):
ClearHighlights(self.Highlights, highlight_type)
-
+
# Draws variable
def Draw(self, dc):
Graphic_Element.Draw(self, dc)
dc.SetPen(MiterPen(wx.BLACK))
dc.SetBrush(wx.WHITE_BRUSH)
-
+
if getattr(dc, "printing", False):
name_size = dc.GetTextExtent(self.Name)
executionorder_size = dc.GetTextExtent(str(self.ExecutionOrder))
else:
name_size = self.NameSize
executionorder_size = self.ExecutionOrderSize
-
- text_pos = (self.Pos.x + (self.Size[0] - name_size[0]) / 2,
+
+ text_pos = (self.Pos.x + (self.Size[0] - name_size[0]) / 2,
self.Pos.y + (self.Size[1] - name_size[1]) / 2)
# Draw a rectangle with the variable size
dc.DrawRectangle(self.Pos.x, self.Pos.y, self.Size[0] + 1, self.Size[1] + 1)
@@ -781,7 +781,7 @@
# Draw connectors
if self.Input:
self.Input.Draw(dc)
- if self.Output:
+ if self.Output:
self.Output.Draw(dc)
if self.ExecutionOrder != 0:
# Draw variable execution order
@@ -789,7 +789,7 @@
self.Pos.y + self.Size[1] + 2)
if not getattr(dc, "printing", False):
DrawHighlightedText(dc, self.Name, self.Highlights, text_pos[0], text_pos[1])
-
+
#-------------------------------------------------------------------------------
# Function Block Diagram Connector
#-------------------------------------------------------------------------------
@@ -816,12 +816,12 @@
self.Connector = Connector(self, "", "ANY", wx.Point(0, 0), EAST)
self.RefreshConnectors()
self.RefreshNameSize()
-
+
def Flush(self):
if self.Connector:
self.Connector.Flush()
self.Connector = None
-
+
# Returns the RedrawRect
def GetRedrawRect(self, movex = 0, movey = 0):
rect = Graphic_Element.GetRedrawRect(self, movex, movey)
@@ -829,7 +829,7 @@
if self.Connector and self.Connector.IsConnected():
rect = rect.Union(self.Connector.GetConnectedRedrawRect(movex, movey))
return rect
-
+
# Make a clone of this FBD_Connector
def Clone(self, parent, id = None, pos = None):
connection = FBD_Connector(parent, self.Type, self.Name, id)
@@ -840,7 +840,7 @@
connection.SetPosition(self.Pos.x, self.Pos.y)
connection.Connector = self.Connector.Clone(connection)
return connection
-
+
def GetConnectorTranslation(self, element):
return {self.Connector : element.Connector}
@@ -848,15 +848,15 @@
def Clean(self):
if self.Connector:
self.Connector.UnConnect(delete = True)
-
+
# Delete this connection by calling the appropriate method
def Delete(self):
self.Parent.DeleteConnection(self)
-
+
# Refresh the size of text for name
def RefreshNameSize(self):
self.NameSize = self.Parent.GetTextExtent(self.Name)
-
+
# Refresh the connection bounding box
def RefreshBoundingBox(self):
if self.Type == CONNECTOR:
@@ -865,7 +865,7 @@
bbx_x = self.Pos.x
bbx_width = self.Size[0] + CONNECTOR_SIZE
self.BoundingBox = wx.Rect(bbx_x, self.Pos.y, bbx_width, self.Size[1])
-
+
# Refresh the position of the connection connector
def RefreshConnectors(self):
scaling = self.Parent.GetScaling()
@@ -878,23 +878,23 @@
else:
self.Connector.SetPosition(wx.Point(self.Size[0], position))
self.RefreshConnected()
-
+
# Refresh the position of wires connected to connector
def RefreshConnected(self, exclude = []):
if self.Connector:
self.Connector.MoveConnected(exclude)
-
+
# Test if point given is on the connection connector
def TestConnector(self, pt, direction = None, exclude=True):
if self.Connector and self.Connector.TestPoint(pt, direction, exclude):
return self.Connector
return None
-
+
# Returns the connection connector
def GetConnector(self, position = None, name = None):
return self.Connector
-
- # Returns all the block connectors
+
+ # Returns all the block connectors
def GetConnectors(self):
connectors = {"inputs": [], "outputs": []}
if self.Type == CONNECTOR:
@@ -923,45 +923,45 @@
self.Connector = Connector(self, "", "ANY", wx.Point(0, 0), EAST)
self.RefreshConnectors()
self.RefreshBoundingBox()
-
+
# Returns the connection type
def GetType(self):
return self.Type
-
+
def GetConnectionResultType(self, connector, connectortype):
if self.Type == CONTINUATION:
connector = self.Parent.GetConnectorByName(self.Name)
if connector is not None:
return connector.Connector.GetConnectedType()
return connectortype
-
+
# Changes the connection name
def SetName(self, name):
self.Name = name
self.RefreshNameSize()
-
+
# Returns the connection name
def GetName(self):
return self.Name
-
+
# Set size of the variable to the minimum size
def SetBestSize(self, scaling):
if self.Type == CONTINUATION:
return Graphic_Element.SetBestSize(self, scaling, x_factor=1.)
else:
return Graphic_Element.SetBestSize(self, scaling, x_factor=0.)
-
+
# Returns the connection minimum size
def GetMinSize(self):
text_width, text_height = self.NameSize
if text_height % 2 == 1:
text_height += 1
return text_width + text_height + 20, text_height + 10
-
+
# Method called when a LeftDClick event have been generated
def OnLeftDClick(self, event, dc, scaling):
if event.ControlDown():
- # Change connection type
+ # Change connection type
if self.Type == CONNECTOR:
self.Parent.ChangeConnectionType(self, CONTINUATION)
else:
@@ -969,12 +969,12 @@
else:
# Edit the connection properties
self.Parent.EditConnectionContent(self)
-
+
# Method called when a RightUp event have been generated
def OnRightUp(self, event, dc, scaling):
# Popup the default menu
self.Parent.PopupConnectionMenu()
-
+
# Refreshes the connection model
def RefreshModel(self, move=True):
self.Parent.RefreshConnectionModel(self)
@@ -983,51 +983,50 @@
if move and self.Type == CONTINUATION:
if self.Connector:
self.Connector.RefreshWires()
-
+
# Adds an highlight to the connection
def AddHighlight(self, infos, start, end, highlight_type):
if infos[0] == "name" and start[0] == 0 and end[0] == 0:
AddHighlight(self.Highlights, (start, end, highlight_type))
-
+
# Removes an highlight from the connection
def RemoveHighlight(self, infos, start, end, highlight_type):
if infos[0] == "name":
RemoveHighlight(self.Highlights, (start, end, highlight_type))
-
+
# Removes all the highlights of one particular type from the connection
def ClearHighlight(self, highlight_type=None):
ClearHighlights(self.Highlights, highlight_type)
-
+
# Draws connection
def Draw(self, dc):
Graphic_Element.Draw(self, dc)
dc.SetPen(MiterPen(wx.BLACK))
dc.SetBrush(wx.WHITE_BRUSH)
-
+
if getattr(dc, "printing", False):
name_size = dc.GetTextExtent(self.Name)
else:
name_size = self.NameSize
-
+
# Draw a rectangle with the connection size with arrows inside
dc.DrawRectangle(self.Pos.x, self.Pos.y, self.Size[0] + 1, self.Size[1] + 1)
arrowsize = min(self.Size[1] / 2, (self.Size[0] - name_size[0] - 10) / 2)
- dc.DrawLine(self.Pos.x, self.Pos.y, self.Pos.x + arrowsize,
+ dc.DrawLine(self.Pos.x, self.Pos.y, self.Pos.x + arrowsize,
self.Pos.y + self.Size[1] / 2)
- dc.DrawLine(self.Pos.x + arrowsize, self.Pos.y + self.Size[1] / 2,
+ dc.DrawLine(self.Pos.x + arrowsize, self.Pos.y + self.Size[1] / 2,
self.Pos.x, self.Pos.y + self.Size[1])
- dc.DrawLine(self.Pos.x + self.Size[0] - arrowsize, self.Pos.y,
+ dc.DrawLine(self.Pos.x + self.Size[0] - arrowsize, self.Pos.y,
self.Pos.x + self.Size[0], self.Pos.y + self.Size[1] / 2)
- dc.DrawLine(self.Pos.x + self.Size[0], self.Pos.y + self.Size[1] / 2,
+ dc.DrawLine(self.Pos.x + self.Size[0], self.Pos.y + self.Size[1] / 2,
self.Pos.x + self.Size[0] - arrowsize, self.Pos.y + self.Size[1])
# Draw connection name
- text_pos = (self.Pos.x + (self.Size[0] - name_size[0]) / 2,
+ text_pos = (self.Pos.x + (self.Size[0] - name_size[0]) / 2,
self.Pos.y + (self.Size[1] - name_size[1]) / 2)
dc.DrawText(self.Name, text_pos[0], text_pos[1])
# Draw connector
if self.Connector:
self.Connector.Draw(dc)
-
+
if not getattr(dc, "printing", False):
DrawHighlightedText(dc, self.Name, self.Highlights, text_pos[0], text_pos[1])
-
--- a/graphics/GraphicCommons.py Fri Aug 11 15:18:19 2017 +0300
+++ b/graphics/GraphicCommons.py Mon Aug 14 19:13:01 2017 +0300
@@ -83,12 +83,12 @@
# Contants for defining the direction of a connector
[EAST, NORTH, WEST, SOUTH] = [(1,0), (0,-1), (-1,0), (0,1)]
-# Contants for defining which mode is selected for each view
-[MODE_SELECTION, MODE_BLOCK, MODE_VARIABLE, MODE_CONNECTION, MODE_COMMENT,
- MODE_COIL, MODE_CONTACT, MODE_POWERRAIL, MODE_INITIALSTEP, MODE_STEP,
+# Contants for defining which mode is selected for each view
+[MODE_SELECTION, MODE_BLOCK, MODE_VARIABLE, MODE_CONNECTION, MODE_COMMENT,
+ MODE_COIL, MODE_CONTACT, MODE_POWERRAIL, MODE_INITIALSTEP, MODE_STEP,
MODE_TRANSITION, MODE_DIVERGENCE, MODE_JUMP, MODE_ACTION, MODE_MOTION] = range(15)
-# Contants for defining alignment types for graphic group
+# Contants for defining alignment types for graphic group
[ALIGN_LEFT, ALIGN_CENTER, ALIGN_RIGHT, ALIGN_TOP, ALIGN_MIDDLE, ALIGN_BOTTOM] = range(6)
# Contants for defining which drawing mode is selected for app
@@ -122,7 +122,7 @@
else:
xround = round(fraction)
if constraint == 1 and xround < fraction:
- xround += 1
+ xround += 1
return int(xround * n)
"""
@@ -224,7 +224,7 @@
dc.DrawText(part, x + offset_width, y)
dc.SetPen(current_pen)
dc.SetTextForeground(wx.BLACK)
-
+
#-------------------------------------------------------------------------------
# Graphic element base class
#-------------------------------------------------------------------------------
@@ -234,7 +234,7 @@
"""
class Graphic_Element(ToolTipProducer):
-
+
# Create a new graphic element
def __init__(self, parent, id = None):
ToolTipProducer.__init__(self, parent)
@@ -251,22 +251,22 @@
self.Size = wx.Size(0, 0)
self.BoundingBox = wx.Rect(0, 0, 0, 0)
self.Visible = False
-
+
def GetDefinition(self):
return [self.Id], []
-
+
def TestVisible(self, screen):
self.Visible = self.Selected or self.GetRedrawRect().Intersects(screen)
-
+
def IsVisible(self):
return self.Visible
-
+
def SpreadCurrent(self):
pass
-
+
def GetConnectorTranslation(self, element):
return {}
-
+
def FindNearestConnector(self, position, connectors):
distances = []
for connector in connectors:
@@ -278,20 +278,20 @@
if len(distances) > 0:
return distances[0][1]
return None
-
+
def IsOfType(self, type, reference):
return self.Parent.IsOfType(type, reference)
-
+
def IsEndType(self, type):
return self.Parent.IsEndType(type)
-
+
def GetDragging(self):
return self.Dragging
-
+
# Make a clone of this element
def Clone(self, parent):
return Graphic_Element(parent, self.Id)
-
+
# Changes the block position
def SetPosition(self, x, y):
self.Pos.x = x
@@ -302,7 +302,7 @@
# Returns the block position
def GetPosition(self):
return self.Pos.x, self.Pos.y
-
+
# Changes the element size
def SetSize(self, width, height):
self.Size.SetWidth(width)
@@ -313,11 +313,11 @@
# Returns the element size
def GetSize(self):
return self.Size.GetWidth(), self.Size.GetHeight()
-
+
# Returns the minimum element size
def GetMinSize(self):
return 0, 0
-
+
# Set size of the element to the minimum size
def SetBestSize(self, scaling, x_factor=0.5, y_factor=0.5):
width, height = self.GetSize()
@@ -336,31 +336,31 @@
height = round_scaling(height, scaling[1], 1)
self.SetSize(width, height)
return self.Pos.x - posx, self.Pos.y - posy
-
+
# Refresh the element Bounding Box
def RefreshBoundingBox(self):
self.BoundingBox = wx.Rect(self.Pos.x, self.Pos.y, self.Size[0], self.Size[1])
-
+
# Refresh the element connectors position
def RefreshConnectors(self):
pass
-
+
# Refresh the position of wires connected to element inputs and outputs
def RefreshConnected(self):
pass
-
+
# Change the parent
def SetParent(self, parent):
self.Parent = parent
-
+
# Override this method for defining the method to call for deleting this element
def Delete(self):
pass
-
+
# Returns the Id
def GetId(self):
return self.Id
-
+
# Returns if the point given is in the bounding box
def HitTest(self, pt, connectors=True):
if connectors:
@@ -368,19 +368,19 @@
else:
rect = wx.Rect(self.Pos.x, self.Pos.y, self.Size[0], self.Size[1])
return rect.InsideXY(pt.x, pt.y)
-
+
# Returns if the point given is in the bounding box
def IsInSelection(self, rect):
return rect.InsideXY(self.BoundingBox.x, self.BoundingBox.y) and rect.InsideXY(self.BoundingBox.x + self.BoundingBox.width, self.BoundingBox.y + self.BoundingBox.height)
-
+
# Override this method for refreshing the bounding box
def RefreshBoundingBox(self):
pass
-
+
# Returns the bounding box
def GetBoundingBox(self):
return self.BoundingBox
-
+
# Returns the RedrawRect
def GetRedrawRect(self, movex = 0, movey = 0):
scalex, scaley = self.Parent.GetViewScale()
@@ -390,42 +390,42 @@
rect.width = self.BoundingBox.width + 2 * (int(HANDLE_SIZE / scalex) + abs(movex) + 1) + 4
rect.height = self.BoundingBox.height + 2 * (int(HANDLE_SIZE / scaley) + abs(movey) + 1) + 4
return rect
-
+
def Refresh(self, rect = None):
if self.Visible:
if rect is not None:
self.Parent.RefreshRect(self.Parent.GetScrolledRect(rect), False)
else:
self.Parent.RefreshRect(self.Parent.GetScrolledRect(self.GetRedrawRect()), False)
-
+
# Change the variable that indicates if this element is selected
def SetSelected(self, selected):
self.Selected = selected
self.Refresh()
-
+
# Change the variable that indicates if this element is highlighted
def SetHighlighted(self, highlighted):
self.Highlighted = highlighted
self.Refresh()
-
+
# Test if the point is on a handle of this element
def TestHandle(self, event):
dc = self.Parent.GetLogicalDC()
scalex, scaley = dc.GetUserScale()
pos = event.GetPosition()
pt = wx.Point(*self.Parent.CalcUnscrolledPosition(pos.x, pos.y))
-
+
left = (self.BoundingBox.x - 2) * scalex - HANDLE_SIZE
center = (self.BoundingBox.x + self.BoundingBox.width / 2) * scalex - HANDLE_SIZE / 2
right = (self.BoundingBox.x + self.BoundingBox.width + 2) * scalex
-
+
top = (self.BoundingBox.y - 2) * scaley - HANDLE_SIZE
middle = (self.BoundingBox.y + self.BoundingBox.height / 2) * scaley - HANDLE_SIZE / 2
bottom = (self.BoundingBox.y + self.BoundingBox.height + 2) * scaley
-
+
extern_rect = wx.Rect(left, top, right + HANDLE_SIZE - left, bottom + HANDLE_SIZE - top)
intern_rect = wx.Rect(left + HANDLE_SIZE, top + HANDLE_SIZE, right - left - HANDLE_SIZE, bottom - top - HANDLE_SIZE)
-
+
# Verify that this element is selected
if self.Selected and extern_rect.InsideXY(pt.x, pt.y) and not intern_rect.InsideXY(pt.x, pt.y):
# Find if point is on a handle horizontally
@@ -450,7 +450,7 @@
if (handle_x, handle_y) in VALID_HANDLES:
return handle_x, handle_y
return 0, 0
-
+
# Method called when a LeftDown event have been generated
def OnLeftDown(self, event, dc, scaling):
pos = event.GetLogicalPosition(dc)
@@ -469,7 +469,7 @@
self.oldPos = GetScaledEventPosition(event, dc, scaling)
self.StartPos = wx.Point(self.Pos.x, self.Pos.y)
self.CurrentDrag = wx.Point(0, 0)
-
+
# Method called when a LeftUp event have been generated
def OnLeftUp(self, event, dc, scaling):
# If a dragging have been initiated
@@ -498,7 +498,7 @@
# Method called when a LeftDClick event have been generated
def OnLeftDClick(self, event, dc, scaling):
pass
-
+
# Method called when a Motion event have been generated
def OnMotion(self, event, dc, scaling):
# If the cursor is dragging and the element have been clicked
@@ -537,12 +537,12 @@
self.Pos.y += max(-self.BoundingBox.y, dy)
self.RefreshConnected(exclude)
self.RefreshBoundingBox()
-
+
# Resizes the element from position and size given
def Resize(self, x, y, width, height):
self.Move(x, y)
self.SetSize(width, height)
-
+
# Refreshes the element state according to move defined and handle selected
def ProcessDragging(self, movex, movey, event, scaling, width_fac = 1, height_fac = 1):
handle_type, handle = self.Handle
@@ -618,27 +618,27 @@
movey = self.StartPos.y - self.Pos.y
else:
movex = self.StartPos.x - self.Pos.x
- movey = self.StartPos.y + self.CurrentDrag.y - self.Pos.y
+ movey = self.StartPos.y + self.CurrentDrag.y - self.Pos.y
self.Move(movex, movey)
return movex, movey
return 0, 0
-
+
# Override this method for defining the method to call for adding an highlight to this element
def AddHighlight(self, infos, start, end, highlight_type):
pass
-
+
# Override this method for defining the method to call for removing an highlight from this element
def RemoveHighlight(self, infos, start, end, highlight_type):
pass
-
+
# Override this method for defining the method to call for removing all the highlights of one particular type from this element
def ClearHighlight(self, highlight_type=None):
pass
-
+
# Override this method for defining the method to call for refreshing the model of this element
def RefreshModel(self, move=True):
pass
-
+
# Draws the highlightment of this element if it is highlighted (can be overwritten)
def DrawHighlightment(self, dc):
scalex, scaley = dc.GetUserScale()
@@ -646,13 +646,13 @@
dc.SetPen(MiterPen(HIGHLIGHTCOLOR))
dc.SetBrush(wx.Brush(HIGHLIGHTCOLOR))
dc.SetLogicalFunction(wx.AND)
- dc.DrawRectangle(int(round((self.Pos.x - 1) * scalex)) - 2,
- int(round((self.Pos.y - 1) * scaley)) - 2,
- int(round((self.Size.width + 3) * scalex)) + 5,
+ dc.DrawRectangle(int(round((self.Pos.x - 1) * scalex)) - 2,
+ int(round((self.Pos.y - 1) * scaley)) - 2,
+ int(round((self.Size.width + 3) * scalex)) + 5,
int(round((self.Size.height + 3) * scaley)) + 5)
dc.SetLogicalFunction(wx.COPY)
dc.SetUserScale(scalex, scaley)
-
+
# Draws the handles of this element if it is selected
def Draw(self, dc):
if not getattr(dc, "printing", False):
@@ -663,20 +663,20 @@
dc.SetUserScale(1, 1)
dc.SetPen(MiterPen(wx.BLACK))
dc.SetBrush(wx.BLACK_BRUSH)
-
+
left = (self.BoundingBox.x - 2) * scalex - HANDLE_SIZE
center = (self.BoundingBox.x + self.BoundingBox.width / 2) * scalex - HANDLE_SIZE / 2
right = (self.BoundingBox.x + self.BoundingBox.width + 2) * scalex
-
+
top = (self.BoundingBox.y - 2) * scaley - HANDLE_SIZE
middle = (self.BoundingBox.y + self.BoundingBox.height / 2) * scaley - HANDLE_SIZE / 2
bottom = (self.BoundingBox.y + self.BoundingBox.height + 2) * scaley
-
+
for x, y in [(left, top), (center, top), (right, top),
(left, middle), (right, middle),
(left, bottom), (center, bottom), (right, bottom)]:
dc.DrawRectangle(x, y, HANDLE_SIZE, HANDLE_SIZE)
-
+
dc.SetUserScale(scalex, scaley)
@@ -689,27 +689,27 @@
"""
class Graphic_Group(Graphic_Element):
-
+
# Create a new group of graphic elements
def __init__(self, parent):
Graphic_Element.__init__(self, parent)
self.Elements = []
self.RefreshWireExclusion()
self.RefreshBoundingBox()
-
+
# Destructor
def __del__(self):
self.Elements = []
-
+
def GetDefinition(self):
- blocks = []
+ blocks = []
wires = []
for element in self.Elements:
block, wire = element.GetDefinition()
blocks.extend(block)
wires.extend(wire)
return blocks, wires
-
+
# Make a clone of this element
def Clone(self, parent, pos = None):
group = Graphic_Group(parent)
@@ -751,20 +751,20 @@
if not isinstance(element, Wire):
parent.AddBlockInModel(element)
return group
-
+
def CanAddBlocks(self, parent):
valid = True
for element in self.Elements:
if not isinstance(element, Wire):
valid &= parent.CanAddElement(element)
return valid
-
+
def IsVisible(self):
for element in self.Elements:
if element.IsVisible():
return True
return False
-
+
# Refresh the list of wire excluded
def RefreshWireExclusion(self):
self.WireExcluded = []
@@ -774,7 +774,7 @@
endblock = element.EndConnected.GetParentBlock()
if startblock in self.Elements and endblock in self.Elements:
self.WireExcluded.append(element)
-
+
# Returns the RedrawRect
def GetRedrawRect(self, movex = 0, movey = 0):
rect = None
@@ -784,41 +784,41 @@
else:
rect = rect.Union(element.GetRedrawRect(movex, movey))
return rect
-
+
# Clean this group of elements
def Clean(self):
# Clean all the elements of the group
for element in self.Elements:
element.Clean()
-
+
# Delete this group of elements
def Delete(self):
# Delete all the elements of the group
for element in self.Elements:
element.Delete()
self.WireExcluded = []
-
+
# Returns if the point given is in the bounding box of one of the elements of this group
def HitTest(self, pt, connectors=True):
result = False
for element in self.Elements:
result |= element.HitTest(pt, connectors)
return result
-
+
# Returns if the element given is in this group
def IsElementIn(self, element):
return element in self.Elements
-
+
# Change the elements of the group
def SetElements(self, elements):
self.Elements = elements
self.RefreshWireExclusion()
self.RefreshBoundingBox()
-
+
# Returns the elements of the group
def GetElements(self):
return self.Elements
-
+
# Align the group elements
def AlignElements(self, horizontally, vertically):
minx = self.BoundingBox.x + self.BoundingBox.width
@@ -854,11 +854,11 @@
element.Move(movex, movey)
element.RefreshModel()
self.RefreshBoundingBox()
-
+
# Add the given element to the group of elements
def AddElement(self, element):
self.Elements.append(element)
-
+
# Remove or select the given element if it is or not in the group
def SelectElement(self, element):
if element in self.Elements:
@@ -867,7 +867,7 @@
self.Elements.append(element)
self.RefreshWireExclusion()
self.RefreshBoundingBox()
-
+
# Move this group of elements
def Move(self, movex, movey):
movex = max(-self.BoundingBox.x, movex)
@@ -879,7 +879,7 @@
elif element in self.WireExcluded:
element.Move(movex, movey, True)
self.RefreshBoundingBox()
-
+
# Refreshes the bounding box of this group of elements
def RefreshBoundingBox(self):
if len(self.Elements) > 0:
@@ -902,7 +902,7 @@
# Forbids to change the group position
def SetPosition(x, y):
pass
-
+
# Returns the position of this group
def GetPosition(self, exclude_wires=False):
if exclude_wires:
@@ -919,15 +919,15 @@
return 0, 0
return posx, posy
return self.BoundingBox.x, self.BoundingBox.y
-
+
# Forbids to change the group size
def SetSize(width, height):
pass
-
+
# Returns the size of this group
def GetSize(self):
return self.BoundingBox.width, self.BoundingBox.height
-
+
# Set size of the group elements to their minimum size
def SetBestSize(self, scaling):
max_movex = max_movey = 0
@@ -936,7 +936,7 @@
max_movex = max(max_movex, movex)
max_movey = max(max_movey, movey)
return max_movex, max_movey
-
+
# Refreshes the group elements to move defined and handle selected
def ProcessDragging(self, movex, movey, event, scaling):
handle_type, handle = self.Handle
@@ -960,17 +960,17 @@
self.Move(movex, movey)
return movex, movey
return 0, 0
-
+
# Change the variable that indicates if this element is highlighted
def SetHighlighted(self, highlighted):
for element in self.Elements:
element.SetHighlighted(highlighted)
-
+
def HighlightPoint(self, pos):
for element in self.Elements:
if isinstance(element, Wire):
element.HighlightPoint(pos)
-
+
# Method called when a LeftDown event have been generated
def OnLeftDown(self, event, dc, scaling):
Graphic_Element.OnLeftDown(self, event, dc, scaling)
@@ -1007,7 +1007,7 @@
"""
class Connector(DebugDataConsumer, ToolTipProducer):
-
+
# Create a new connector
def __init__(self, parent, name, type, position, direction, negated = False, edge = "none", onlyone = False):
DebugDataConsumer.__init__(self)
@@ -1033,13 +1033,13 @@
self.Selected = False
self.Highlights = []
self.RefreshNameSize()
-
+
def Flush(self):
self.ParentBlock = None
for wire, handle in self.Wires:
wire.Flush()
self.Wires = []
-
+
# Returns the RedrawRect
def GetRedrawRect(self, movex = 0, movey = 0):
parent_pos = self.ParentBlock.GetPosition()
@@ -1072,22 +1072,22 @@
height * (self.Direction[1] - 1),
width, height))
return rect
-
+
# Change the connector selection
def SetSelected(self, selected):
self.Selected = selected
-
+
# Make a clone of the connector
def Clone(self, parent = None):
if parent is None:
parent = self.ParentBlock
return Connector(parent, self.Name, self.Type, wx.Point(self.Pos[0], self.Pos[1]),
self.Direction, self.Negated)
-
+
# Returns the connector parent block
def GetParentBlock(self):
return self.ParentBlock
-
+
# Returns the connector type
def GetType(self, raw = False):
if self.ParentBlock.IsEndType(self.Type) or raw:
@@ -1096,7 +1096,7 @@
return "BOOL"
else:
return self.ParentBlock.GetConnectionResultType(self, self.Type)
-
+
# Returns the connector type
def GetConnectedType(self):
if self.ParentBlock.IsEndType(self.Type):
@@ -1104,7 +1104,7 @@
elif len(self.Wires) == 1:
return self.Wires[0][0].GetOtherConnectedType(self.Wires[0][1])
return self.Type
-
+
# Returns the connector type
def GetConnectedRedrawRect(self, movex, movey):
rect = None
@@ -1114,22 +1114,22 @@
else:
rect = rect.Union(wire.GetRedrawRect())
return rect
-
+
# Returns if connector type is compatible with type given
def IsCompatible(self, type):
reference = self.GetType()
return self.ParentBlock.IsOfType(type, reference) or self.ParentBlock.IsOfType(reference, type)
-
+
# Changes the connector name
def SetType(self, type):
self.Type = type
for wire, handle in self.Wires:
wire.SetValid(wire.IsConnectedCompatible())
-
+
# Returns the connector name
def GetName(self):
return self.Name
-
+
# Changes the connector name
def SetName(self, name):
self.Name = name
@@ -1140,15 +1140,15 @@
self.Forced = forced
if self.Visible:
self.Parent.ElementNeedRefresh(self)
-
+
def GetComputedValue(self):
if self.Value is not None and self.Value != "undefined" and not isinstance(self.Value, BooleanType):
return self.Value
return None
-
+
def GetToolTipValue(self):
return self.GetComputedValue()
-
+
def SetValue(self, value):
if self.Value != value:
self.Value = value
@@ -1161,7 +1161,7 @@
self.ValueSize = None
if self.ParentBlock.Visible:
self.ParentBlock.Parent.ElementNeedRefresh(self)
-
+
def RefreshForced(self):
self.Forced = False
for wire, handle in self.Wires:
@@ -1169,12 +1169,12 @@
def RefreshValue(self):
self.Value = self.ReceivingCurrent()
-
+
def RefreshValid(self):
self.Valid = True
for wire, handle in self.Wires:
self.Valid &= wire.GetValid()
-
+
def ReceivingCurrent(self):
current = False
for wire, handle in self.Wires:
@@ -1184,34 +1184,34 @@
elif value == "undefined":
current = "undefined"
return current
-
+
def SpreadCurrent(self, spreading):
for wire, handle in self.Wires:
wire.SetValue(spreading)
-
+
# Changes the connector name size
def RefreshNameSize(self):
if self.Name != "":
self.NameSize = self.ParentBlock.Parent.GetTextExtent(self.Name)
else:
self.NameSize = 0, 0
-
+
# Returns the connector name size
def GetNameSize(self):
return self.NameSize
-
+
# Returns the wires connected to the connector
def GetWires(self):
return self.Wires
-
+
# Returns the parent block Id
def GetBlockId(self):
return self.ParentBlock.GetId()
-
+
# Returns the connector relative position
def GetRelPosition(self):
return self.Pos
-
+
# Returns the connector absolute position
def GetPosition(self, size = True):
parent_pos = self.ParentBlock.GetPosition()
@@ -1223,23 +1223,23 @@
x = parent_pos[0] + self.Pos.x
y = parent_pos[1] + self.Pos.y
return wx.Point(x, y)
-
+
# Change the connector relative position
def SetPosition(self, pos):
self.Pos = pos
-
+
# Returns the connector direction
def GetDirection(self):
return self.Direction
-
+
# Change the connector direction
def SetDirection(self, direction):
self.Direction = direction
-
+
# Connect a wire to this connector at the last place
def Connect(self, wire, refresh = True):
self.InsertConnect(len(self.Wires), wire, refresh)
-
+
# Connect a wire to this connector at the place given
def InsertConnect(self, idx, wire, refresh = True):
if wire not in self.Wires:
@@ -1250,14 +1250,14 @@
wire[0].ConnectEndPoint(None, self)
if refresh:
self.ParentBlock.RefreshModel(False)
-
+
# Returns the index of the wire given in the list of connected
def GetWireIndex(self, wire):
for i, (tmp_wire, handle) in enumerate(self.Wires):
if tmp_wire == wire:
return i
return None
-
+
# Unconnect a wire or all wires connected to the connector
def UnConnect(self, wire = None, unconnect = True, delete = False):
i = 0
@@ -1281,11 +1281,11 @@
if not delete:
self.RefreshValid()
self.ParentBlock.RefreshModel(False)
-
+
# Returns if connector has one or more wire connected
def IsConnected(self):
return len(self.Wires) > 0
-
+
# Move the wires connected
def MoveConnected(self, exclude = []):
if len(self.Wires) > 0:
@@ -1300,21 +1300,21 @@
wire.MoveStartPoint(wx.Point(x, y))
else:
wire.MoveEndPoint(wx.Point(x, y))
-
+
# Refreshes the model of all the wires connected
def RefreshWires(self):
for wire in self.Wires:
wire[0].RefreshModel()
-
+
# Refreshes the parent block model
def RefreshParentBlock(self):
self.ParentBlock.RefreshModel(False)
-
+
# Highlight the parent block
def HighlightParentBlock(self, highlight):
self.ParentBlock.SetHighlighted(highlight)
self.ParentBlock.Refresh()
-
+
# Returns all the blocks connected to this connector
def GetConnectedBlocks(self):
blocks = []
@@ -1330,31 +1330,31 @@
if block not in blocks:
blocks.append(block)
return blocks
-
+
# Returns the connector negated property
def IsNegated(self):
return self.Negated
-
+
# Changes the connector negated property
def SetNegated(self, negated):
if self.ParentBlock.IsOfType("BOOL", self.Type):
self.Negated = negated
self.Edge = "none"
-
+
# Returns the connector edge property
def GetEdge(self):
return self.Edge
-
+
# Changes the connector edge property
def SetEdge(self, edge):
if self.ParentBlock.IsOfType("BOOL", self.Type):
- self.Edge = edge
+ self.Edge = edge
self.Negated = False
-
+
# assume that pointer is already inside of this connector
def ConnectionAvailable(self, direction=None, exclude=True):
wire_nums = len(self.Wires)
-
+
connector_free = (wire_nums<= 0)
connector_max_used = ((wire_nums > 0) and self.OneConnected)
if (self.Parent.CurrentLanguage in ["SFC", "LD"]) and (self.Type == "BOOL"):
@@ -1363,7 +1363,7 @@
# connector is available for new connection
connect = connector_free or not connector_max_used
return connect, connector_max_used
-
+
# Tests if the point given is near from the end point of this connector
def TestPoint(self, pt, direction=None, exclude=True):
inside = False;
@@ -1378,9 +1378,9 @@
height = ANCHOR_DISTANCE * 2 + abs(self.Direction[1]) * CONNECTOR_SIZE
rect = wx.Rect(x, y, width, height)
inside = rect.InsideXY(pt.x, pt.y);
-
+
return inside
-
+
# Draws the highlightment of this element if it is highlighted
def DrawHighlightment(self, dc):
scalex, scaley = dc.GetUserScale()
@@ -1393,7 +1393,7 @@
parent_pos = self.ParentBlock.GetPosition()
posx = parent_pos[0] + self.Pos.x
posy = parent_pos[1] + self.Pos.y
- xstart = parent_pos[0] + self.Pos.x
+ xstart = parent_pos[0] + self.Pos.x
ystart = parent_pos[1] + self.Pos.y
if self.Direction[0] < 0:
xstart += 1
@@ -1401,18 +1401,18 @@
ystart += 1
xend = xstart + CONNECTOR_SIZE * self.Direction[0]
yend = ystart + CONNECTOR_SIZE * self.Direction[1]
- dc.DrawLine(round((xstart + self.Direction[0]) * scalex), round((ystart + self.Direction[1]) * scaley),
+ dc.DrawLine(round((xstart + self.Direction[0]) * scalex), round((ystart + self.Direction[1]) * scaley),
round(xend * scalex), round(yend * scaley))
dc.SetLogicalFunction(wx.COPY)
dc.SetUserScale(scalex, scaley)
-
+
# Adds an highlight to the connector
def AddHighlight(self, infos, start, end, highlight_type):
if highlight_type == ERROR_HIGHLIGHT:
for wire, handle in self.Wires:
wire.SetValid(False)
AddHighlight(self.Highlights, (start, end, highlight_type))
-
+
# Removes an highlight from the connector
def RemoveHighlight(self, infos, start, end, highlight_type):
error = False
@@ -1425,7 +1425,7 @@
if not error:
for wire, handle in self.Wires:
wire.SetValid(wire.IsConnectedCompatible())
-
+
# Removes all the highlights of one particular type from the connector
def ClearHighlight(self, highlight_type=None):
error = False
@@ -1441,7 +1441,7 @@
if not error:
for wire, handle in self.Wires:
wire.SetValid(wire.IsConnectedCompatible())
-
+
# Draws the connector
def Draw(self, dc):
if self.Selected:
@@ -1466,19 +1466,19 @@
dc.SetPen(MiterPen(wx.BLACK))
dc.SetBrush(wx.WHITE_BRUSH)
parent_pos = self.ParentBlock.GetPosition()
-
+
if getattr(dc, "printing", False):
name_size = dc.GetTextExtent(self.Name)
else:
name_size = self.NameSize
-
+
if self.Negated:
# If connector is negated, draw a circle
xcenter = parent_pos[0] + self.Pos.x + (CONNECTOR_SIZE * self.Direction[0]) / 2
ycenter = parent_pos[1] + self.Pos.y + (CONNECTOR_SIZE * self.Direction[1]) / 2
dc.DrawCircle(xcenter, ycenter, CONNECTOR_SIZE / 2)
else:
- xstart = parent_pos[0] + self.Pos.x
+ xstart = parent_pos[0] + self.Pos.x
ystart = parent_pos[1] + self.Pos.y
if self.Edge == "rising":
# If connector has a rising edge, draw a right arrow
@@ -1524,7 +1524,7 @@
self.ValueSize = self.ParentBlock.Parent.GetMiniTextExtent(self.ComputedValue)
if self.ValueSize is not None:
width, height = self.ValueSize
- dc.DrawText(self.ComputedValue,
+ dc.DrawText(self.ComputedValue,
parent_pos[0] + self.Pos.x + CONNECTOR_SIZE * self.Direction[0] + \
width * (self.Direction[0] - 1) / 2,
parent_pos[1] + self.Pos.y + CONNECTOR_SIZE * self.Direction[1] + \
@@ -1541,7 +1541,7 @@
"""
class Wire(Graphic_Element, DebugDataConsumer):
-
+
# Create a new wire
def __init__(self, parent, start = None, end = None):
Graphic_Element.__init__(self, parent)
@@ -1568,18 +1568,18 @@
self.ComputingType = False
self.Font = parent.GetMiniFont()
self.ErrHighlight = False
-
+
def GetDefinition(self):
if self.StartConnected is not None and self.EndConnected is not None:
startblock = self.StartConnected.GetParentBlock()
endblock = self.EndConnected.GetParentBlock()
return [], [(startblock.GetId(), endblock.GetId())]
return [], []
-
+
def Flush(self):
self.StartConnected = None
self.EndConnected = None
-
+
# Returns the RedrawRect
def GetRedrawRect(self, movex = 0, movey = 0):
rect = Graphic_Element.GetRedrawRect(self, movex, movey)
@@ -1607,7 +1607,7 @@
y = self.Points[middle].y - height
rect = rect.Union(wx.Rect(x, y, width, height))
return rect
-
+
def Clone(self, parent, connectors = {}, dx = 0, dy = 0):
start_connector = connectors.get(self.StartConnected, None)
end_connector = connectors.get(self.EndConnected, None)
@@ -1620,18 +1620,18 @@
wire.ConnectEndPoint(end_connector.GetPosition(), end_connector)
return wire
return None
-
+
# Forbids to change the wire position
def SetPosition(x, y):
pass
-
+
# Forbids to change the wire size
def SetSize(width, height):
pass
-
+
# Forbids to et size of the group elements to their minimum size
pass
-
+
# Moves and Resizes the element for fitting scaling
def SetBestSize(self, scaling):
if scaling is not None:
@@ -1664,11 +1664,11 @@
point.y += movey
return movex_max, movey_max
return 0, 0
-
+
# Returns connector to which start point is connected
def GetStartConnected(self):
return self.StartConnected
-
+
# Returns connector to which start point is connected
def GetStartConnectedType(self):
if self.StartConnected and not self.ComputingType:
@@ -1677,11 +1677,11 @@
self.ComputingType = False
return computed_type
return None
-
+
# Returns connector to which end point is connected
def GetEndConnected(self):
return self.EndConnected
-
+
# Returns connector to which end point is connected
def GetEndConnectedType(self):
if self.EndConnected and not self.ComputingType:
@@ -1690,7 +1690,7 @@
self.ComputingType = False
return computed_type
return None
-
+
def GetConnectionDirection(self):
if self.StartConnected is None and self.EndConnected is None:
return None
@@ -1707,26 +1707,26 @@
else:
return (-self.StartPoint[1][0], -self.StartPoint[1][1])
return None
-
+
def GetOtherConnected(self, connector):
if self.StartConnected == connector:
return self.EndConnected
else:
return self.StartConnected
-
+
def GetOtherConnectedType(self, handle):
if handle == 0:
return self.GetEndConnectedType()
else:
return self.GetStartConnectedType()
-
+
def IsConnectedCompatible(self):
if self.StartConnected:
return self.StartConnected.IsCompatible(self.GetEndConnectedType())
elif self.EndConnected:
return True
return False
-
+
def SetForced(self, forced):
if self.Forced != forced:
self.Forced = forced
@@ -1741,7 +1741,7 @@
if self.Value is not None and self.Value != "undefined" and not isinstance(self.Value, BooleanType):
return self.Value
return None
-
+
def GetToolTipValue(self):
return self.GetComputedValue()
@@ -1773,18 +1773,18 @@
if isinstance(value, BooleanType) and self.StartConnected is not None:
block = self.StartConnected.GetParentBlock()
block.SpreadCurrent()
-
+
# Unconnect the start and end points
def Clean(self):
if self.StartConnected:
self.UnConnectStartPoint()
if self.EndConnected:
self.UnConnectEndPoint()
-
+
# Delete this wire by calling the corresponding method
def Delete(self):
self.Parent.DeleteWire(self)
-
+
# Select a segment and not the whole wire. It's useful for Ladder Diagram
def SetSelectedSegment(self, segment):
# The last segment is indicated
@@ -1814,17 +1814,17 @@
self.EndConnected.SetSelected(True)
self.SelectedSegment = segment
self.Refresh()
-
+
def SetValid(self, valid):
self.Valid = valid
if self.StartConnected:
self.StartConnected.RefreshValid()
if self.EndConnected:
self.EndConnected.RefreshValid()
-
+
def GetValid(self):
return self.Valid
-
+
# Reinitialize the wire points
def ResetPoints(self):
if self.StartPoint and self.EndPoint:
@@ -1833,7 +1833,7 @@
else:
self.Points = []
self.Segments = []
-
+
# Refresh the wire bounding box
def RefreshBoundingBox(self):
if len(self.Points) > 0:
@@ -1862,7 +1862,7 @@
self.Pos.x, self.Pos.y = minx, miny
self.Size = wx.Size(maxx - minx, maxy - miny)
self.BoundingBox = wx.Rect(minbbxx, minbbxy, maxbbxx - minbbxx + 1, maxbbxy - minbbxy + 1)
-
+
# Refresh the realpoints that permits to keep the proportionality in wire during resizing
def RefreshRealPoints(self):
if len(self.Points) > 0:
@@ -1870,8 +1870,8 @@
# Calculate float relative position of each point with the minimum point
for point in self.Points:
self.RealPoints.append([float(point.x - self.Pos.x), float(point.y - self.Pos.y)])
-
- # Returns the wire minimum size
+
+ # Returns the wire minimum size
def GetMinSize(self):
width = 1
height = 1
@@ -1893,7 +1893,7 @@
width = MIN_SEGMENT_SIZE
height = MIN_SEGMENT_SIZE
return width + 1, height + 1
-
+
# Returns if the point given is on one of the wire segments
def HitTest(self, pt, connectors=True):
test = False
@@ -1903,7 +1903,7 @@
x1 = self.Points[i].x - self.Segments[0][0] * CONNECTOR_SIZE
y1 = self.Points[i].y - self.Segments[0][1] * CONNECTOR_SIZE
else:
- x1, y1 = self.Points[i].x, self.Points[i].y
+ x1, y1 = self.Points[i].x, self.Points[i].y
if i == len(self.Points) - 2 and self.EndConnected is not None:
x2 = self.Points[i + 1].x + self.Segments[-1][0] * CONNECTOR_SIZE
y2 = self.Points[i + 1].y + self.Segments[-1][1] * CONNECTOR_SIZE
@@ -1912,10 +1912,10 @@
# Calculate a rectangle around the segment
rect = wx.Rect(min(x1, x2) - ANCHOR_DISTANCE, min(y1, y2) - ANCHOR_DISTANCE,
abs(x1 - x2) + 2 * ANCHOR_DISTANCE, abs(y1 - y2) + 2 * ANCHOR_DISTANCE)
- test |= rect.InsideXY(pt.x, pt.y)
+ test |= rect.InsideXY(pt.x, pt.y)
return test
-
- # Returns the wire start or end point if the point given is on one of them
+
+ # Returns the wire start or end point if the point given is on one of them
def TestPoint(self, pt):
# Test the wire start point
rect = wx.Rect(self.Points[0].x - ANCHOR_DISTANCE, self.Points[0].y - ANCHOR_DISTANCE,
@@ -1929,7 +1929,7 @@
if rect.InsideXY(pt.x, pt.y):
return -1
return None
-
+
# Returns the wire segment if the point given is on it
def TestSegment(self, pt, all=False):
for i in xrange(len(self.Segments)):
@@ -1943,7 +1943,7 @@
if rect.InsideXY(pt.x, pt.y):
return i, self.Segments[i]
return None
-
+
# Define the wire points
def SetPoints(self, points, verify=True):
if len(points) > 1:
@@ -1952,9 +1952,9 @@
self.StartPoint = [None, vector(self.Points[0], self.Points[1])]
self.EndPoint = [None, vector(self.Points[-1], self.Points[-2])]
# Calculate the start and end points
- self.StartPoint[0] = wx.Point(self.Points[0].x + CONNECTOR_SIZE * self.StartPoint[1][0],
+ self.StartPoint[0] = wx.Point(self.Points[0].x + CONNECTOR_SIZE * self.StartPoint[1][0],
self.Points[0].y + CONNECTOR_SIZE * self.StartPoint[1][1])
- self.EndPoint[0] = wx.Point(self.Points[-1].x + CONNECTOR_SIZE * self.EndPoint[1][0],
+ self.EndPoint[0] = wx.Point(self.Points[-1].x + CONNECTOR_SIZE * self.EndPoint[1][0],
self.Points[-1].y + CONNECTOR_SIZE * self.EndPoint[1][1])
self.Points[0] = self.StartPoint[0]
self.Points[-1] = self.EndPoint[0]
@@ -1979,37 +1979,37 @@
i += 1
self.RefreshBoundingBox()
self.RefreshRealPoints()
-
+
# Returns the position of the point indicated
def GetPoint(self, index):
if index < len(self.Points):
return self.Points[index].x, self.Points[index].y
return None
-
+
# Returns a list of the position of all wire points
def GetPoints(self, invert = False):
points = self.VerifyPoints()
- points[0] = wx.Point(points[0].x - CONNECTOR_SIZE * self.StartPoint[1][0],
+ points[0] = wx.Point(points[0].x - CONNECTOR_SIZE * self.StartPoint[1][0],
points[0].y - CONNECTOR_SIZE * self.StartPoint[1][1])
- points[-1] = wx.Point(points[-1].x - CONNECTOR_SIZE * self.EndPoint[1][0],
+ points[-1] = wx.Point(points[-1].x - CONNECTOR_SIZE * self.EndPoint[1][0],
points[-1].y - CONNECTOR_SIZE * self.EndPoint[1][1])
# An inversion of the list is asked
if invert:
points.reverse()
return points
-
+
# Returns the position of the two selected segment points
def GetSelectedSegmentPoints(self):
if self.SelectedSegment != None and len(self.Points) > 1:
return self.Points[self.SelectedSegment:self.SelectedSegment + 2]
return []
-
+
# Returns if the selected segment is the first and/or the last of the wire
def GetSelectedSegmentConnections(self):
if self.SelectedSegment != None and len(self.Points) > 1:
return self.SelectedSegment == 0, self.SelectedSegment == len(self.Segments) - 1
return (True, True)
-
+
# Returns the connectors on which the wire is connected
def GetConnected(self):
connected = []
@@ -2018,7 +2018,7 @@
if self.EndConnected and self.EndPoint[1] == WEST:
connected.append(self.EndConnected)
return connected
-
+
# Returns the id of the block connected to the first or the last wire point
def GetConnectedInfos(self, index):
if index == 0 and self.StartConnected:
@@ -2026,14 +2026,14 @@
elif index == -1 and self.EndConnected:
return self.EndConnected.GetBlockId(), self.EndConnected.GetName()
return None
-
+
# Update the wire points position by keeping at most possible the current positions
def GeneratePoints(self, realpoints = True):
i = 0
# Calculate the start enad end points with the minimum segment size in the right direction
end = wx.Point(self.EndPoint[0].x + self.EndPoint[1][0] * MIN_SEGMENT_SIZE,
self.EndPoint[0].y + self.EndPoint[1][1] * MIN_SEGMENT_SIZE)
- start = wx.Point(self.StartPoint[0].x + self.StartPoint[1][0] * MIN_SEGMENT_SIZE,
+ start = wx.Point(self.StartPoint[0].x + self.StartPoint[1][0] * MIN_SEGMENT_SIZE,
self.StartPoint[0].y + self.StartPoint[1][1] * MIN_SEGMENT_SIZE)
# Evaluate the point till it's the last
while i < len(self.Points) - 1:
@@ -2046,14 +2046,14 @@
# If the end point is not in the start direction, a point is added
if v_end != self.Segments[0] or v_end == self.EndPoint[1]:
self.Points.insert(1, wx.Point(start.x, start.y))
- self.Segments.insert(1, DirectionChoice((self.Segments[0][1],
+ self.Segments.insert(1, DirectionChoice((self.Segments[0][1],
self.Segments[0][0]), v_end, self.EndPoint[1]))
# The current point is the second
elif i == 1:
# The previous direction and the target direction are mainly opposed, a point is added
if product(v_end, self.Segments[0]) < 0:
self.Points.insert(2, wx.Point(self.Points[1].x, self.Points[1].y))
- self.Segments.insert(2, DirectionChoice((self.Segments[1][1],
+ self.Segments.insert(2, DirectionChoice((self.Segments[1][1],
self.Segments[1][0]), v_end, self.EndPoint[1]))
# The previous direction and the end direction are the same or they are
# perpendiculars and the end direction points towards current segment
@@ -2066,7 +2066,7 @@
# If the previous direction and the end direction are the same, a point is added
if product(self.Segments[0], self.EndPoint[1]) > 0:
self.Points.insert(2, wx.Point(self.Points[1].x, self.Points[1].y))
- self.Segments.insert(2, DirectionChoice((self.Segments[1][1],
+ self.Segments.insert(2, DirectionChoice((self.Segments[1][1],
self.Segments[1][0]), v_end, self.EndPoint[1]))
else:
# Current point is positioned in the middle of start point
@@ -2076,7 +2076,7 @@
if self.Segments[0][1] != 0:
self.Points[1].y = (end.y + start.y) / 2
self.Points.insert(2, wx.Point(self.Points[1].x, self.Points[1].y))
- self.Segments.insert(2, DirectionChoice((self.Segments[1][1],
+ self.Segments.insert(2, DirectionChoice((self.Segments[1][1],
self.Segments[1][0]), v_end, self.EndPoint[1]))
else:
# The previous direction and the end direction are perpendiculars
@@ -2093,7 +2093,7 @@
self.Segments[i - 1] = (-self.Segments[i - 1][0], -self.Segments[i - 1][1])
else:
test = True
- # If the current point is the third, test if the second
+ # If the current point is the third, test if the second
# point can be aligned with the end point
if i == 2:
test_point = wx.Point(self.Points[1].x, self.Points[1].y)
@@ -2119,7 +2119,7 @@
if self.Segments[1][1] != 0:
self.Points[2].y = (self.Points[1].y + end.y) / 2
self.Points.insert(3, wx.Point(self.Points[2].x, self.Points[2].y))
- self.Segments.insert(3, DirectionChoice((self.Segments[2][1],
+ self.Segments.insert(3, DirectionChoice((self.Segments[2][1],
self.Segments[2][0]), v_end, self.EndPoint[1]))
else:
# Current point is aligned with end point
@@ -2140,15 +2140,15 @@
self.Points[i].y = (end.y + self.Points[i - 1].y) / 2
# A point is added
self.Points.insert(i + 1, wx.Point(self.Points[i].x, self.Points[i].y))
- self.Segments.insert(i + 1, DirectionChoice((self.Segments[i][1],
+ self.Segments.insert(i + 1, DirectionChoice((self.Segments[i][1],
self.Segments[i][0]), v_end, self.EndPoint[1]))
else:
# Current point is the first, and second is not mainly in the first direction
if i == 0 and product(vector(start, self.Points[1]), self.Segments[0]) < 0:
- # If first and second directions aren't perpendiculars, a point is added
+ # If first and second directions aren't perpendiculars, a point is added
if product(self.Segments[0], self.Segments[1]) != 0:
self.Points.insert(1, wx.Point(start.x, start.y))
- self.Segments.insert(1, DirectionChoice((self.Segments[0][1],
+ self.Segments.insert(1, DirectionChoice((self.Segments[0][1],
self.Segments[0][0]), vector(start, self.Points[1]), self.Segments[1]))
else:
self.Points[1].x, self.Points[1].y = start.x, start.y
@@ -2165,7 +2165,7 @@
self.RefreshBoundingBox()
if realpoints:
self.RefreshRealPoints()
-
+
# Verify that two consecutive points haven't the same position
def VerifyPoints(self):
points = [point for point in self.Points]
@@ -2185,7 +2185,7 @@
self.RefreshBoundingBox()
self.RefreshRealPoints()
return points
-
+
# Moves all the wire points except the first and the last if they are connected
def Move(self, dx, dy, endpoints = False):
for i, point in enumerate(self.Points):
@@ -2195,7 +2195,7 @@
self.StartPoint[0] = self.Points[0]
self.EndPoint[0] = self.Points[-1]
self.GeneratePoints()
-
+
# Resize the wire from position and size given
def Resize(self, x, y, width, height):
if len(self.Points) > 1:
@@ -2254,25 +2254,25 @@
self.StartPoint[0] = self.Points[0]
self.EndPoint[0] = self.Points[-1]
self.GeneratePoints(False)
-
+
# Moves the wire start point and update the wire points
def MoveStartPoint(self, point):
if len(self.Points) > 1:
self.StartPoint[0] = point
self.Points[0] = point
self.GeneratePoints()
-
+
# Changes the wire start direction and update the wire points
def SetStartPointDirection(self, dir):
if len(self.Points) > 1:
self.StartPoint[1] = dir
self.Segments[0] = dir
self.GeneratePoints()
-
+
# Rotates the wire start direction by an angle of 90 degrees anticlockwise
def RotateStartPoint(self):
self.SetStartPointDirection((self.StartPoint[1][1], -self.StartPoint[1][0]))
-
+
# Connects wire start point to the connector given and moves wire start point
# to given point
def ConnectStartPoint(self, point, connector):
@@ -2280,7 +2280,7 @@
self.MoveStartPoint(point)
self.StartConnected = connector
self.RefreshBoundingBox()
-
+
# Unconnects wire start point
def UnConnectStartPoint(self, delete = False):
if delete:
@@ -2290,7 +2290,7 @@
self.StartConnected.UnConnect(self, unconnect = False)
self.StartConnected = None
self.RefreshBoundingBox()
-
+
# Moves the wire end point and update the wire points
def MoveEndPoint(self, point):
if len(self.Points) > 1:
@@ -2303,7 +2303,7 @@
if len(self.Points) > 1:
self.EndPoint[1] = dir
self.GeneratePoints()
-
+
# Rotates the wire end direction by an angle of 90 degrees anticlockwise
def RotateEndPoint(self):
self.SetEndPointDirection((self.EndPoint[1][1], -self.EndPoint[1][0]))
@@ -2315,7 +2315,7 @@
self.MoveEndPoint(point)
self.EndConnected = connector
self.RefreshBoundingBox()
-
+
# Unconnects wire end point
def UnConnectEndPoint(self, delete = False):
if delete:
@@ -2325,7 +2325,7 @@
self.EndConnected.UnConnect(self, unconnect = False)
self.EndConnected = None
self.RefreshBoundingBox()
-
+
# Moves the wire segment given by its index
def MoveSegment(self, idx, movex, movey, scaling):
if 0 < idx < len(self.Segments) - 1:
@@ -2356,7 +2356,7 @@
if start_y != self.Points[idx].y:
return 0, self.Points[idx].y - start_y
return 0, 0
-
+
# Adds two points in the middle of the handled segment
def AddSegment(self):
handle_type, handle = self.Handle
@@ -2391,7 +2391,7 @@
self.Points.insert(segment + 4, wx.Point(p2x, p2y))
self.Segments.insert(segment + 4, dir)
self.GeneratePoints()
-
+
# Delete the handled segment by removing the two segment points
def DeleteSegment(self):
handle_type, handle = self.Handle
@@ -2402,7 +2402,7 @@
self.Segments.pop(segment)
self.GeneratePoints()
self.RefreshModel()
-
+
# Method called when a LeftDown event have been generated
def OnLeftDown(self, event, dc, scaling):
pos = GetScaledEventPosition(event, dc, scaling)
@@ -2424,7 +2424,7 @@
else:
Graphic_Element.OnLeftDown(self, event, dc, scaling)
self.oldPos = pos
-
+
# Method called when a RightUp event has been generated
def OnRightUp(self, event, dc, scaling):
pos = GetScaledEventPosition(event, dc, scaling)
@@ -2437,7 +2437,7 @@
else:
# Execute the default method for a graphic element
Graphic_Element.OnRightUp(self, event, dc, scaling)
-
+
# Method called when a LeftDClick event has been generated
def OnLeftDClick(self, event, dc, scaling):
rect = self.GetRedrawRect()
@@ -2492,7 +2492,7 @@
self.Parent.RefreshBuffer()
rect.Union(self.GetRedrawRect())
self.Parent.RefreshRect(self.Parent.GetScrolledRect(rect), False)
-
+
# Method called when a Motion event has been generated
def OnMotion(self, event, dc, scaling):
pos = GetScaledEventPosition(event, dc, scaling)
@@ -2511,7 +2511,7 @@
else:
# Execute the default method for a graphic element
return Graphic_Element.OnMotion(self, event, dc, scaling)
-
+
# Refreshes the wire state according to move defined and handle selected
def ProcessDragging(self, movex, movey, event, scaling):
handle_type, handle = self.Handle
@@ -2572,14 +2572,14 @@
# Execute the default method for a graphic element
else:
return Graphic_Element.ProcessDragging(self, movex, movey, event, scaling)
-
+
# Refreshes the wire model
def RefreshModel(self, move=True):
if self.StartConnected and self.StartPoint[1] in [WEST, NORTH]:
self.StartConnected.RefreshParentBlock()
if self.EndConnected and self.EndPoint[1] in [WEST, NORTH]:
self.EndConnected.RefreshParentBlock()
-
+
# Change the variable that indicates if this element is highlighted
def SetHighlighted(self, highlighted):
self.Highlighted = highlighted
@@ -2587,7 +2587,7 @@
self.OverStart = False
self.OverEnd = False
self.Refresh()
-
+
def HighlightPoint(self, pos):
refresh = False
start, end = self.OverStart, self.OverEnd
@@ -2602,7 +2602,7 @@
self.OverEnd = True
if start != self.OverStart or end != self.OverEnd:
self.Refresh()
-
+
# Draws the highlightment of this element if it is highlighted
def DrawHighlightment(self, dc):
scalex, scaley = dc.GetUserScale()
@@ -2617,31 +2617,31 @@
dc.SetLogicalFunction(wx.AND)
# Draw the start and end points if they are not connected or the mouse is over them
if len(self.Points) > 0 and (not self.StartConnected or self.OverStart):
- dc.DrawCircle(round(self.Points[0].x * scalex),
- round(self.Points[0].y * scaley),
+ dc.DrawCircle(round(self.Points[0].x * scalex),
+ round(self.Points[0].y * scaley),
(POINT_RADIUS + 1) * scalex + 2)
if len(self.Points) > 1 and (not self.EndConnected or self.OverEnd):
dc.DrawCircle(self.Points[-1].x * scalex, self.Points[-1].y * scaley, (POINT_RADIUS + 1) * scalex + 2)
# Draw the wire lines and the last point (it seems that DrawLines stop before the last point)
if len(self.Points) > 1:
- points = [wx.Point(round((self.Points[0].x - self.Segments[0][0]) * scalex),
+ points = [wx.Point(round((self.Points[0].x - self.Segments[0][0]) * scalex),
round((self.Points[0].y - self.Segments[0][1]) * scaley))]
points.extend([wx.Point(round(point.x * scalex), round(point.y * scaley)) for point in self.Points[1:-1]])
- points.append(wx.Point(round((self.Points[-1].x + self.Segments[-1][0]) * scalex),
+ points.append(wx.Point(round((self.Points[-1].x + self.Segments[-1][0]) * scalex),
round((self.Points[-1].y + self.Segments[-1][1]) * scaley)))
else:
points = []
dc.DrawLines(points)
dc.SetLogicalFunction(wx.COPY)
dc.SetUserScale(scalex, scaley)
-
+
if self.StartConnected is not None:
self.StartConnected.DrawHighlightment(dc)
self.StartConnected.Draw(dc)
if self.EndConnected is not None:
self.EndConnected.DrawHighlightment(dc)
self.EndConnected.Draw(dc)
-
+
# Draws the wire lines and points
def Draw(self, dc):
Graphic_Element.Draw(self, dc)
@@ -2750,7 +2750,7 @@
self.Pos = wx.Point(0, 0)
self.Size = wx.Size(0, 0)
self.Highlights = []
-
+
# Make a clone of this comment
def Clone(self, parent, id = None, pos = None):
comment = Comment(parent, self.Content, id)
@@ -2758,19 +2758,19 @@
comment.SetPosition(pos.x, pos.y)
comment.SetSize(self.Size[0], self.Size[1])
return comment
-
+
# Method for keeping compatibility with others
def Clean(self):
pass
-
+
# Delete this comment by calling the corresponding method
def Delete(self):
self.Parent.DeleteComment(self)
-
+
# Refresh the comment bounding box
def RefreshBoundingBox(self):
self.BoundingBox = wx.Rect(self.Pos.x, self.Pos.y, self.Size[0] + 1, self.Size[1] + 1)
-
+
# Changes the comment size
def SetSize(self, width, height):
self.Size.SetWidth(width)
@@ -2780,7 +2780,7 @@
# Returns the comment size
def GetSize(self):
return self.Size.GetWidth(), self.Size.GetHeight()
-
+
# Returns the comment minimum size
def GetMinSize(self):
dc = wx.ClientDC(self.Parent)
@@ -2793,7 +2793,7 @@
min_width = max(min_width, wordwidth)
min_height = max(min_height, wordheight)
return min_width + 20, min_height + 20
-
+
# Changes the comment position
def SetPosition(self, x, y):
self.Pos.x = x
@@ -2815,51 +2815,51 @@
# Returns the comment position
def GetPosition(self):
return self.Pos.x, self.Pos.y
-
+
# Moves the comment
def Move(self, dx, dy, connected = True):
self.Pos.x += dx
self.Pos.y += dy
self.RefreshBoundingBox()
-
+
# Resizes the comment with the position and the size given
def Resize(self, x, y, width, height):
self.Move(x, y)
self.SetSize(width, height)
-
+
# Method called when a RightUp event have been generated
def OnRightUp(self, event, dc, scaling):
# Popup the default menu
self.Parent.PopupDefaultMenu()
-
+
# Refreshes the wire state according to move defined and handle selected
def ProcessDragging(self, movex, movey, event, scaling):
if self.Parent.GetDrawingMode() != FREEDRAWING_MODE and self.Parent.CurrentLanguage == "LD":
movex = movey = 0
return Graphic_Element.ProcessDragging(self, movex, movey, event, scaling)
-
+
# Refreshes the comment model
def RefreshModel(self, move=True):
self.Parent.RefreshCommentModel(self)
-
+
# Method called when a LeftDClick event have been generated
def OnLeftDClick(self, event, dc, scaling):
# Edit the comment content
self.Parent.EditCommentContent(self)
-
+
# Adds an highlight to the comment
def AddHighlight(self, infos, start, end, highlight_type):
if infos[0] == "content":
AddHighlight(self.Highlights, (start, end, highlight_type))
-
+
# Removes an highlight from the comment
def RemoveHighlight(self, infos, start, end, highlight_type):
RemoveHighlight(self.Highlights, (start, end, highlight_type))
-
+
# Removes all the highlights of one particular type from the comment
def ClearHighlight(self, highlight_type=None):
self.Highlights = ClearHighlights(self.Highlights, highlight_type)
-
+
# Draws the highlightment of this element if it is highlighted
def DrawHighlightment(self, dc):
scalex, scaley = dc.GetUserScale()
@@ -2867,29 +2867,29 @@
dc.SetPen(MiterPen(HIGHLIGHTCOLOR))
dc.SetBrush(wx.Brush(HIGHLIGHTCOLOR))
dc.SetLogicalFunction(wx.AND)
-
+
left = (self.Pos.x - 1) * scalex - 2
right = (self.Pos.x + self.Size[0] + 1) * scalex + 2
top = (self.Pos.y - 1) * scaley - 2
bottom = (self.Pos.y + self.Size[1] + 1) * scaley + 2
angle_top = (self.Pos.x + self.Size[0] - 9) * scalex + 2
angle_right = (self.Pos.y + 9) * scaley - 2
-
+
polygon = [wx.Point(left, top), wx.Point(angle_top, top),
wx.Point(right, angle_right), wx.Point(right, bottom),
wx.Point(left, bottom)]
dc.DrawPolygon(polygon)
-
+
dc.SetLogicalFunction(wx.COPY)
dc.SetUserScale(scalex, scaley)
-
+
# Draws the comment and its content
def Draw(self, dc):
Graphic_Element.Draw(self, dc)
dc.SetPen(MiterPen(wx.BLACK))
dc.SetBrush(wx.WHITE_BRUSH)
# Draws the comment shape
- polygon = [wx.Point(self.Pos.x, self.Pos.y),
+ polygon = [wx.Point(self.Pos.x, self.Pos.y),
wx.Point(self.Pos.x + self.Size[0] - 10, self.Pos.y),
wx.Point(self.Pos.x + self.Size[0], self.Pos.y + 10),
wx.Point(self.Pos.x + self.Size[0], self.Pos.y + self.Size[1]),
@@ -2951,4 +2951,3 @@
y += wordheight + 5
if y + wordheight > self.Pos.y + self.Size[1] - 10:
break
-
--- a/graphics/LD_Objects.py Fri Aug 11 15:18:19 2017 +0300
+++ b/graphics/LD_Objects.py Mon Aug 14 19:13:01 2017 +0300
@@ -37,7 +37,7 @@
"""
class LD_PowerRail(Graphic_Element):
-
+
# Create a new power rail
def __init__(self, parent, type, id=None, connectors=1):
Graphic_Element.__init__(self, parent)
@@ -47,12 +47,12 @@
self.Id = id
self.Extensions = [LD_LINE_SIZE / 2, LD_LINE_SIZE / 2]
self.SetType(type, connectors)
-
+
def Flush(self):
for connector in self.Connectors:
connector.Flush()
self.Connectors = []
-
+
# Make a clone of this LD_PowerRail
def Clone(self, parent, id = None, pos = None):
powerrail = LD_PowerRail(parent, self.Type, id)
@@ -65,11 +65,11 @@
for connector in self.Connectors:
powerrail.Connectors.append(connector.Clone(powerrail))
return powerrail
-
+
def GetConnectorTranslation(self, element):
return dict(zip([connector for connector in self.Connectors],
[connector for connector in element.Connectors]))
-
+
# Returns the RedrawRect
def GetRedrawRect(self, movex = 0, movey = 0):
rect = Graphic_Element.GetRedrawRect(self, movex, movey)
@@ -80,7 +80,7 @@
if connector.IsConnected():
rect = rect.Union(connector.GetConnectedRedrawRect(movex, movey))
return rect
-
+
# Forbids to change the power rail size
def SetSize(self, width, height):
if self.Parent.GetDrawingMode() == FREEDRAWING_MODE:
@@ -88,47 +88,47 @@
else:
Graphic_Element.SetSize(self, LD_POWERRAIL_WIDTH, height)
self.RefreshConnectors()
-
+
# Forbids to select a power rail
def HitTest(self, pt, connectors=True):
if self.Parent.GetDrawingMode() == FREEDRAWING_MODE:
return Graphic_Element.HitTest(self, pt, connectors) or self.TestConnector(pt, exclude=False) != None
return False
-
+
# Forbids to select a power rail
def IsInSelection(self, rect):
if self.Parent.GetDrawingMode() == FREEDRAWING_MODE:
return Graphic_Element.IsInSelection(self, rect)
return False
-
+
# Deletes this power rail by calling the appropriate method
def Delete(self):
self.Parent.DeletePowerRail(self)
-
+
# Unconnect all connectors
def Clean(self):
for connector in self.Connectors:
connector.UnConnect(delete = self.Parent.GetDrawingMode() == FREEDRAWING_MODE)
-
+
# Refresh the power rail bounding box
def RefreshBoundingBox(self):
self.BoundingBox = wx.Rect(self.Pos.x, self.Pos.y, self.Size[0] + 1, self.Size[1] + 1)
-
+
# Refresh the power rail size
def RefreshSize(self):
self.Size = wx.Size(LD_POWERRAIL_WIDTH, max(LD_LINE_SIZE * len(self.Connectors), self.Size[1]))
self.RefreshBoundingBox()
-
+
# Returns the block minimum size
def GetMinSize(self, default=False):
height = (LD_LINE_SIZE * (len(self.Connectors) - 1)
if default else 0)
return LD_POWERRAIL_WIDTH, height + self.Extensions[0] + self.Extensions[1]
-
+
# Add a connector or a blank to this power rail at the last place
def AddConnector(self):
self.InsertConnector(len(self.Connectors))
-
+
# Add a connector or a blank to this power rail at the place given
def InsertConnector(self, idx):
if self.Type == LEFTRAIL:
@@ -138,7 +138,7 @@
self.Connectors.insert(idx, connector)
self.RefreshSize()
self.RefreshConnectors()
-
+
# Moves the divergence connector given
def MoveConnector(self, connector, movey):
position = connector.GetRelPosition()
@@ -163,19 +163,19 @@
self.Size[1] = max(maxy + self.Extensions[1], self.Size[1])
connector.MoveConnected()
self.RefreshBoundingBox()
-
+
# Returns the index in connectors list for the connector given
def GetConnectorIndex(self, connector):
if connector in self.Connectors:
return self.Connectors.index(connector)
return None
-
+
# Delete the connector or blank from connectors list at the index given
def DeleteConnector(self, idx):
self.Connectors.pop(idx)
self.RefreshConnectors()
self.RefreshSize()
-
+
# Refresh the positions of the power rail connectors
def RefreshConnectors(self):
scaling = self.Parent.GetScaling()
@@ -193,13 +193,13 @@
elif self.Type == RIGHTRAIL:
connector.SetPosition(wx.Point(0, position))
self.RefreshConnected()
-
+
# Refresh the position of wires connected to power rail
def RefreshConnected(self, exclude = []):
for connector in self.Connectors:
connector.MoveConnected(exclude)
-
- # Returns the power rail connector that starts with the point given if it exists
+
+ # Returns the power rail connector that starts with the point given if it exists
def GetConnector(self, position, name = None):
# if a name is given
if name is not None:
@@ -208,22 +208,22 @@
if name == connector.GetName():
return connector
return self.FindNearestConnector(position, [connector for connector in self.Connectors if connector is not None])
-
- # Returns all the power rail connectors
+
+ # Returns all the power rail connectors
def GetConnectors(self):
connectors = [connector for connector in self.Connectors if connector]
if self.Type == LEFTRAIL:
return {"inputs": [], "outputs": connectors}
else:
return {"inputs": connectors, "outputs": []}
-
+
# Test if point given is on one of the power rail connectors
def TestConnector(self, pt, direction = None, exclude = True):
for connector in self.Connectors:
if connector.TestPoint(pt, direction, exclude):
return connector
return None
-
+
# Returns the power rail type
def SetType(self, type, connectors):
if type != self.Type or len(self.Connectors) != connectors:
@@ -235,11 +235,11 @@
for connector in xrange(connectors):
self.AddConnector()
self.RefreshSize()
-
+
# Returns the power rail type
def GetType(self):
return self.Type
-
+
# Method called when a LeftDown event have been generated
def OnLeftDown(self, event, dc, scaling):
self.RealConnectors = []
@@ -253,12 +253,12 @@
else:
self.RealConnectors = [0.5]
Graphic_Element.OnLeftDown(self, event, dc, scaling)
-
+
# Method called when a LeftUp event have been generated
def OnLeftUp(self, event, dc, scaling):
Graphic_Element.OnLeftUp(self, event, dc, scaling)
self.RealConnectors = None
-
+
# Method called when a LeftDown event have been generated
def OnRightDown(self, event, dc, scaling):
pos = GetScaledEventPosition(event, dc, scaling)
@@ -272,12 +272,12 @@
self.oldPos = GetScaledEventPosition(event, dc, scaling)
else:
Graphic_Element.OnRightDown(self, event, dc, scaling)
-
+
# Method called when a LeftDClick event have been generated
def OnLeftDClick(self, event, dc, scaling):
# Edit the powerrail properties
self.Parent.EditPowerRailContent(self)
-
+
# Method called when a RightUp event have been generated
def OnRightUp(self, event, dc, scaling):
handle_type, handle = self.Handle
@@ -292,7 +292,7 @@
Graphic_Element.OnRightUp(self, event, dc, scaling)
else:
self.Parent.PopupDefaultMenu()
-
+
def Resize(self, x, y, width, height):
self.Move(x, y)
if self.Parent.GetDrawingMode() == FREEDRAWING_MODE:
@@ -314,16 +314,16 @@
elif self.Parent.GetDrawingMode() == FREEDRAWING_MODE:
return Graphic_Element.ProcessDragging(self, movex, movey, event, scaling)
return 0, 0
-
+
# Refreshes the power rail model
def RefreshModel(self, move=True):
self.Parent.RefreshPowerRailModel(self)
- # If power rail has moved and power rail is of type LEFT, refresh the model
+ # If power rail has moved and power rail is of type LEFT, refresh the model
# of wires connected to connectors
if move and self.Type == LEFTRAIL:
for connector in self.Connectors:
connector.RefreshWires()
-
+
# Draws power rail
def Draw(self, dc):
Graphic_Element.Draw(self, dc)
@@ -337,7 +337,7 @@
# Draw connectors
for connector in self.Connectors:
connector.Draw(dc)
-
+
#-------------------------------------------------------------------------------
# Ladder Diagram Contact
@@ -348,7 +348,7 @@
"""
class LD_Contact(Graphic_Element, DebugDataConsumer):
-
+
# Create a new contact
def __init__(self, parent, type, name, id = None):
Graphic_Element.__init__(self, parent)
@@ -365,7 +365,7 @@
self.PreviousSpreading = False
self.RefreshNameSize()
self.RefreshTypeSize()
-
+
def Flush(self):
if self.Input is not None:
self.Input.Flush()
@@ -373,13 +373,13 @@
if self.Output is not None:
self.Output.Flush()
self.Output = None
-
+
def SetForced(self, forced):
if self.Forced != forced:
self.Forced = forced
if self.Visible:
self.Parent.ElementNeedRefresh(self)
-
+
def SetValue(self, value):
if self.Type == CONTACT_RISING:
refresh = self.Value and not self.PreviousValue
@@ -393,7 +393,7 @@
if self.Visible:
self.Parent.ElementNeedRefresh(self)
self.SpreadCurrent()
-
+
def SpreadCurrent(self):
if self.Parent.Debug:
if self.Value is None:
@@ -414,7 +414,7 @@
elif not spreading and self.PreviousSpreading:
self.Output.SpreadCurrent(False)
self.PreviousSpreading = spreading
-
+
# Make a clone of this LD_Contact
def Clone(self, parent, id = None, pos = None):
contact = LD_Contact(parent, self.Type, self.Name, id)
@@ -426,10 +426,10 @@
contact.Input = self.Input.Clone(contact)
contact.Output = self.Output.Clone(contact)
return contact
-
+
def GetConnectorTranslation(self, element):
return {self.Input : element.Input, self.Output : element.Output}
-
+
# Returns the RedrawRect
def GetRedrawRect(self, movex = 0, movey = 0):
rect = Graphic_Element.GetRedrawRect(self, movex, movey)
@@ -446,29 +446,29 @@
if self.Parent.GetDrawingMode() != FREEDRAWING_MODE:
movex = movey = 0
return Graphic_Element.ProcessDragging(self, movex, movey, event, scaling, height_fac = 2)
-
+
# Forbids to change the contact size
def SetSize(self, width, height):
if self.Parent.GetDrawingMode() == FREEDRAWING_MODE:
Graphic_Element.SetSize(self, width, height)
self.RefreshConnectors()
-
+
# Delete this contact by calling the appropriate method
def Delete(self):
self.Parent.DeleteContact(self)
-
+
# Unconnect input and output
def Clean(self):
self.Input.UnConnect(delete = self.Parent.GetDrawingMode() == FREEDRAWING_MODE)
self.Output.UnConnect(delete = self.Parent.GetDrawingMode() == FREEDRAWING_MODE)
-
+
# Refresh the size of text for name
def RefreshNameSize(self):
if self.Name != "":
self.NameSize = self.Parent.GetTextExtent(self.Name)
else:
self.NameSize = 0, 0
-
+
# Refresh the size of text for type
def RefreshTypeSize(self):
typetext = ""
@@ -482,7 +482,7 @@
self.TypeSize = self.Parent.GetTextExtent(typetext)
else:
self.TypeSize = 0, 0
-
+
# Refresh the contact bounding box
def RefreshBoundingBox(self):
# Calculate the size of the name outside the contact
@@ -499,17 +499,17 @@
bbx_y = self.Pos.y
bbx_height = self.Size[1]
self.BoundingBox = wx.Rect(bbx_x, bbx_y, bbx_width + 1, bbx_height + 1)
-
+
# Returns the block minimum size
def GetMinSize(self):
return LD_ELEMENT_SIZE
-
+
# Refresh the position of wire connected to contact
def RefreshConnected(self, exclude = []):
self.Input.MoveConnected(exclude)
self.Output.MoveConnected(exclude)
-
- # Returns the contact connector that starts with the point given if it exists
+
+ # Returns the contact connector that starts with the point given if it exists
def GetConnector(self, position, name = None):
# if a name is given
if name is not None:
@@ -519,11 +519,11 @@
if name == self.Output.GetName():
return self.Output
return self.FindNearestConnector(position, [self.Input, self.Output])
-
- # Returns input and output contact connectors
+
+ # Returns input and output contact connectors
def GetConnectors(self):
return {"inputs": [self.Input], "outputs": [self.Output]}
-
+
# Test if point given is on contact input or output connector
def TestConnector(self, pt, direction = None, exclude=True):
# Test input connector
@@ -561,24 +561,24 @@
# Returns the contact type
def GetType(self):
return self.Type
-
+
# Method called when a LeftDClick event have been generated
def OnLeftDClick(self, event, dc, scaling):
# Edit the contact properties
self.Parent.EditContactContent(self)
-
+
# Method called when a RightUp event have been generated
def OnRightUp(self, event, dc, scaling):
# Popup the default menu
self.Parent.PopupDefaultMenu()
-
+
# Refreshes the contact model
def RefreshModel(self, move=True):
self.Parent.RefreshContactModel(self)
# If contact has moved, refresh the model of wires connected to output
if move:
self.Output.RefreshWires()
-
+
# Draws the highlightment of this element if it is highlighted
def DrawHighlightment(self, dc):
scalex, scaley = dc.GetUserScale()
@@ -592,12 +592,12 @@
top = (self.Pos.y - 1) * scaley - 2
width = 4 * scalex + 5
height = (self.Size[1] + 3) * scaley + 5
-
+
dc.DrawRectangle(left_left, top, width, height)
dc.DrawRectangle(right_left, top, width, height)
dc.SetLogicalFunction(wx.COPY)
dc.SetUserScale(scalex, scaley)
-
+
# Adds an highlight to the connection
def AddHighlight(self, infos, start, end, highlight_type):
highlights = self.Highlights.setdefault(infos[0], [])
@@ -606,13 +606,13 @@
AddHighlight(highlights, (start, end, highlight_type))
else:
AddHighlight(highlights, ((0, 0), (0, 1), highlight_type))
-
+
# Removes an highlight from the connection
def RemoveHighlight(self, infos, start, end, highlight_type):
highlights = self.Highlights.get(infos[0], [])
if RemoveHighlight(highlights, (start, end, highlight_type)) and len(highlights) == 0:
self.Highlights.pop(infos[0])
-
+
# Removes all the highlights of one particular type from the connection
def ClearHighlight(self, highlight_type=None):
if highlight_type is None:
@@ -623,11 +623,11 @@
highlights = ClearHighlights(highlight, highlight_type)
if len(highlights) == 0:
self.Highlights.pop(name)
-
+
# Draws contact
def Draw(self, dc):
Graphic_Element.Draw(self, dc)
- if self.Value is not None:
+ if self.Value is not None:
if self.Type == CONTACT_NORMAL and self.Value or \
self.Type == CONTACT_REVERSE and not self.Value or \
self.Type == CONTACT_RISING and self.Value and not self.PreviousValue or \
@@ -643,7 +643,7 @@
else:
dc.SetPen(MiterPen(wx.BLACK))
dc.SetBrush(wx.BLACK_BRUSH)
-
+
# Compiling contact type modifier symbol
typetext = ""
if self.Type == CONTACT_REVERSE:
@@ -652,7 +652,7 @@
typetext = "P"
elif self.Type == CONTACT_FALLING:
typetext = "N"
-
+
if getattr(dc, "printing", False):
name_size = dc.GetTextExtent(self.Name)
if typetext != "":
@@ -661,7 +661,7 @@
name_size = self.NameSize
if typetext != "":
type_size = self.TypeSize
-
+
# Draw two rectangles for representing the contact
dc.DrawRectangle(self.Pos.x, self.Pos.y, 2, self.Size[1] + 1)
dc.DrawRectangle(self.Pos.x + self.Size[0] - 1, self.Pos.y, 2, self.Size[1] + 1)
@@ -677,7 +677,7 @@
# Draw input and output connectors
self.Input.Draw(dc)
self.Output.Draw(dc)
-
+
if not getattr(dc, "printing", False):
for name, highlights in self.Highlights.iteritems():
if name == "reference":
@@ -694,7 +694,7 @@
"""
class LD_Coil(Graphic_Element):
-
+
# Create a new coil
def __init__(self, parent, type, name, id = None):
Graphic_Element.__init__(self, parent)
@@ -710,7 +710,7 @@
self.PreviousValue = False
self.RefreshNameSize()
self.RefreshTypeSize()
-
+
def Flush(self):
if self.Input is not None:
self.Input.Flush()
@@ -718,7 +718,7 @@
if self.Output is not None:
self.Output.Flush()
self.Output = None
-
+
def SpreadCurrent(self):
if self.Parent.Debug:
self.PreviousValue = self.Value
@@ -729,7 +729,7 @@
self.Output.SpreadCurrent(False)
if self.Value != self.PreviousValue and self.Visible:
self.Parent.ElementNeedRefresh(self)
-
+
# Make a clone of this LD_Coil
def Clone(self, parent, id = None, pos = None):
coil = LD_Coil(parent, self.Type, self.Name, id)
@@ -741,10 +741,10 @@
coil.Input = self.Input.Clone(coil)
coil.Output = self.Output.Clone(coil)
return coil
-
+
def GetConnectorTranslation(self, element):
return {self.Input : element.Input, self.Output : element.Output}
-
+
# Returns the RedrawRect
def GetRedrawRect(self, movex = 0, movey = 0):
rect = Graphic_Element.GetRedrawRect(self, movex, movey)
@@ -756,34 +756,34 @@
if self.Output.IsConnected():
rect = rect.Union(self.Output.GetConnectedRedrawRect(movex, movey))
return rect
-
+
def ProcessDragging(self, movex, movey, event, scaling):
if self.Parent.GetDrawingMode() != FREEDRAWING_MODE:
movex = movey = 0
- return Graphic_Element.ProcessDragging(self, movex, movey, event, scaling, height_fac = 2)
-
+ return Graphic_Element.ProcessDragging(self, movex, movey, event, scaling, height_fac = 2)
+
# Forbids to change the Coil size
def SetSize(self, width, height):
if self.Parent.GetDrawingMode() == FREEDRAWING_MODE:
Graphic_Element.SetSize(self, width, height)
self.RefreshConnectors()
-
+
# Delete this coil by calling the appropriate method
def Delete(self):
self.Parent.DeleteCoil(self)
-
+
# Unconnect input and output
def Clean(self):
self.Input.UnConnect(delete = self.Parent.GetDrawingMode() == FREEDRAWING_MODE)
self.Output.UnConnect(delete = self.Parent.GetDrawingMode() == FREEDRAWING_MODE)
-
+
# Refresh the size of text for name
def RefreshNameSize(self):
if self.Name != "":
self.NameSize = self.Parent.GetTextExtent(self.Name)
else:
self.NameSize = 0, 0
-
+
# Refresh the size of text for type
def RefreshTypeSize(self):
typetext = ""
@@ -801,7 +801,7 @@
self.TypeSize = self.Parent.GetTextExtent(typetext)
else:
self.TypeSize = 0, 0
-
+
# Refresh the coil bounding box
def RefreshBoundingBox(self):
# Calculate the size of the name outside the coil
@@ -818,17 +818,17 @@
bbx_y = self.Pos.y
bbx_height = self.Size[1]
self.BoundingBox = wx.Rect(bbx_x, bbx_y, bbx_width + 1, bbx_height + 1)
-
+
# Returns the block minimum size
def GetMinSize(self):
return LD_ELEMENT_SIZE
-
+
# Refresh the position of wire connected to coil
def RefreshConnected(self, exclude = []):
self.Input.MoveConnected(exclude)
self.Output.MoveConnected(exclude)
-
- # Returns the coil connector that starts with the point given if it exists
+
+ # Returns the coil connector that starts with the point given if it exists
def GetConnector(self, position, name = None):
# if a name is given
if name is not None:
@@ -838,11 +838,11 @@
if self.Output and name == self.Output.GetName():
return self.Output
return self.FindNearestConnector(position, [self.Input, self.Output])
-
- # Returns input and output coil connectors
+
+ # Returns input and output coil connectors
def GetConnectors(self):
return {"inputs": [self.Input], "outputs": [self.Output]}
-
+
# Test if point given is on coil input or output connector
def TestConnector(self, pt, direction = None, exclude=True):
# Test input connector
@@ -852,7 +852,7 @@
if self.Output.TestPoint(pt, direction, exclude):
return self.Output
return None
-
+
# Refresh the positions of the block connectors
def RefreshConnectors(self):
scaling = self.Parent.GetScaling()
@@ -862,7 +862,7 @@
self.Input.SetPosition(wx.Point(0, position))
self.Output.SetPosition(wx.Point(self.Size[0], position))
self.RefreshConnected()
-
+
# Changes the coil name
def SetName(self, name):
self.Name = name
@@ -871,33 +871,33 @@
# Returns the coil name
def GetName(self):
return self.Name
-
+
# Changes the coil type
def SetType(self, type):
self.Type = type
self.RefreshTypeSize()
-
+
# Returns the coil type
def GetType(self):
return self.Type
-
+
# Method called when a LeftDClick event have been generated
def OnLeftDClick(self, event, dc, scaling):
# Edit the coil properties
self.Parent.EditCoilContent(self)
-
+
# Method called when a RightUp event have been generated
def OnRightUp(self, event, dc, scaling):
# Popup the default menu
self.Parent.PopupDefaultMenu()
-
+
# Refreshes the coil model
def RefreshModel(self, move=True):
self.Parent.RefreshCoilModel(self)
# If coil has moved, refresh the model of wires connected to output
if move:
self.Output.RefreshWires()
-
+
# Draws the highlightment of this element if it is highlighted
def DrawHighlightment(self, dc):
scalex, scaley = dc.GetUserScale()
@@ -906,19 +906,19 @@
dc.SetBrush(wx.TRANSPARENT_BRUSH)
dc.SetLogicalFunction(wx.AND)
# Draw a two circle arcs for representing the coil
- dc.DrawEllipticArc(round(self.Pos.x * scalex),
- round((self.Pos.y - int(self.Size[1] * (sqrt(2) - 1.) / 2.) + 1) * scaley),
- round(self.Size[0] * scalex),
+ dc.DrawEllipticArc(round(self.Pos.x * scalex),
+ round((self.Pos.y - int(self.Size[1] * (sqrt(2) - 1.) / 2.) + 1) * scaley),
+ round(self.Size[0] * scalex),
round((int(self.Size[1] * sqrt(2)) - 1) * scaley),
135, 225)
- dc.DrawEllipticArc(round(self.Pos.x * scalex),
- round((self.Pos.y - int(self.Size[1] * (sqrt(2) - 1.) / 2.) + 1) * scaley),
- round(self.Size[0] * scalex),
+ dc.DrawEllipticArc(round(self.Pos.x * scalex),
+ round((self.Pos.y - int(self.Size[1] * (sqrt(2) - 1.) / 2.) + 1) * scaley),
+ round(self.Size[0] * scalex),
round((int(self.Size[1] * sqrt(2)) - 1) * scaley),
-45, 45)
dc.SetLogicalFunction(wx.COPY)
dc.SetUserScale(scalex, scaley)
-
+
# Adds an highlight to the connection
def AddHighlight(self, infos, start, end, highlight_type):
highlights = self.Highlights.setdefault(infos[0], [])
@@ -927,13 +927,13 @@
AddHighlight(highlights, (start, end, highlight_type))
else:
AddHighlight(highlights, ((0, 0), (0, 1), highlight_type))
-
+
# Removes an highlight from the connection
def RemoveHighlight(self, infos, start, end, highlight_type):
highlights = self.Highlights.get(infos[0], [])
if RemoveHighlight(highlights, (start, end, highlight_type)) and len(highlights) == 0:
self.Highlights.pop(infos[0])
-
+
# Removes all the highlights of one particular type from the connection
def ClearHighlight(self, highlight_type=None):
if highlight_type is None:
@@ -944,7 +944,7 @@
highlights = ClearHighlights(highlight, highlight_type)
if len(highlights) == 0:
self.Highlights.pop(name)
-
+
# Draws coil
def Draw(self, dc):
Graphic_Element.Draw(self, dc)
@@ -953,8 +953,8 @@
else:
dc.SetPen(MiterPen(wx.BLACK, 2, wx.SOLID))
dc.SetBrush(wx.TRANSPARENT_BRUSH)
-
- # Compiling coil type modifier symbol
+
+ # Compiling coil type modifier symbol
typetext = ""
if self.Type == COIL_REVERSE:
typetext = "/"
@@ -966,7 +966,7 @@
typetext = "P"
elif self.Type == COIL_FALLING:
typetext = "N"
-
+
if getattr(dc, "printing", False) and not isinstance(dc, wx.PostScriptDC):
# Draw an clipped ellipse for representing the coil
clipping_box = dc.GetClippingBox()
@@ -992,7 +992,7 @@
name_size = self.NameSize
if typetext != "":
type_size = self.TypeSize
-
+
# Draw coil name
name_pos = (self.Pos.x + (self.Size[0] - name_size[0]) / 2,
self.Pos.y - (name_size[1] + 2))
@@ -1012,5 +1012,3 @@
DrawHighlightedText(dc, self.Name, highlights, name_pos[0], name_pos[1])
elif typetext != "":
DrawHighlightedText(dc, typetext, highlights, type_pos[0], type_pos[1])
-
-
--- a/graphics/RubberBand.py Fri Aug 11 15:18:19 2017 +0300
+++ b/graphics/RubberBand.py Mon Aug 14 19:13:01 2017 +0300
@@ -35,19 +35,19 @@
"""
class RubberBand:
-
+
def __init__(self, viewer):
"""
Constructor
@param viewer: Viewer on which rubberband must be drawn
"""
self.Viewer = viewer
-
+
# wx.Panel on which rubberband will be drawn
self.DrawingSurface = viewer.Editor
-
+
self.Reset()
-
+
def Reset(self):
"""
Initialize internal attributes of rubberband
@@ -55,14 +55,14 @@
self.StartPoint = None
self.CurrentBBox = None
self.LastBBox = None
-
+
def IsShown(self):
"""
Indicate if rubberband is drawn on viewer
@return: True if rubberband is drawn
"""
return self.CurrentBBox != None
-
+
def GetCurrentExtent(self):
"""
Return the rubberband bounding box
@@ -73,7 +73,7 @@
if self.IsShown():
return self.CurrentBBox
return self.LastBBox
-
+
def OnLeftDown(self, event, dc, scaling):
"""
Called when left mouse is pressed on Viewer. Starts to edit a new
@@ -85,16 +85,16 @@
# Save the point where mouse was pressed in Viewer unit, position may
# be modified by scroll and zoom applied on viewer
self.StartPoint = GetScaledEventPosition(event, dc, scaling)
-
+
# Initialize rubberband bounding box
self.CurrentBBox = wx.Rect(self.StartPoint.x, self.StartPoint.y, 0, 0)
-
+
# Change viewer mouse cursor to reflect a rubberband bounding box is
# edited
self.DrawingSurface.SetCursor(wx.StockCursor(wx.CURSOR_CROSS))
-
+
self.Redraw()
-
+
def OnMotion(self, event, dc, scaling):
"""
Called when mouse is dragging over Viewer. Update the current edited
@@ -106,19 +106,19 @@
# Get mouse position in Viewer unit, position may be modified by scroll
# and zoom applied on viewer
pos = GetScaledEventPosition(event, dc, scaling)
-
+
# Save the last bounding box drawn for erasing it later
self.LastBBox = wx.Rect(0, 0, 0, 0)
self.LastBBox.Union(self.CurrentBBox)
-
- # Calculate new position and size of the box
+
+ # Calculate new position and size of the box
self.CurrentBBox.x = min(pos.x, self.StartPoint.x)
self.CurrentBBox.y = min(pos.y, self.StartPoint.y)
self.CurrentBBox.width = abs(pos.x - self.StartPoint.x) + 1
self.CurrentBBox.height = abs(pos.y - self.StartPoint.y) + 1
-
+
self.Redraw()
-
+
def OnLeftUp(self, event, dc, scaling):
"""
Called when mouse is release from Viewer. Erase the current edited
@@ -129,16 +129,16 @@
"""
# Change viewer mouse cursor to default
self.DrawingSurface.SetCursor(wx.NullCursor)
-
+
# Save the last edited bounding box
self.LastBBox = self.CurrentBBox
self.CurrentBBox = None
-
+
self.Redraw()
-
+
def DrawBoundingBoxes(self, bboxes, dc=None):
"""
- Draw a list of bounding box on Viewer in the order given using XOR
+ Draw a list of bounding box on Viewer in the order given using XOR
logical function
@param bboxes: List of bounding boxes to draw on viewer
@param dc: Device Context of Viewer (default None)
@@ -146,29 +146,29 @@
# Get viewer Device Context if not given
if dc is None:
dc = self.Viewer.GetLogicalDC()
-
+
# Save current viewer scale factors before resetting them in order to
# avoid rubberband pen to be scaled
scalex, scaley = dc.GetUserScale()
dc.SetUserScale(1, 1)
-
+
# Set DC drawing style
dc.SetPen(wx.Pen(wx.WHITE, style=wx.DOT))
dc.SetBrush(wx.TRANSPARENT_BRUSH)
dc.SetLogicalFunction(wx.XOR)
-
+
# Draw the bounding boxes using viewer scale factor
for bbox in bboxes:
if bbox is not None:
dc.DrawRectangle(
- bbox.x * scalex, bbox.y * scaley,
+ bbox.x * scalex, bbox.y * scaley,
bbox.width * scalex, bbox.height * scaley)
-
+
dc.SetLogicalFunction(wx.COPY)
-
+
# Restore Viewer scale factor
dc.SetUserScale(scalex, scaley)
-
+
def Redraw(self, dc = None):
"""
Redraw rubberband on Viewer
@@ -176,7 +176,7 @@
"""
# Erase last bbox and draw current bbox
self.DrawBoundingBoxes([self.LastBBox, self.CurrentBBox], dc)
-
+
def Erase(self, dc = None):
"""
Erase rubberband from Viewer
--- a/graphics/SFC_Objects.py Fri Aug 11 15:18:19 2017 +0300
+++ b/graphics/SFC_Objects.py Mon Aug 14 19:13:01 2017 +0300
@@ -43,7 +43,7 @@
"""
class SFC_Step(Graphic_Element, DebugDataConsumer):
-
+
# Create a new step
def __init__(self, parent, name, initial = False, id = None):
Graphic_Element.__init__(self, parent)
@@ -62,7 +62,7 @@
self.Action = None
self.PreviousValue = None
self.PreviousSpreading = False
-
+
def Flush(self):
if self.Input is not None:
self.Input.Flush()
@@ -73,13 +73,13 @@
if self.Action is not None:
self.Action.Flush()
self.Action = None
-
+
def SetForced(self, forced):
if self.Forced != forced:
self.Forced = forced
if self.Visible:
self.Parent.ElementNeedRefresh(self)
-
+
def SetValue(self, value):
self.PreviousValue = self.Value
self.Value = value
@@ -87,7 +87,7 @@
if self.Visible:
self.Parent.ElementNeedRefresh(self)
self.SpreadCurrent()
-
+
def SpreadCurrent(self):
if self.Parent.Debug:
spreading = self.Value
@@ -102,7 +102,7 @@
if self.Action is not None:
self.Action.SpreadCurrent(False)
self.PreviousSpreading = spreading
-
+
# Make a clone of this SFC_Step
def Clone(self, parent, id = None, name = "Step", pos = None):
step = SFC_Step(parent, name, self.Initial, id)
@@ -118,7 +118,7 @@
if self.Action:
step.Action = self.Action.Clone(step)
return step
-
+
def GetConnectorTranslation(self, element):
connectors = {}
if self.Input is not None:
@@ -128,7 +128,7 @@
if self.Action is not None:
connectors[self.Action] = element.Action
return connectors
-
+
# Returns the RedrawRect
def GetRedrawRect(self, movex = 0, movey = 0):
rect = Graphic_Element.GetRedrawRect(self, movex, movey)
@@ -146,11 +146,11 @@
if self.Action and self.Action.IsConnected():
rect = rect.Union(self.Action.GetConnectedRedrawRect(movex, movey))
return rect
-
+
# Delete this step by calling the appropriate method
def Delete(self):
self.Parent.DeleteStep(self)
-
+
# Unconnect input and output
def Clean(self):
if self.Input:
@@ -159,50 +159,50 @@
self.Output.UnConnect(delete = self.Parent.GetDrawingMode() == FREEDRAWING_MODE)
if self.Action:
self.Action.UnConnect(delete = self.Parent.GetDrawingMode() == FREEDRAWING_MODE)
-
+
# Refresh the size of text for name
def RefreshNameSize(self):
self.NameSize = self.Parent.GetTextExtent(self.Name)
-
+
# Add output connector to step
def AddInput(self):
if not self.Input:
self.Input = Connector(self, "", None, wx.Point(self.Size[0] / 2, 0), NORTH)
self.RefreshBoundingBox()
-
+
# Remove output connector from step
def RemoveInput(self):
if self.Input:
self.Input.UnConnect(delete = self.Parent.GetDrawingMode() == FREEDRAWING_MODE)
self.Input = None
self.RefreshBoundingBox()
-
+
# Add output connector to step
def AddOutput(self):
if not self.Output:
self.Output = Connector(self, "", None, wx.Point(self.Size[0] / 2, self.Size[1]), SOUTH, onlyone = True)
self.RefreshBoundingBox()
-
+
# Remove output connector from step
def RemoveOutput(self):
if self.Output:
self.Output.UnConnect(delete = self.Parent.GetDrawingMode() == FREEDRAWING_MODE)
self.Output = None
self.RefreshBoundingBox()
-
+
# Add action connector to step
def AddAction(self):
if not self.Action:
self.Action = Connector(self, "", None, wx.Point(self.Size[0], self.Size[1] / 2), EAST, onlyone = True)
self.RefreshBoundingBox()
-
+
# Remove action connector from step
def RemoveAction(self):
if self.Action:
self.Action.UnConnect(delete = self.Parent.GetDrawingMode() == FREEDRAWING_MODE)
self.Action = None
self.RefreshBoundingBox()
-
+
# Refresh the step bounding box
def RefreshBoundingBox(self):
# Calculate the bounding box size
@@ -222,7 +222,7 @@
bbx_height += CONNECTOR_SIZE
#self.BoundingBox = wx.Rect(self.Pos.x, bbx_y, bbx_width + 1, bbx_height + 1)
self.BoundingBox = wx.Rect(self.Pos.x, self.Pos.y, self.Size[0] + 1, self.Size[1] + 1)
-
+
# Refresh the positions of the step connectors
def RefreshConnectors(self):
scaling = self.Parent.GetScaling()
@@ -241,7 +241,7 @@
if self.Action:
self.Action.SetPosition(wx.Point(self.Size[0], vertical_pos))
self.RefreshConnected()
-
+
# Refresh the position of wires connected to step
def RefreshConnected(self, exclude = []):
if self.Input:
@@ -250,8 +250,8 @@
self.Output.MoveConnected(exclude)
if self.Action:
self.Action.MoveConnected(exclude)
-
- # Returns the step connector that starts with the point given if it exists
+
+ # Returns the step connector that starts with the point given if it exists
def GetConnector(self, position, name = None):
# if a name is given
if name is not None:
@@ -273,12 +273,12 @@
if self.Action:
connectors.append(self.Action)
return self.FindNearestConnector(position, connectors)
-
- # Returns action step connector
+
+ # Returns action step connector
def GetActionConnector(self):
return self.Action
-
- # Returns input and output step connectors
+
+ # Returns input and output step connectors
def GetConnectors(self):
connectors = {"inputs": [], "outputs": []}
if self.Input:
@@ -286,7 +286,7 @@
if self.Output:
connectors["outputs"].append(self.Output)
return connectors
-
+
# Test if point given is on step input or output connector
def TestConnector(self, pt, direction = None, exclude=True):
# Test input connector if it exists
@@ -312,7 +312,7 @@
# Returns the step initial property
def GetInitial(self):
return self.Initial
-
+
# Returns the connector connected to input
def GetPreviousConnector(self):
if self.Input:
@@ -320,7 +320,7 @@
if len(wires) == 1:
return wires[0][0].GetOtherConnected(self.Input)
return None
-
+
# Returns the connector connected to output
def GetNextConnector(self):
if self.Output:
@@ -328,7 +328,7 @@
if len(wires) == 1:
return wires[0][0].GetOtherConnected(self.Output)
return None
-
+
# Returns the connector connected to action
def GetActionConnected(self):
if self.Action:
@@ -336,7 +336,7 @@
if len(wires) == 1:
return wires[0][0].GetOtherConnected(self.Action)
return None
-
+
# Returns the number of action line
def GetActionExtraLineNumber(self):
if self.Action:
@@ -346,7 +346,7 @@
action_block = wires[0][0].GetOtherConnected(self.Action).GetParentBlock()
return max(0, action_block.GetLineNumber() - 1)
return 0
-
+
# Returns the step minimum size
def GetMinSize(self):
text_width, text_height = self.Parent.GetTextExtent(self.Name)
@@ -354,7 +354,7 @@
return text_width + 14, text_height + 14
else:
return text_width + 10, text_height + 10
-
+
# Updates the step size
def UpdateSize(self, width, height):
diffx = self.Size.GetWidth() / 2 - width / 2
@@ -365,7 +365,7 @@
self.RefreshConnected()
else:
self.RefreshOutputPosition((0, diffy))
-
+
# Align input element with this step
def RefreshInputPosition(self):
if self.Input:
@@ -382,7 +382,7 @@
input_block.MoveActionBlock((diffx, 0))
input_block.Move(diffx, 0)
input_block.RefreshInputPosition()
-
+
# Align output element with this step
def RefreshOutputPosition(self, move = None):
if self.Output:
@@ -422,7 +422,7 @@
output_block.MoveActionBlock((diffx, 0))
output_block.Move(diffx, 0)
output_block.RefreshOutputPosition()
-
+
# Refresh action element with this step
def MoveActionBlock(self, move):
if self.Action:
@@ -432,24 +432,24 @@
action_block = wires[0][0].GetOtherConnected(self.Action).GetParentBlock()
action_block.Move(move[0], move[1], self.Parent.Wires)
wires[0][0].Move(move[0], move[1], True)
-
+
# Resize the divergence from position and size given
def Resize(self, x, y, width, height):
if self.Parent.GetDrawingMode() != FREEDRAWING_MODE:
self.UpdateSize(width, height)
else:
Graphic_Element.Resize(self, x, y, width, height)
-
+
# Method called when a LeftDClick event have been generated
def OnLeftDClick(self, event, dc, scaling):
# Edit the step properties
self.Parent.EditStepContent(self)
-
+
# Method called when a RightUp event have been generated
def OnRightUp(self, event, dc, scaling):
# Popup the menu with special items for a step
self.Parent.PopupDefaultMenu()
-
+
# Refreshes the step state according to move defined and handle selected
def ProcessDragging(self, movex, movey, event, scaling):
handle_type, handle = self.Handle
@@ -477,17 +477,17 @@
return movex, 0
else:
return Graphic_Element.ProcessDragging(self, movex, movey, event, scaling)
-
+
# Refresh input element model
def RefreshInputModel(self):
if self.Input:
input = self.GetPreviousConnector()
- if input:
+ if input:
input_block = input.GetParentBlock()
input_block.RefreshModel(False)
if not isinstance(input_block, SFC_Divergence):
input_block.RefreshInputModel()
-
+
# Refresh output element model
def RefreshOutputModel(self, move=False):
if self.Output:
@@ -497,7 +497,7 @@
output_block.RefreshModel(False)
if not isinstance(output_block, SFC_Divergence) or move:
output_block.RefreshOutputModel(move)
-
+
# Refreshes the step model
def RefreshModel(self, move=True):
self.Parent.RefreshStepModel(self)
@@ -513,21 +513,21 @@
self.RefreshOutputModel(self.Initial)
elif self.Output:
self.Output.RefreshWires()
-
+
# Adds an highlight to the connection
def AddHighlight(self, infos, start, end, highlight_type):
if infos[0] == "name" and start[0] == 0 and end[0] == 0:
AddHighlight(self.Highlights, (start, end, highlight_type))
-
+
# Removes an highlight from the connection
def RemoveHighlight(self, infos, start, end, highlight_type):
if infos[0] == "name":
RemoveHighlight(self.Highlights, (start, end, highlight_type))
-
+
# Removes all the highlights of one particular type from the connection
def ClearHighlight(self, highlight_type=None):
ClearHighlights(self.Highlights, highlight_type)
-
+
# Draws step
def Draw(self, dc):
Graphic_Element.Draw(self, dc)
@@ -541,12 +541,12 @@
else:
dc.SetPen(MiterPen(wx.BLACK))
dc.SetBrush(wx.WHITE_BRUSH)
-
+
if getattr(dc, "printing", False):
name_size = dc.GetTextExtent(self.Name)
else:
name_size = self.NameSize
-
+
# Draw two rectangles for representing the step
dc.DrawRectangle(self.Pos.x, self.Pos.y, self.Size[0] + 1, self.Size[1] + 1)
if self.Initial:
@@ -562,10 +562,10 @@
self.Output.Draw(dc)
if self.Action:
self.Action.Draw(dc)
-
+
if not getattr(dc, "printing", False):
DrawHighlightedText(dc, self.Name, self.Highlights, name_pos[0], name_pos[1])
-
+
#-------------------------------------------------------------------------------
# Sequencial Function Chart Transition
@@ -576,7 +576,7 @@
"""
class SFC_Transition(Graphic_Element, DebugDataConsumer):
-
+
# Create a new transition
def __init__(self, parent, type = "reference", condition = None, priority = 0, id = None):
Graphic_Element.__init__(self, parent)
@@ -593,7 +593,7 @@
self.Highlights = {}
self.PreviousValue = None
self.PreviousSpreading = False
-
+
def Flush(self):
if self.Input is not None:
self.Input.Flush()
@@ -604,13 +604,13 @@
if self.Type == "connection" and self.Condition is not None:
self.Condition.Flush()
self.Condition = None
-
+
def SetForced(self, forced):
if self.Forced != forced:
self.Forced = forced
if self.Visible:
self.Parent.ElementNeedRefresh(self)
-
+
def SetValue(self, value):
self.PreviousValue = self.Value
self.Value = value
@@ -618,7 +618,7 @@
if self.Visible:
self.Parent.ElementNeedRefresh(self)
self.SpreadCurrent()
-
+
def SpreadCurrent(self):
if self.Parent.Debug:
if self.Value is None:
@@ -629,7 +629,7 @@
elif not spreading and self.PreviousSpreading:
self.Output.SpreadCurrent(False)
self.PreviousSpreading = spreading
-
+
# Make a clone of this SFC_Transition
def Clone(self, parent, id = None, pos = None):
transition = SFC_Transition(parent, self.Type, self.Condition, self.Priority, id)
@@ -643,13 +643,13 @@
if self.Type == "connection":
transition.Condition = self.Condition.Clone(transition)
return transition
-
+
def GetConnectorTranslation(self, element):
connectors = {self.Input : element.Input, self.Output : element.Output}
if self.Type == "connection" and self.Condition is not None:
connectors[self.Condition] = element.Condition
return connectors
-
+
# Returns the RedrawRect
def GetRedrawRect(self, movex = 0, movey = 0):
rect = Graphic_Element.GetRedrawRect(self, movex, movey)
@@ -665,17 +665,17 @@
if self.Type == "connection" and self.Condition.IsConnected():
rect = rect.Union(self.Condition.GetConnectedRedrawRect(movex, movey))
return rect
-
+
# Forbids to change the transition size
def SetSize(self, width, height):
if self.Parent.GetDrawingMode() == FREEDRAWING_MODE:
Graphic_Element.SetSize(self, width, height)
-
+
# Forbids to resize the transition
def Resize(self, x, y, width, height):
if self.Parent.GetDrawingMode() == FREEDRAWING_MODE:
Graphic_Element.Resize(self, x, y, width, height)
-
+
# Refresh the size of text for name
def RefreshConditionSize(self):
if self.Type != "connection":
@@ -683,7 +683,7 @@
self.ConditionSize = self.Parent.GetTextExtent(self.Condition)
else:
self.ConditionSize = self.Parent.GetTextExtent("Transition")
-
+
# Refresh the size of text for name
def RefreshPrioritySize(self):
if self.Priority != "":
@@ -694,14 +694,14 @@
# Delete this transition by calling the appropriate method
def Delete(self):
self.Parent.DeleteTransition(self)
-
+
# Unconnect input and output
def Clean(self):
self.Input.UnConnect(delete = self.Parent.GetDrawingMode() == FREEDRAWING_MODE)
self.Output.UnConnect(delete = self.Parent.GetDrawingMode() == FREEDRAWING_MODE)
if self.Type == "connection":
self.Condition.UnConnect(delete = self.Parent.GetDrawingMode() == FREEDRAWING_MODE)
-
+
# Returns if the point given is in the bounding box
def HitTest(self, pt, connectors=True):
if self.Type != "connection":
@@ -715,7 +715,7 @@
else:
test_text = False
return test_text or Graphic_Element.HitTest(self, pt, connectors)
-
+
# Refresh the transition bounding box
def RefreshBoundingBox(self):
bbx_x, bbx_y, bbx_width, bbx_height = self.Pos.x, self.Pos.y, self.Size[0], self.Size[1]
@@ -733,21 +733,21 @@
bbx_y = min(bbx_y, self.Pos.y - max(0, (text_height - self.Size[1]) / 2))
bbx_height = max(bbx_height, self.Pos.y - bbx_y + (self.Size[1] + text_height) / 2)
self.BoundingBox = wx.Rect(bbx_x, bbx_y, bbx_width + 1, bbx_height + 1)
-
+
# Returns the connector connected to input
def GetPreviousConnector(self):
wires = self.Input.GetWires()
if len(wires) == 1:
return wires[0][0].GetOtherConnected(self.Input)
return None
-
+
# Returns the connector connected to output
def GetNextConnector(self):
wires = self.Output.GetWires()
if len(wires) == 1:
return wires[0][0].GetOtherConnected(self.Output)
return None
-
+
# Refresh the positions of the transition connectors
def RefreshConnectors(self):
scaling = self.Parent.GetScaling()
@@ -763,15 +763,15 @@
if self.Type == "connection":
self.Condition.SetPosition(wx.Point(0, vertical_pos))
self.RefreshConnected()
-
+
# Refresh the position of the wires connected to transition
def RefreshConnected(self, exclude = []):
self.Input.MoveConnected(exclude)
self.Output.MoveConnected(exclude)
if self.Type == "connection":
self.Condition.MoveConnected(exclude)
-
- # Returns the transition connector that starts with the point given if it exists
+
+ # Returns the transition connector that starts with the point given if it exists
def GetConnector(self, position, name = None):
# if a name is given
if name is not None:
@@ -786,17 +786,17 @@
if self.Type == "connection":
connectors.append(self.Condition)
return self.FindNearestConnector(position, connectors)
-
+
# Returns the transition condition connector
def GetConditionConnector(self):
if self.Type == "connection":
return self.Condition
return None
-
+
# Returns input and output transition connectors
def GetConnectors(self):
return {"inputs": [self.Input], "outputs": [self.Output]}
-
+
# Test if point given is on transition input or output connector
def TestConnector(self, pt, direction = None, exclude=True):
# Test input connector
@@ -814,7 +814,7 @@
def SetType(self, type, condition = None):
if self.Type != type:
if self.Type == "connection":
- self.Condition.UnConnect(delete = self.Parent.GetDrawingMode() == FREEDRAWING_MODE)
+ self.Condition.UnConnect(delete = self.Parent.GetDrawingMode() == FREEDRAWING_MODE)
self.Type = type
if type == "connection":
self.Condition = Connector(self, "", "BOOL", wx.Point(0, self.Size[1] / 2), WEST)
@@ -829,7 +829,7 @@
self.Condition = condition
self.RefreshConditionSize()
self.RefreshBoundingBox()
-
+
# Returns the transition type
def GetType(self):
return self.Type
@@ -839,7 +839,7 @@
self.Priority = priority
self.RefreshPrioritySize()
self.RefreshBoundingBox()
-
+
# Returns the transition type
def GetPriority(self):
return self.Priority
@@ -849,11 +849,11 @@
if self.Type != "connection":
return self.Condition
return None
-
+
# Returns the transition minimum size
def GetMinSize(self):
return SFC_TRANSITION_SIZE
-
+
# Align input element with this step
def RefreshInputPosition(self):
wires = self.Input.GetWires()
@@ -870,7 +870,7 @@
input_block.MoveActionBlock((diffx, 0))
input_block.Move(diffx, 0)
input_block.RefreshInputPosition()
-
+
# Align output element with this step
def RefreshOutputPosition(self, move = None):
wires = self.Output.GetWires()
@@ -902,12 +902,12 @@
def OnLeftDClick(self, event, dc, scaling):
# Edit the transition properties
self.Parent.EditTransitionContent(self)
-
+
# Method called when a RightUp event have been generated
def OnRightUp(self, event, dc, scaling):
# Popup the menu with special items for a step
self.Parent.PopupDefaultMenu()
-
+
# Refreshes the transition state according to move defined and handle selected
def ProcessDragging(self, movex, movey, event, scaling):
if self.Parent.GetDrawingMode() != FREEDRAWING_MODE:
@@ -920,7 +920,7 @@
return movex, 0
else:
return Graphic_Element.ProcessDragging(self, movex, movey, event, scaling, width_fac = 2, height_fac = 2)
-
+
# Refresh input element model
def RefreshInputModel(self):
if self.Parent.GetDrawingMode() != FREEDRAWING_MODE:
@@ -930,7 +930,7 @@
input_block.RefreshModel(False)
if not isinstance(input_block, SFC_Divergence):
input_block.RefreshInputModel()
-
+
# Refresh output element model
def RefreshOutputModel(self, move=False):
output = self.GetNextConnector()
@@ -939,7 +939,7 @@
output_block.RefreshModel(False)
if not isinstance(output_block, SFC_Divergence) or move:
output_block.RefreshOutputModel(move)
-
+
# Refreshes the transition model
def RefreshModel(self, move=True):
self.Parent.RefreshTransitionModel(self)
@@ -950,20 +950,20 @@
self.RefreshOutputModel()
else:
self.Output.RefreshWires()
-
+
# Adds an highlight to the block
def AddHighlight(self, infos, start, end ,highlight_type):
if infos[0] in ["reference", "inline", "priority"] and start[0] == 0 and end[0] == 0:
highlights = self.Highlights.setdefault(infos[0], [])
AddHighlight(highlights, (start, end, highlight_type))
-
+
# Removes an highlight from the block
def RemoveHighlight(self, infos, start, end, highlight_type):
if infos[0] in ["reference", "inline", "priority"]:
highlights = self.Highlights.get(infos[0], [])
if RemoveHighlight(highlights, (start, end, highlight_type)) and len(highlights) == 0:
self.Highlights.pop(infos[0])
-
+
# Removes all the highlights of one particular type from the block
def ClearHighlight(self, highlight_type=None):
if highlight_type is None:
@@ -974,7 +974,7 @@
highlights = ClearHighlights(highlight, highlight_type)
if len(highlights) == 0:
self.Highlights.pop(name)
-
+
# Draws transition
def Draw(self, dc):
Graphic_Element.Draw(self, dc)
@@ -991,7 +991,7 @@
else:
dc.SetPen(MiterPen(wx.BLACK))
dc.SetBrush(wx.BLACK_BRUSH)
-
+
if getattr(dc, "printing", False):
if self.Type != "connection":
condition_size = dc.GetTextExtent(self.Condition)
@@ -1002,14 +1002,14 @@
condition_size = self.ConditionSize
if self.Priority != 0:
priority_size = self.PrioritySize
-
+
# Draw plain rectangle for representing the transition
- dc.DrawRectangle(self.Pos.x,
- self.Pos.y + (self.Size[1] - SFC_TRANSITION_SIZE[1])/2,
+ dc.DrawRectangle(self.Pos.x,
+ self.Pos.y + (self.Size[1] - SFC_TRANSITION_SIZE[1])/2,
self.Size[0] + 1,
SFC_TRANSITION_SIZE[1] + 1)
vertical_line_x = self.Input.GetPosition()[0]
- dc.DrawLine(vertical_line_x, self.Pos.y, vertical_line_x, self.Pos.y + self.Size[1] + 1)
+ dc.DrawLine(vertical_line_x, self.Pos.y, vertical_line_x, self.Pos.y + self.Size[1] + 1)
# Draw transition condition
if self.Type != "connection":
if self.Condition != "":
@@ -1028,7 +1028,7 @@
self.Output.Draw(dc)
if self.Type == "connection":
self.Condition.Draw(dc)
-
+
if not getattr(dc, "printing", False):
for name, highlights in self.Highlights.iteritems():
if name == "priority":
@@ -1046,7 +1046,7 @@
"""
class SFC_Divergence(Graphic_Element):
-
+
# Create a new divergence
def __init__(self, parent, type, number = 2, id = None):
Graphic_Element.__init__(self, parent)
@@ -1068,7 +1068,7 @@
self.Outputs = [Connector(self, "", None, wx.Point(self.Size[0] / 2, self.Size[1]), SOUTH, onlyone = True)]
self.Value = None
self.PreviousValue = None
-
+
def Flush(self):
for input in self.Inputs:
input.Flush()
@@ -1076,7 +1076,7 @@
for output in self.Outputs:
output.Flush()
self.Outputs = []
-
+
def SpreadCurrent(self):
if self.Parent.Debug:
self.PreviousValue = self.Value
@@ -1102,7 +1102,7 @@
self.Parent.ElementNeedRefresh(self)
for output in self.Outputs:
output.SpreadCurrent(False)
-
+
# Make a clone of this SFC_Divergence
def Clone(self, parent, id = None, pos = None):
divergence = SFC_Divergence(parent, self.Type, max(len(self.Inputs), len(self.Outputs)), id)
@@ -1114,10 +1114,10 @@
divergence.Inputs = [input.Clone(divergence) for input in self.Inputs]
divergence.Outputs = [output.Clone(divergence) for output in self.Outputs]
return divergence
-
+
def GetConnectorTranslation(self, element):
return dict(zip(self.Inputs + self.Outputs, element.Inputs + element.Outputs))
-
+
# Returns the RedrawRect
def GetRedrawRect(self, movex = 0, movey = 0):
rect = Graphic_Element.GetRedrawRect(self, movex, movey)
@@ -1129,27 +1129,27 @@
if output.IsConnected():
rect = rect.Union(output.GetConnectedRedrawRect(movex, movey))
return rect
-
+
# Forbids to resize the divergence
def Resize(self, x, y, width, height):
if self.Parent.GetDrawingMode() == FREEDRAWING_MODE:
Graphic_Element.Resize(self, x, 0, width, self.GetMinSize()[1])
-
+
# Delete this divergence by calling the appropriate method
def Delete(self):
self.Parent.DeleteDivergence(self)
-
+
# Returns the divergence type
def GetType(self):
return self.Type
-
+
# Unconnect input and output
def Clean(self):
for input in self.Inputs:
input.UnConnect(delete = self.Parent.GetDrawingMode() == FREEDRAWING_MODE)
for output in self.Outputs:
output.UnConnect(delete = self.Parent.GetDrawingMode() == FREEDRAWING_MODE)
-
+
# Add a branch to the divergence
def AddBranch(self):
if self.Type in [SELECTION_DIVERGENCE, SIMULTANEOUS_DIVERGENCE]:
@@ -1168,7 +1168,7 @@
connector = Connector(self, "", None, wx.Point(maxx + SFC_DEFAULT_SEQUENCE_INTERVAL, 0), NORTH, onlyone = True)
self.Inputs.append(connector)
self.MoveConnector(connector, SFC_DEFAULT_SEQUENCE_INTERVAL)
-
+
# Remove a branch from the divergence
def RemoveBranch(self, connector):
if self.Type in [SELECTION_DIVERGENCE, SIMULTANEOUS_DIVERGENCE]:
@@ -1179,41 +1179,41 @@
if connector in self.Inputs and len(self.Inputs) > 2:
self.Inputs.remove(connector)
self.MoveConnector(self.Inputs[0], 0)
-
+
# Remove the handled branch from the divergence
def RemoveHandledBranch(self):
handle_type, handle = self.Handle
if handle_type == HANDLE_CONNECTOR:
handle.UnConnect(delete=True)
self.RemoveBranch(handle)
-
+
# Return the number of branches for the divergence
def GetBranchNumber(self):
if self.Type in [SELECTION_DIVERGENCE, SIMULTANEOUS_DIVERGENCE]:
return len(self.Outputs)
elif self.Type in [SELECTION_CONVERGENCE, SIMULTANEOUS_CONVERGENCE]:
return len(self.Inputs)
-
+
# Returns if the point given is in the bounding box
def HitTest(self, pt, connectors=True):
return self.BoundingBox.InsideXY(pt.x, pt.y) or self.TestConnector(pt, exclude=False) != None
-
+
# Refresh the divergence bounding box
def RefreshBoundingBox(self):
if self.Type in [SELECTION_DIVERGENCE, SELECTION_CONVERGENCE]:
- self.BoundingBox = wx.Rect(self.Pos.x, self.Pos.y,
+ self.BoundingBox = wx.Rect(self.Pos.x, self.Pos.y,
self.Size[0] + 1, self.Size[1] + 1)
elif self.Type in [SIMULTANEOUS_DIVERGENCE, SIMULTANEOUS_CONVERGENCE]:
- self.BoundingBox = wx.Rect(self.Pos.x - SFC_SIMULTANEOUS_SEQUENCE_EXTRA, self.Pos.y,
+ self.BoundingBox = wx.Rect(self.Pos.x - SFC_SIMULTANEOUS_SEQUENCE_EXTRA, self.Pos.y,
self.Size[0] + 2 * SFC_SIMULTANEOUS_SEQUENCE_EXTRA + 1, self.Size[1] + 1)
-
+
# Refresh the position of wires connected to divergence
def RefreshConnected(self, exclude = []):
for input in self.Inputs:
input.MoveConnected(exclude)
for output in self.Outputs:
output.MoveConnected(exclude)
-
+
# Moves the divergence connector given
def MoveConnector(self, connector, movex):
position = connector.GetRelPosition()
@@ -1241,8 +1241,8 @@
self.Size[0] = maxx - minx
connector.MoveConnected()
self.RefreshBoundingBox()
-
- # Returns the divergence connector that starts with the point given if it exists
+
+ # Returns the divergence connector that starts with the point given if it exists
def GetConnector(self, position, name = None):
# if a name is given
if name is not None:
@@ -1254,11 +1254,11 @@
if name == output.GetName():
return output
return self.FindNearestConnector(position, self.Inputs + self.Outputs)
-
- # Returns input and output divergence connectors
+
+ # Returns input and output divergence connectors
def GetConnectors(self):
return {"inputs": self.Inputs, "outputs": self.Outputs}
-
+
# Test if point given is on divergence input or output connector
def TestConnector(self, pt, direction = None, exclude=True):
# Test input connector
@@ -1270,7 +1270,7 @@
if output.TestPoint(pt, direction, exclude):
return output
return None
-
+
# Changes the divergence size
def SetSize(self, width, height):
height = self.GetMinSize()[1]
@@ -1290,7 +1290,7 @@
output.MoveConnected()
self.Size = wx.Size(width, height)
self.RefreshBoundingBox()
-
+
# Returns the divergence minimum size
def GetMinSize(self, default=False):
width = 0
@@ -1304,7 +1304,7 @@
elif self.Type in [SIMULTANEOUS_DIVERGENCE, SIMULTANEOUS_CONVERGENCE]:
return width, 3
return 0, 0
-
+
# Refresh the position of the block connected to connector
def RefreshConnectedPosition(self, connector):
wires = connector.GetWires()
@@ -1340,7 +1340,7 @@
self.RefreshOutputPosition((0, diffy))
for input in self.Inputs:
input.MoveConnected()
-
+
# Align output element with this divergence
def RefreshOutputPosition(self, move = None):
if move:
@@ -1359,7 +1359,7 @@
if not isinstance(output_block, SFC_Divergence) or output_block.GetConnectors()["inputs"].index(output) == 0:
output_block.Move(move[0], move[1], self.Parent.Wires)
output_block.RefreshOutputPosition(move)
-
+
# Method called when a LeftDown event have been generated
def OnLeftDown(self, event, dc, scaling):
self.RealConnectors = {"Inputs":[],"Outputs":[]}
@@ -1370,12 +1370,12 @@
position = output.GetRelPosition()
self.RealConnectors["Outputs"].append(float(position.x)/float(self.Size[0]))
Graphic_Element.OnLeftDown(self, event, dc, scaling)
-
+
# Method called when a LeftUp event have been generated
def OnLeftUp(self, event, dc, scaling):
Graphic_Element.OnLeftUp(self, event, dc, scaling)
self.RealConnectors = None
-
+
# Method called when a RightDown event have been generated
def OnRightDown(self, event, dc, scaling):
pos = GetScaledEventPosition(event, dc, scaling)
@@ -1389,7 +1389,7 @@
self.oldPos = GetScaledEventPosition(event, dc, scaling)
else:
Graphic_Element.OnRightDown(self, event, dc, scaling)
-
+
# Method called when a RightUp event have been generated
def OnRightUp(self, event, dc, scaling):
pos = GetScaledEventPosition(event, dc, scaling)
@@ -1414,7 +1414,7 @@
else:
# Popup the divergence menu without delete branch
self.Parent.PopupDivergenceMenu(False)
-
+
# Refreshes the divergence state according to move defined and handle selected
def ProcessDragging(self, movex, movey, event, scaling):
handle_type, handle = self.Handle
@@ -1430,7 +1430,7 @@
elif self.Parent.GetDrawingMode() == FREEDRAWING_MODE:
return Graphic_Element.ProcessDragging(self, movex, movey, event, scaling)
return 0, 0
-
+
# Refresh output element model
def RefreshOutputModel(self, move=False):
if move and self.Parent.GetDrawingMode() != FREEDRAWING_MODE:
@@ -1442,7 +1442,7 @@
output_block.RefreshModel(False)
if not isinstance(output_block, SFC_Divergence) or move:
output_block.RefreshOutputModel(move)
-
+
# Refreshes the divergence model
def RefreshModel(self, move=True):
self.Parent.RefreshDivergenceModel(self)
@@ -1453,7 +1453,7 @@
else:
for output in self.Outputs:
output.RefreshWires()
-
+
# Draws the highlightment of this element if it is highlighted
def DrawHighlightment(self, dc):
scalex, scaley = dc.GetUserScale()
@@ -1467,13 +1467,13 @@
if self.Type in [SIMULTANEOUS_DIVERGENCE, SIMULTANEOUS_CONVERGENCE]:
posx -= SFC_SIMULTANEOUS_SEQUENCE_EXTRA
width += SFC_SIMULTANEOUS_SEQUENCE_EXTRA * 2
- dc.DrawRectangle(int(round((posx - 1) * scalex)) - 2,
- int(round((self.Pos.y - 1) * scaley)) - 2,
- int(round((width + 3) * scalex)) + 5,
+ dc.DrawRectangle(int(round((posx - 1) * scalex)) - 2,
+ int(round((self.Pos.y - 1) * scaley)) - 2,
+ int(round((width + 3) * scalex)) + 5,
int(round((self.Size.height + 3) * scaley)) + 5)
dc.SetLogicalFunction(wx.COPY)
dc.SetUserScale(scalex, scaley)
-
+
# Draws divergence
def Draw(self, dc):
Graphic_Element.Draw(self, dc)
@@ -1487,16 +1487,16 @@
if self.Type in [SELECTION_DIVERGENCE, SELECTION_CONVERGENCE]:
dc.DrawRectangle(self.Pos.x, self.Pos.y, self.Size[0] + 1, self.Size[1] + 1)
elif self.Type in [SIMULTANEOUS_DIVERGENCE, SIMULTANEOUS_CONVERGENCE]:
- dc.DrawLine(self.Pos.x - SFC_SIMULTANEOUS_SEQUENCE_EXTRA, self.Pos.y,
+ dc.DrawLine(self.Pos.x - SFC_SIMULTANEOUS_SEQUENCE_EXTRA, self.Pos.y,
self.Pos.x + self.Size[0] + SFC_SIMULTANEOUS_SEQUENCE_EXTRA + 1, self.Pos.y)
- dc.DrawLine(self.Pos.x - SFC_SIMULTANEOUS_SEQUENCE_EXTRA, self.Pos.y + self.Size[1],
+ dc.DrawLine(self.Pos.x - SFC_SIMULTANEOUS_SEQUENCE_EXTRA, self.Pos.y + self.Size[1],
self.Pos.x + self.Size[0] + SFC_SIMULTANEOUS_SEQUENCE_EXTRA + 1, self.Pos.y + self.Size[1])
# Draw inputs and outputs connectors
for input in self.Inputs:
input.Draw(dc)
for output in self.Outputs:
output.Draw(dc)
-
+
#-------------------------------------------------------------------------------
# Sequencial Function Chart Jump to Step
@@ -1507,7 +1507,7 @@
"""
class SFC_Jump(Graphic_Element):
-
+
# Create a new jump
def __init__(self, parent, target, id = None):
Graphic_Element.__init__(self, parent)
@@ -1519,19 +1519,19 @@
self.Input = Connector(self, "", None, wx.Point(self.Size[0] / 2, 0), NORTH, onlyone = True)
self.Value = None
self.PreviousValue = None
-
+
def Flush(self):
if self.Input is not None:
self.Input.Flush()
self.Input = None
-
+
def SpreadCurrent(self):
if self.Parent.Debug:
self.PreviousValue = self.Value
self.Value = self.Input.ReceivingCurrent()
if self.Value != self.PreviousValue and self.Visible:
self.Parent.ElementNeedRefresh(self)
-
+
# Make a clone of this SFC_Jump
def Clone(self, parent, id = None, pos = None):
jump = SFC_Jump(parent, self.Target, id)
@@ -1542,10 +1542,10 @@
jump.SetPosition(self.Pos.x, self.Pos.y)
jump.Input = self.Input.Clone(jump)
return jump
-
+
def GetConnectorTranslation(self, element):
return {self.Input : element.Input}
-
+
# Returns the RedrawRect
def GetRedrawRect(self, movex = 0, movey = 0):
rect = Graphic_Element.GetRedrawRect(self, movex, movey)
@@ -1555,29 +1555,29 @@
if self.Input.IsConnected():
rect = rect.Union(self.Input.GetConnectedRedrawRect(movex, movey))
return rect
-
+
# Forbids to change the jump size
def SetSize(self, width, height):
if self.Parent.GetDrawingMode() == FREEDRAWING_MODE:
Graphic_Element.SetSize(self, width, height)
-
+
# Forbids to resize jump
def Resize(self, x, y, width, height):
if self.Parent.GetDrawingMode() == FREEDRAWING_MODE:
Graphic_Element.Resize(self, x, y, width, height)
-
+
# Delete this jump by calling the appropriate method
def Delete(self):
self.Parent.DeleteJump(self)
-
+
# Unconnect input
def Clean(self):
self.Input.UnConnect(delete = self.Parent.GetDrawingMode() == FREEDRAWING_MODE)
-
+
# Refresh the size of text for target
def RefreshTargetSize(self):
self.TargetSize = self.Parent.GetTextExtent(self.Target)
-
+
# Returns if the point given is in the bounding box
def HitTest(self, pt, connectors=True):
# Calculate the bounding box of the condition outside the transition
@@ -1587,22 +1587,22 @@
text_width,
text_height)
return text_bbx.InsideXY(pt.x, pt.y) or Graphic_Element.HitTest(self, pt, connectors)
-
+
# Refresh the jump bounding box
def RefreshBoundingBox(self):
text_width, text_height = self.Parent.GetTextExtent(self.Target)
# Calculate the bounding box size
bbx_width = self.Size[0] + 2 + text_width
- self.BoundingBox = wx.Rect(self.Pos.x, self.Pos.y - CONNECTOR_SIZE,
+ self.BoundingBox = wx.Rect(self.Pos.x, self.Pos.y - CONNECTOR_SIZE,
bbx_width + 1, self.Size[1] + CONNECTOR_SIZE + 1)
-
+
# Returns the connector connected to input
def GetPreviousConnector(self):
wires = self.Input.GetWires()
if len(wires) == 1:
return wires[0][0].GetOtherConnected(self.Input)
return None
-
+
# Refresh the element connectors position
def RefreshConnectors(self):
scaling = self.Parent.GetScaling()
@@ -1611,41 +1611,41 @@
horizontal_pos = round(float(self.Pos.x + horizontal_pos) / float(scaling[0])) * scaling[0] - self.Pos.x
self.Input.SetPosition(wx.Point(horizontal_pos, 0))
self.RefreshConnected()
-
+
# Refresh the position of wires connected to jump
def RefreshConnected(self, exclude = []):
if self.Input:
self.Input.MoveConnected(exclude)
-
- # Returns input jump connector
+
+ # Returns input jump connector
def GetConnector(self, position = None, name = None):
return self.Input
-
- # Returns all the jump connectors
+
+ # Returns all the jump connectors
def GetConnectors(self):
return {"inputs": [self.Input], "outputs": []}
-
+
# Test if point given is on jump input connector
def TestConnector(self, pt, direction = None, exclude = True):
# Test input connector
if self.Input and self.Input.TestPoint(pt, direction, exclude):
return self.Input
return None
-
+
# Changes the jump target
def SetTarget(self, target):
self.Target = target
self.RefreshTargetSize()
self.RefreshBoundingBox()
-
+
# Returns the jump target
def GetTarget(self):
return self.Target
-
+
# Returns the jump minimum size
def GetMinSize(self):
return SFC_JUMP_SIZE
-
+
# Align input element with this jump
def RefreshInputPosition(self):
if self.Input:
@@ -1662,21 +1662,21 @@
input_block.MoveActionBlock((diffx, 0))
input_block.Move(diffx, 0)
input_block.RefreshInputPosition()
-
+
# Can't align output element, because there is no output
def RefreshOutputPosition(self, move = None):
pass
-
+
# Method called when a LeftDClick event have been generated
def OnLeftDClick(self, event, dc, scaling):
# Edit the jump properties
self.Parent.EditJumpContent(self)
-
+
# Method called when a RightUp event have been generated
def OnRightUp(self, event, dc, scaling):
# Popup the default menu
self.Parent.PopupDefaultMenu()
-
+
# Refreshes the jump state according to move defined and handle selected
def ProcessDragging(self, movex, movey, event, scaling):
if self.Parent.GetDrawingMode() != FREEDRAWING_MODE:
@@ -1688,7 +1688,7 @@
return movex, 0
else:
return Graphic_Element.ProcessDragging(self, movex, movey, event, scaling, width_fac = 2)
-
+
# Refresh input element model
def RefreshInputModel(self):
if self.Parent.GetDrawingMode() != FREEDRAWING_MODE:
@@ -1698,32 +1698,32 @@
input_block.RefreshModel(False)
if not isinstance(input_block, SFC_Divergence):
input_block.RefreshInputModel()
-
+
# Refresh output element model
def RefreshOutputModel(self, move=False):
pass
-
+
# Refreshes the jump model
def RefreshModel(self, move=True):
self.Parent.RefreshJumpModel(self)
if move:
if self.Parent.GetDrawingMode() != FREEDRAWING_MODE:
self.RefreshInputModel()
-
+
# Adds an highlight to the variable
def AddHighlight(self, infos, start, end, highlight_type):
if infos[0] == "target" and start[0] == 0 and end[0] == 0:
AddHighlight(self.Highlights, (start, end, highlight_type))
-
+
# Removes an highlight from the variable
def RemoveHighlight(self, infos, start, end, highlight_type):
if infos[0] == "target":
RemoveHighlight(self.Highlights, (start, end, highlight_type))
-
+
# Removes all the highlights of one particular type from the variable
def ClearHighlight(self, highlight_type=None):
ClearHighlights(self.Highlights, highlight_type)
-
+
# Draws the highlightment of this element if it is highlighted
def DrawHighlightment(self, dc):
scalex, scaley = dc.GetUserScale()
@@ -1731,16 +1731,16 @@
dc.SetPen(MiterPen(HIGHLIGHTCOLOR))
dc.SetBrush(wx.Brush(HIGHLIGHTCOLOR))
dc.SetLogicalFunction(wx.AND)
- points = [wx.Point(int(round((self.Pos.x - 2) * scalex)) - 3,
+ points = [wx.Point(int(round((self.Pos.x - 2) * scalex)) - 3,
int(round((self.Pos.y - 2) * scaley)) - 2),
- wx.Point(int(round((self.Pos.x + self.Size[0] + 2) * scalex)) + 4,
+ wx.Point(int(round((self.Pos.x + self.Size[0] + 2) * scalex)) + 4,
int(round((self.Pos.y - 2) * scaley)) - 2),
- wx.Point(int(round((self.Pos.x + self.Size[0] / 2) * scalex)),
+ wx.Point(int(round((self.Pos.x + self.Size[0] / 2) * scalex)),
int(round((self.Pos.y + self.Size[1] + 3) * scaley)) + 4)]
dc.DrawPolygon(points)
dc.SetLogicalFunction(wx.COPY)
dc.SetUserScale(scalex, scaley)
-
+
# Draws divergence
def Draw(self, dc):
Graphic_Element.Draw(self, dc)
@@ -1750,12 +1750,12 @@
else:
dc.SetPen(MiterPen(wx.BLACK))
dc.SetBrush(wx.BLACK_BRUSH)
-
+
if getattr(dc, "printing", False):
target_size = dc.GetTextExtent(self.Target)
else:
target_size = self.TargetSize
-
+
# Draw plain rectangle for representing the divergence
dc.DrawLine(self.Pos.x + self.Size[0] / 2, self.Pos.y, self.Pos.x + self.Size[0] / 2, self.Pos.y + self.Size[1])
points = [wx.Point(self.Pos.x, self.Pos.y),
@@ -1769,10 +1769,10 @@
# Draw input connector
if self.Input:
self.Input.Draw(dc)
-
+
if not getattr(dc, "printing", False):
DrawHighlightedText(dc, self.Target, self.Highlights, target_pos[0], target_pos[1])
-
+
#-------------------------------------------------------------------------------
# Sequencial Function Chart Action Block
@@ -1783,7 +1783,7 @@
"""
class SFC_ActionBlock(Graphic_Element):
-
+
# Create a new action block
def __init__(self, parent, actions = [], id = None):
Graphic_Element.__init__(self, parent)
@@ -1796,19 +1796,19 @@
self.SetActions(actions)
self.Value = None
self.PreviousValue = None
-
+
def Flush(self):
if self.Input is not None:
self.Input.Flush()
self.Input = None
-
+
def SpreadCurrent(self):
if self.Parent.Debug:
self.PreviousValue = self.Value
self.Value = self.Input.ReceivingCurrent()
if self.Value != self.PreviousValue and self.Visible:
self.Parent.ElementNeedRefresh(self)
-
+
# Make a clone of this SFC_ActionBlock
def Clone(self, parent, id = None, pos = None):
actions = [action.copy() for action in self.Actions]
@@ -1820,10 +1820,10 @@
action_block.SetPosition(self.Pos.x, self.Pos.y)
action_block.Input = self.Input.Clone(action_block)
return action_block
-
+
def GetConnectorTranslation(self, element):
return {self.Input : element.Input}
-
+
# Returns the RedrawRect
def GetRedrawRect(self, movex = 0, movey = 0):
rect = Graphic_Element.GetRedrawRect(self, movex, movey)
@@ -1833,17 +1833,17 @@
if self.Input.IsConnected():
rect = rect.Union(self.Input.GetConnectedRedrawRect(movex, movey))
return rect
-
+
# Returns the number of action lines
def GetLineNumber(self):
return len(self.Actions)
-
+
def GetLineSize(self):
if len(self.Actions) > 0:
return self.Size[1] / len(self.Actions)
else:
return SFC_ACTION_MIN_SIZE[1]
-
+
# Forbids to resize the action block
def Resize(self, x, y, width, height):
if self.Parent.GetDrawingMode() != FREEDRAWING_MODE:
@@ -1851,38 +1851,38 @@
self.SetSize(width, self.Size[1])
else:
Graphic_Element.Resize(self, x, y, width, height)
-
+
# Delete this action block by calling the appropriate method
def Delete(self):
self.Parent.DeleteActionBlock(self)
-
+
# Unconnect input and output
def Clean(self):
self.Input.UnConnect(delete = self.Parent.GetDrawingMode() == FREEDRAWING_MODE)
-
+
# Refresh the action block bounding box
def RefreshBoundingBox(self):
self.BoundingBox = wx.Rect(self.Pos.x, self.Pos.y, self.Size[0] + 1, self.Size[1] + 1)
-
+
# Refresh the position of wires connected to action block
def RefreshConnected(self, exclude = []):
self.Input.MoveConnected(exclude)
-
- # Returns input action block connector
+
+ # Returns input action block connector
def GetConnector(self, position = None, name = None):
return self.Input
-
- # Returns all the action block connectors
+
+ # Returns all the action block connectors
def GetConnectors(self):
return {"inputs": [self.Input], "outputs": []}
-
+
# Test if point given is on action block input connector
def TestConnector(self, pt, direction = None, exclude = True):
# Test input connector
if self.Input.TestPoint(pt, direction, exclude):
return self.Input
return None
-
+
# Refresh the element connectors position
def RefreshConnectors(self):
scaling = self.Parent.GetScaling()
@@ -1891,7 +1891,7 @@
vertical_pos = round(float(self.Pos.y + vertical_pos) / float(scaling[1])) * scaling[1] - self.Pos.y
self.Input.SetPosition(wx.Point(0, vertical_pos))
self.RefreshConnected()
-
+
# Changes the action block actions
def SetActions(self, actions):
self.Actions = actions
@@ -1931,25 +1931,25 @@
input_block = wires[0][0].GetOtherConnected(self.Input).GetParentBlock()
input_block.RefreshOutputPosition()
input_block.RefreshOutputModel(True)
-
+
# Returns the action block actions
def GetActions(self):
return self.Actions
-
+
# Returns the action block minimum size
def GetMinSize(self):
return self.MinSize
-
+
# Method called when a LeftDClick event have been generated
def OnLeftDClick(self, event, dc, scaling):
# Edit the action block properties
self.Parent.EditActionBlockContent(self)
-
+
# Method called when a RightUp event have been generated
def OnRightUp(self, event, dc, scaling):
# Popup the default menu
self.Parent.PopupDefaultMenu()
-
+
# Refreshes the action block state according to move defined and handle selected
def ProcessDragging(self, movex, movey, event, scaling):
if self.Parent.GetDrawingMode() != FREEDRAWING_MODE:
@@ -1970,18 +1970,18 @@
else:
return Graphic_Element.ProcessDragging(self, movex, movey, event, scaling)
-
+
# Refreshes the action block model
def RefreshModel(self, move=True):
self.Parent.RefreshActionBlockModel(self)
-
+
# Adds an highlight to the variable
def AddHighlight(self, infos, start, end, highlight_type):
if infos[0] == "action" and infos[1] < len(self.Actions):
action_highlights = self.Highlights.setdefault(infos[1], {})
attribute_highlights = action_highlights.setdefault(infos[2], [])
AddHighlight(attribute_highlights, (start, end, highlight_type))
-
+
# Removes an highlight from the block
def RemoveHighlight(self, infos, start, end, highlight_type):
if infos[0] == "action" and infos[1] < len(self.Actions):
@@ -1991,7 +1991,7 @@
action_highlights.pop(infos[2])
if len(action_highlights) == 0:
self.Highlights.pop(infos[1])
-
+
# Removes all the highlights of one particular type from the block
def ClearHighlight(self, highlight_type=None):
if highlight_type is None:
@@ -2006,7 +2006,7 @@
action_highlights.pop(name)
if len(action_highlights) == 0:
self.Highlights.pop(number)
-
+
# Draws divergence
def Draw(self, dc):
Graphic_Element.Draw(self, dc)
@@ -2018,14 +2018,14 @@
colsize = [self.ColSize[0], self.Size[0] - self.ColSize[0] - self.ColSize[2], self.ColSize[2]]
# Draw plain rectangle for representing the action block
dc.DrawRectangle(self.Pos.x, self.Pos.y, self.Size[0] + 1, self.Size[1] + 1)
- dc.DrawLine(self.Pos.x + colsize[0], self.Pos.y,
+ dc.DrawLine(self.Pos.x + colsize[0], self.Pos.y,
self.Pos.x + colsize[0], self.Pos.y + self.Size[1])
- dc.DrawLine(self.Pos.x + colsize[0] + colsize[1], self.Pos.y,
+ dc.DrawLine(self.Pos.x + colsize[0] + colsize[1], self.Pos.y,
self.Pos.x + colsize[0] + colsize[1], self.Pos.y + self.Size[1])
line_size = self.GetLineSize()
for i, action in enumerate(self.Actions):
if i != 0:
- dc.DrawLine(self.Pos.x, self.Pos.y + i * line_size,
+ dc.DrawLine(self.Pos.x, self.Pos.y + i * line_size,
self.Pos.x + self.Size[0], self.Pos.y + i * line_size)
qualifier_size = dc.GetTextExtent(action.qualifier)
if action.duration != "":
@@ -2048,7 +2048,7 @@
indicator_pos = (self.Pos.x + colsize[0] + colsize[1] + (colsize[2] - indicator_size[0]) / 2,
self.Pos.y + i * line_size + (line_size - indicator_size[1]) / 2)
dc.DrawText(action.indicator, indicator_pos[0], indicator_pos[1])
-
+
if not getattr(dc, "printing", False):
action_highlights = self.Highlights.get(i, {})
for name, attribute_highlights in action_highlights.iteritems():
@@ -2060,7 +2060,6 @@
DrawHighlightedText(dc, action.value, attribute_highlights, content_pos[0], content_pos[1])
elif name == "indicator":
DrawHighlightedText(dc, action.indicator, attribute_highlights, indicator_pos[0], indicator_pos[1])
-
+
# Draw input connector
self.Input.Draw(dc)
-
--- a/graphics/ToolTipProducer.py Fri Aug 11 15:18:19 2017 +0300
+++ b/graphics/ToolTipProducer.py Mon Aug 14 19:13:01 2017 +0300
@@ -25,7 +25,7 @@
import wx
from controls.CustomToolTip import CustomToolTip, TOOLTIP_WAIT_PERIOD
-
+
#-------------------------------------------------------------------------------
# Tool Tip Producer class
#-------------------------------------------------------------------------------
@@ -35,29 +35,29 @@
"""
class ToolTipProducer:
-
+
def __init__(self, parent):
"""
Constructor
@param parent: Parent Viewer
"""
self.Parent = parent
-
+
self.ToolTip = None
self.ToolTipPos = None
-
+
# Timer for firing Tool tip display
self.ToolTipTimer = wx.Timer(self.Parent, -1)
- self.Parent.Bind(wx.EVT_TIMER,
- self.OnToolTipTimer,
+ self.Parent.Bind(wx.EVT_TIMER,
+ self.OnToolTipTimer,
self.ToolTipTimer)
-
+
def __del__(self):
"""
Destructor
"""
self.DestroyToolTip()
-
+
def OnToolTipTimer(self, event):
"""
Callback for Tool Tip firing timer Event
@@ -65,21 +65,21 @@
"""
# Get Tool Tip text
value = self.GetToolTipValue()
-
+
if value is not None and self.ToolTipPos is not None:
# Create Tool Tip
self.ToolTip = CustomToolTip(self.Parent, value)
self.ToolTip.SetToolTipPosition(self.ToolTipPos)
self.ToolTip.Show()
-
+
def GetToolTipValue(self):
"""
Return tool tip text
- Have to be overridden by inherited classes
- @return: Tool tip text (None if not overridden)
+ Have to be overridden by inherited classes
+ @return: Tool tip text (None if not overridden)
"""
return None
-
+
def DisplayToolTip(self, pos):
"""
Display Tool tip
@@ -87,14 +87,14 @@
"""
# Destroy current displayed Tool tip
self.DestroyToolTip()
-
+
# Save Tool Tip position
self.ToolTipPos = pos
# Start Tool tip firing timer
self.ToolTipTimer.Start(
- int(TOOLTIP_WAIT_PERIOD * 1000),
+ int(TOOLTIP_WAIT_PERIOD * 1000),
oneShot=True)
-
+
def SetToolTipText(self, text):
"""
Set current Tool tip text
@@ -102,7 +102,7 @@
"""
if self.ToolTip is not None:
self.ToolTip.SetTip(text)
-
+
def DestroyToolTip(self):
"""
Destroy current displayed Tool Tip
@@ -110,7 +110,7 @@
# Stop Tool tip firing timer
self.ToolTipTimer.Stop()
self.ToolTipPos = None
-
+
# Destroy Tool Tip
if self.ToolTip is not None:
self.ToolTip.Destroy()
--- a/i18n/mki18n.py Fri Aug 11 15:18:19 2017 +0300
+++ b/i18n/mki18n.py Mon Aug 14 19:13:01 2017 +0300
@@ -1,21 +1,21 @@
#! /usr/bin/env python
# -*- coding: iso-8859-1 -*-
-#
+#
# PYTHON MODULE: MKI18N.PY
# =========
-#
+#
# Abstract: Make Internationalization (i18n) files for an application.
-#
+#
# Copyright Pierre Rouleau. 2003. Released to public domain.
-#
+#
# Last update: Saturday, November 8, 2003. @ 15:55:18.
-#
+#
# File: ROUP2003N01::C:/dev/python/mki18n.py
-#
+#
# RCS $Header: //software/official/MKS/MKS_SI/TV_NT/dev/Python/rcs/mki18n.py 1.5 2003/11/05 19:40:04 PRouleau Exp $
-#
+#
# Update history:
-#
+#
# - File created: Saturday, June 7, 2003. by Pierre Rouleau
# - 10/06/03 rcs : RCS Revision 1.1 2003/06/10 10:06:12 PRouleau
# - 10/06/03 rcs : RCS Initial revision
@@ -27,22 +27,22 @@
# - 05/11/03 rcs : RCS Revision 1.4 2003/10/22 06:39:31 PRouleau
# - 05/11/03 P.R.: [code:fix] : included the unixpath() in this file.
# - 08/11/03 rcs : RCS Revision 1.5 2003/11/05 19:40:04 PRouleau
-#
+#
# RCS $Log: $
-#
-#
-# -----------------------------------------------------------------------------
-"""
-mki18n allows you to internationalize your software. You can use it to
+#
+#
+# -----------------------------------------------------------------------------
+"""
+mki18n allows you to internationalize your software. You can use it to
create the GNU .po files (Portable Object) and the compiled .mo files
(Machine Object).
-mki18n module can be used from the command line or from within a script (see
+mki18n module can be used from the command line or from within a script (see
the Usage at the end of this page).
Table of Contents
-----------------
-
+
makePO() -- Build the Portable Object file for the application --
catPO() -- Concatenate one or several PO files with the application domain files. --
makeMO() -- Compile the Portable Object files into the Machine Object stored in the right location. --
@@ -60,24 +60,24 @@
libiconv ftp site`_ and get version 1.9.1 or later. Get the Windows .ZIP
files and install the packages inside c:/gnu. All binaries will be stored
inside c:/gnu/bin. Just put c:/gnu/bin inside your PATH. You will need
- the following files:
-
- - `gettext-runtime-0.12.1.bin.woe32.zip`_
+ the following files:
+
+ - `gettext-runtime-0.12.1.bin.woe32.zip`_
- `gettext-tools-0.12.1.bin.woe32.zip`_
- - `libiconv-1.9.1.bin.woe32.zip`_
+ - `libiconv-1.9.1.bin.woe32.zip`_
.. _GNU libiconv: http://www.gnu.org/software/libiconv/
.. _GNU libiconv ftp site: http://www.ibiblio.org/pub/gnu/libiconv/
-.. _gettext-runtime-0.12.1.bin.woe32.zip: ftp://ftp.gnu.org/gnu/gettext/gettext-runtime-0.12.1.bin.woe32.zip
-.. _gettext-tools-0.12.1.bin.woe32.zip: ftp://ftp.gnu.org/gnu/gettext/gettext-tools-0.12.1.bin.woe32.zip
+.. _gettext-runtime-0.12.1.bin.woe32.zip: ftp://ftp.gnu.org/gnu/gettext/gettext-runtime-0.12.1.bin.woe32.zip
+.. _gettext-tools-0.12.1.bin.woe32.zip: ftp://ftp.gnu.org/gnu/gettext/gettext-tools-0.12.1.bin.woe32.zip
.. _libiconv-1.9.1.bin.woe32.zip: http://www.ibiblio.org/pub/gnu/libiconv/libiconv-1.9.1.bin.woe32.zip
"""
# -----------------------------------------------------------------------------
# Module Import
# -------------
-#
+#
import os
import sys
import wx
@@ -143,24 +143,24 @@
def makePO(applicationDirectoryPath, applicationDomain=None, verbose=0) :
"""Build the Portable Object Template file for the application.
- makePO builds the .pot file for the application stored inside
- a specified directory by running xgettext for all application source
- files. It finds the name of all files by looking for a file called 'app.fil'.
+ makePO builds the .pot file for the application stored inside
+ a specified directory by running xgettext for all application source
+ files. It finds the name of all files by looking for a file called 'app.fil'.
If this file does not exists, makePo raises an IOError exception.
By default the application domain (the application
name) is the same as the directory name but it can be overridden by the
'applicationDomain' argument.
- makePO always creates a new file called messages.pot. If it finds files
- of the form app_xx.po where 'app' is the application name and 'xx' is one
- of the ISO 639 two-letter language codes, makePO resynchronizes those
- files with the latest extracted strings (now contained in messages.pot).
+ makePO always creates a new file called messages.pot. If it finds files
+ of the form app_xx.po where 'app' is the application name and 'xx' is one
+ of the ISO 639 two-letter language codes, makePO resynchronizes those
+ files with the latest extracted strings (now contained in messages.pot).
This process updates all line location number in the language-specific
- .po files and may also create new entries for translation (or comment out
- some). The .po file is not changed, instead a new file is created with
+ .po files and may also create new entries for translation (or comment out
+ some). The .po file is not changed, instead a new file is created with
the .new extension appended to the name of the .po file.
- By default the function does not display what it is doing. Set the
+ By default the function does not display what it is doing. Set the
verbose argument to 1 to force it to print its commands.
"""
@@ -175,10 +175,10 @@
raise IOError(2,'No module file: ' % filelist)
fileout = 'messages.pot'
- # Steps:
+ # Steps:
# Use xgettext to parse all application modules
# The following switches are used:
- #
+ #
# -s : sort output by string content (easier to use when we need to merge several .po files)
# --files-from=app.fil : The list of files is taken from the file: app.fil
# --output= : specifies the name of the output file (using a .pot extension)
@@ -190,12 +190,12 @@
processCustomFiles(filelist, fileout, XSD_STRING_MODEL, 'Extra XSD strings')
XML_TC6_STRING_MODEL = re.compile("<documentation>\s*<xhtml\:p><!\[CDATA\[([^\]]*)\]\]></xhtml\:p>\s*</documentation>", re.MULTILINE | re.DOTALL)
- processCustomFiles(filelist, fileout, XML_TC6_STRING_MODEL, 'Extra TC6 documentation strings')
+ processCustomFiles(filelist, fileout, XML_TC6_STRING_MODEL, 'Extra TC6 documentation strings')
# generate messages.po
cmd = 'msginit --no-wrap --no-translator -i %s -l en_US.UTF-8 -o messages.po' % (fileout)
if verbose: print cmd
- os.system(cmd)
+ os.system(cmd)
languageDict = getlanguageDict()
@@ -251,18 +251,18 @@
# -----------------------------------------------------------------------------
# m a k e M O ( ) -- Compile the Portable Object files into the Machine Object stored in the right location. --
# ^^^^^^^^^^^^^^^
-#
+#
def makeMO(applicationDirectoryPath,targetDir='./locale',applicationDomain=None, verbose=0, forceEnglish=0) :
"""Compile the Portable Object files into the Machine Object stored in the right location.
- makeMO converts all translated language-specific PO files located inside
- the application directory into the binary .MO files stored inside the
+ makeMO converts all translated language-specific PO files located inside
+ the application directory into the binary .MO files stored inside the
LC_MESSAGES sub-directory for the found locale files.
- makeMO searches for all files that have a name of the form 'app_xx.po'
- inside the application directory specified by the first argument. The
- 'app' is the application domain name (that can be specified by the
- applicationDomain argument or is taken from the directory name). The 'xx'
+ makeMO searches for all files that have a name of the form 'app_xx.po'
+ inside the application directory specified by the first argument. The
+ 'app' is the application domain name (that can be specified by the
+ applicationDomain argument or is taken from the directory name). The 'xx'
corresponds to one of the ISO 639 two-letter language codes.
makeMo stores the resulting files inside a sub-directory of `targetDir`
@@ -296,7 +296,7 @@
if verbose: print cmd
os.system(cmd)
os.chdir(currentDir)
-
+
# -----------------------------------------------------------------------------
# p r i n t U s a g e -- Displays how to use this script from the command line --
# ^^^^^^^^^^^^^^^^^^^
@@ -331,7 +331,7 @@
# #
# You must specify one of the -p or -m option to perform the work. You can #
# specify the path of the target application. If you leave it out mki18n #
- # will use the current directory as the application main directory. #
+ # will use the current directory as the application main directory. #
# #
##################################################################################"""
if errorMsg:
@@ -340,14 +340,14 @@
# -----------------------------------------------------------------------------
# f i l e B a s e O f ( ) -- Return base name of filename --
# ^^^^^^^^^^^^^^^^^^^^^^^
-#
+#
def fileBaseOf(filename,withPath=0) :
"""fileBaseOf(filename,withPath) ---> string
Return base name of filename. The returned string never includes the extension.
- Use os.path.basename() to return the basename with the extension. The
- second argument is optional. If specified and if set to 'true' (non zero)
- the string returned contains the full path of the file name. Otherwise the
+ Use os.path.basename() to return the basename with the extension. The
+ second argument is optional. If specified and if set to 'true' (non zero)
+ the string returned contains the full path of the file name. Otherwise the
path is excluded.
[Example]
@@ -370,8 +370,8 @@
'abcdef'
>>> fileBaseOf(fn,1)
'abcdef'
- """
- pos = filename.rfind('.')
+ """
+ pos = filename.rfind('.')
if pos > 0:
filename = filename[:pos]
if withPath:
@@ -381,49 +381,49 @@
# -----------------------------------------------------------------------------
# m k d i r ( ) -- Create a directory (and possibly the entire tree) --
# ^^^^^^^^^^^^^
-#
+#
def mkdir(directory) :
"""Create a directory (and possibly the entire tree).
The os.mkdir() will fail to create a directory if one of the
directory in the specified path does not exist. mkdir()
solves this problem. It creates every intermediate directory
- required to create the final path. Under Unix, the function
+ required to create the final path. Under Unix, the function
only supports forward slash separator, but under Windows and MacOS
the function supports the forward slash and the OS separator (backslash
under windows).
- """
+ """
# translate the path separators
directory = unixpath(directory)
# build a list of all directory elements
aList = filter(lambda x: len(x)>0, directory.split('/'))
- theLen = len(aList)
+ theLen = len(aList)
# if the first element is a Windows-style disk drive
# concatenate it with the first directory
if aList[0].endswith(':'):
if theLen > 1:
aList[1] = aList[0] + '/' + aList[1]
- del aList[0]
- theLen -= 1
+ del aList[0]
+ theLen -= 1
# if the original directory starts at root,
- # make sure the first element of the list
+ # make sure the first element of the list
# starts at root too
- if directory[0] == '/':
+ if directory[0] == '/':
aList[0] = '/' + aList[0]
- # Now iterate through the list, check if the
+ # Now iterate through the list, check if the
# directory exists and if not create it
theDir = ''
for i in range(theLen):
theDir += aList[i]
if not os.path.exists(theDir):
os.mkdir(theDir)
- theDir += '/'
-
+ theDir += '/'
+
# -----------------------------------------------------------------------------
# u n i x p a t h ( ) -- Return a path name that contains Unix separator. --
# ^^^^^^^^^^^^^^^^^^^
-#
+#
def unixpath(thePath) :
r"""Return a path name that contains Unix separator.
@@ -432,7 +432,7 @@
'd:/test'
>>> unixpath("d:/test/file.txt")
'd:/test/file.txt'
- >>>
+ >>>
"""
thePath = os.path.normpath(thePath)
if os.sep == '/':
@@ -440,11 +440,11 @@
else:
return thePath.replace(os.sep,'/')
-# -----------------------------------------------------------------------------
+# -----------------------------------------------------------------------------
# S c r i p t e x e c u t i o n -- Runs when invoked from the command line --
# ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-#
+#
if __name__ == "__main__":
import getopt # command line parsing
argc = len(sys.argv)
@@ -453,11 +453,11 @@
sys.exit(1)
# If there is some arguments, parse the command line
validOptions = "ehmpv"
- validLongOptions = ['domain=', 'moTarget=']
+ validLongOptions = ['domain=', 'moTarget=']
option = {}
option['forceEnglish'] = 0
option['mo'] = 0
- option['po'] = 0
+ option['po'] = 0
option['verbose'] = 0
option['domain'] = None
option['moTarget'] = None
@@ -465,11 +465,11 @@
optionList,pargs = getopt.getopt(sys.argv[1:],validOptions,validLongOptions)
except getopt.GetoptError, e:
printUsage(e[0])
- sys.exit(1)
+ sys.exit(1)
for (opt,val) in optionList:
- if (opt == '-h'):
+ if (opt == '-h'):
printUsage()
- sys.exit(0)
+ sys.exit(0)
elif (opt == '-e'): option['forceEnglish'] = 1
elif (opt == '-m'): option['mo'] = 1
elif (opt == '-p'): option['po'] = 1
@@ -497,7 +497,7 @@
printUsage(e[1] + '\n You must write a file app.fil that contains the list of all files to parse.')
if option['mo']:
makeMO(appDirPath,option['moTarget'],option['domain'],option['verbose'],option['forceEnglish'])
- sys.exit(1)
-
-
-# -----------------------------------------------------------------------------
+ sys.exit(1)
+
+
+# -----------------------------------------------------------------------------
--- a/plcopen/plcopen.py Fri Aug 11 15:18:19 2017 +0300
+++ b/plcopen/plcopen.py Mon Aug 14 19:13:01 2017 +0300
@@ -49,14 +49,14 @@
VarOrder = ["Local","Temp","Input","Output","InOut","External","Global","Access"]
"""
-Define which action qualifier must be associated with a duration
+Define which action qualifier must be associated with a duration
"""
-QualifierList = OrderedDict([("N", False), ("R", False), ("S", False),
- ("L", True), ("D", True), ("P", False), ("P0", False),
+QualifierList = OrderedDict([("N", False), ("R", False), ("S", False),
+ ("L", True), ("D", True), ("P", False), ("P0", False),
("P1", False), ("SD", True), ("DS", True), ("SL", True)])
-FILTER_ADDRESS_MODEL = "(%%[IQM](?:[XBWDL])?)(%s)((?:\.[0-9]+)*)"
+FILTER_ADDRESS_MODEL = "(%%[IQM](?:[XBWDL])?)(%s)((?:\.[0-9]+)*)"
def update_address(address, address_model, new_leading):
result = address_model.match(address)
@@ -73,10 +73,10 @@
return v1
"""
-Helper class for bounding_box calculation
+Helper class for bounding_box calculation
"""
class rect:
-
+
def __init__(self, x=None, y=None, width=None, height=None):
self.x_min = x
self.x_max = None
@@ -86,19 +86,19 @@
self.x_max = x + width
if height is not None and y is not None:
self.y_max = y + height
-
+
def update(self, x, y):
self.x_min = _init_and_compare(min, self.x_min, x)
self.x_max = _init_and_compare(max, self.x_max, x)
self.y_min = _init_and_compare(min, self.y_min, y)
self.y_max = _init_and_compare(max, self.y_max, y)
-
+
def union(self, rect):
self.x_min = _init_and_compare(min, self.x_min, rect.x_min)
self.x_max = _init_and_compare(max, self.x_max, rect.x_max)
self.y_min = _init_and_compare(min, self.y_min, rect.y_min)
self.y_max = _init_and_compare(max, self.y_max, rect.y_max)
-
+
def bounding_box(self):
width = height = None
if self.x_min is not None and self.x_max is not None:
@@ -125,7 +125,7 @@
test_result = []
result = criteria["pattern"].search(text)
while result is not None:
- prev_pos=result.endpos
+ prev_pos=result.endpos
start = TextLenInRowColumn(text[:result.start()])
end = TextLenInRowColumn(text[:result.end() - 1])
test_result.append((start, end, "\n".join(lines[start[0]:end[0] + 1])))
@@ -141,11 +141,11 @@
PLCOpen_XPath = lambda xpath: etree.XPath(xpath, namespaces=PLCOpenParser.NSMAP)
LOAD_POU_PROJECT_TEMPLATE = """
-<project xmlns:ns1="http://www.plcopen.org/xml/tc6_0201"
- xmlns:xhtml="http://www.w3.org/1999/xhtml"
- xmlns:xsd="http://www.w3.org/2001/XMLSchema"
+<project xmlns:ns1="http://www.plcopen.org/xml/tc6_0201"
+ xmlns:xhtml="http://www.w3.org/1999/xhtml"
+ xmlns:xsd="http://www.w3.org/2001/XMLSchema"
xmlns="http://www.plcopen.org/xml/tc6_0201">
- <fileHeader companyName="" productName="" productVersion=""
+ <fileHeader companyName="" productName="" productVersion=""
creationDateTime="1970-01-01T00:00:00"/>
<contentHeader name="paste_project">
<coordinateInfo>
@@ -176,8 +176,8 @@
PLCOpen_v1_xml = PLCOpen_v1_file.read()
PLCOpen_v1_file.close()
PLCOpen_v1_xml = PLCOpen_v1_xml.replace(
- "http://www.plcopen.org/xml/tc6.xsd",
- "http://www.plcopen.org/xml/tc6_0201")
+ "http://www.plcopen.org/xml/tc6.xsd",
+ "http://www.plcopen.org/xml/tc6_0201")
PLCOpen_v1_xsd = etree.XMLSchema(etree.fromstring(PLCOpen_v1_xml))
# XPath for file compatibility process
@@ -190,21 +190,21 @@
def LoadProjectXML(project_xml):
project_xml = project_xml.replace(
- "http://www.plcopen.org/xml/tc6.xsd",
+ "http://www.plcopen.org/xml/tc6.xsd",
"http://www.plcopen.org/xml/tc6_0201")
for cre, repl in [
(re.compile("(?<!<xhtml:p>)(?:<!\[CDATA\[)"), "<xhtml:p><![CDATA["),
(re.compile("(?:]]>)(?!</xhtml:p>)"), "]]></xhtml:p>")]:
project_xml = cre.sub(repl, project_xml)
-
+
try:
tree, error = PLCOpenParser.LoadXMLString(project_xml)
if error is None:
return tree, None
-
+
if PLCOpen_v1_xsd.validate(tree):
# Make file compatible with PLCOpen v2
-
+
# Update resource interval value
for resource in ProjectResourcesXPath(tree):
for task in resource.gettask():
@@ -229,13 +229,13 @@
else:
text += "%dms"%(time_values[3] / 1000)
task.set("interval", text)
-
+
# Update resources pou instance attributes
for pouInstance in ResourceInstancesXpath(resource):
type_name = pouInstance.attrib.pop("type")
if type_name is not None:
pouInstance.set("typeName", type_name)
-
+
# Update transitions condition
for transition_condition in TransitionsConditionXPath(tree):
connections = ConditionConnectionsXPath(transition_condition)
@@ -245,23 +245,23 @@
connectionPointIn.setrelPositionXY(0, 0)
for connection in connections:
connectionPointIn.append(connection)
-
+
# Update actionBlocks
for actionBlock in ActionBlocksXPath(tree):
for connectionPointOut in ActionBlocksConnectionPointOutXPath(actionBlock):
actionBlock.remove(connectionPointOut)
-
+
for action in actionBlock.getaction():
action.set("localId", "0")
relPosition = PLCOpenParser.CreateElement("relPosition", "action")
relPosition.set("x", "0")
relPosition.set("y", "0")
action.setrelPosition(relPosition)
-
+
return tree, None
-
+
return tree, error
-
+
except Exception, e:
return None, e.message
@@ -288,9 +288,9 @@
def SaveProject(project, filepath):
project_file = open(filepath, 'w')
project_file.write(etree.tostring(
- project,
- pretty_print=True,
- xml_declaration=True,
+ project,
+ pretty_print=True,
+ xml_declaration=True,
encoding='utf-8'))
project_file.close()
@@ -302,7 +302,7 @@
text = pattern.sub(new_name, text)
self.setanyText(text)
setattr(cls, "updateElementName", updateElementName)
-
+
def updateElementAddress(self, address_model, new_leading):
text = self.getanyText()
startpos = 0
@@ -315,28 +315,28 @@
result = address_model.search(text, startpos)
self.setanyText(text)
setattr(cls, "updateElementAddress", updateElementAddress)
-
+
def hasblock(self, block_type):
- text = self.getanyText()
+ text = self.getanyText()
pattern = re.compile('\\b' + block_type + '\\b', re.IGNORECASE)
return pattern.search(text) is not None
setattr(cls, "hasblock", hasblock)
-
+
def Search(self, criteria, parent_infos):
return [(tuple(parent_infos),) + result for result in TestTextElement(self.getanyText(), criteria)]
setattr(cls, "Search", Search)
-
+
cls = PLCOpenParser.GetElementClass("project")
if cls:
-
+
def setname(self, name):
self.contentHeader.setname(name)
setattr(cls, "setname", setname)
-
+
def getname(self):
return self.contentHeader.getname()
setattr(cls, "getname", getname)
-
+
def getfileHeader(self):
fileheader_obj = self.fileHeader
return {
@@ -351,7 +351,7 @@
("contentDescription", fileheader_obj.getcontentDescription())]
}
setattr(cls, "getfileHeader", getfileHeader)
-
+
def setfileHeader(self, fileheader):
fileheader_obj = self.fileHeader
for attr in ["companyName", "companyURL", "productName",
@@ -361,7 +361,7 @@
if value is not None:
setattr(fileheader_obj, attr, value)
setattr(cls, "setfileHeader", setfileHeader)
-
+
def getcontentHeader(self):
contentheader_obj = self.contentHeader
contentheader = {
@@ -378,7 +378,7 @@
contentheader["scaling"] = self.contentHeader.getscaling()
return contentheader
setattr(cls, "getcontentHeader", getcontentHeader)
-
+
def setcontentHeader(self, contentheader):
contentheader_obj = self.contentHeader
for attr, value in contentheader.iteritems():
@@ -392,7 +392,7 @@
elif attr in ["modificationDateTime", "organization", "language"]:
setattr(contentheader_obj, attr, value)
setattr(cls, "setcontentHeader", setcontentHeader)
-
+
def gettypeElementFunc(element_type):
elements_xpath = PLCOpen_XPath(
"ppx:types/ppx:%(element_type)ss/ppx:%(element_type)s[@name=$name]" % locals())
@@ -402,7 +402,7 @@
return elements[0]
return None
return gettypeElement
-
+
datatypes_xpath = PLCOpen_XPath("ppx:types/ppx:dataTypes/ppx:dataType")
filtered_datatypes_xpath = PLCOpen_XPath(
"ppx:types/ppx:dataTypes/ppx:dataType[@name!=$exclude]")
@@ -411,43 +411,43 @@
return filtered_datatypes_xpath(self, exclude=exclude)
return datatypes_xpath(self)
setattr(cls, "getdataTypes", getdataTypes)
-
+
setattr(cls, "getdataType", gettypeElementFunc("dataType"))
-
+
def appenddataType(self, name):
if self.getdataType(name) is not None:
raise ValueError, "\"%s\" Data Type already exists !!!"%name
self.types.appenddataTypeElement(name)
setattr(cls, "appenddataType", appenddataType)
-
+
def insertdataType(self, index, datatype):
self.types.insertdataTypeElement(index, datatype)
setattr(cls, "insertdataType", insertdataType)
-
+
def removedataType(self, name):
self.types.removedataTypeElement(name)
setattr(cls, "removedataType", removedataType)
-
+
def getpous(self, exclude=None, filter=[]):
return self.xpath(
- "ppx:types/ppx:pous/ppx:pou%s%s" %
+ "ppx:types/ppx:pous/ppx:pou%s%s" %
(("[@name!='%s']" % exclude) if exclude is not None else '',
("[%s]" % " or ".join(
map(lambda x: "@pouType='%s'" % x, filter)))
if len(filter) > 0 else ""),
namespaces=PLCOpenParser.NSMAP)
setattr(cls, "getpous", getpous)
-
+
setattr(cls, "getpou", gettypeElementFunc("pou"))
-
+
def appendpou(self, name, pou_type, body_type):
self.types.appendpouElement(name, pou_type, body_type)
setattr(cls, "appendpou", appendpou)
-
+
def insertpou(self, index, pou):
self.types.insertpouElement(index, pou)
setattr(cls, "insertpou", insertpou)
-
+
def removepou(self, name):
self.types.removepouElement(name)
setattr(cls, "removepou", removepou)
@@ -473,7 +473,7 @@
new_configuration = PLCOpenParser.CreateElement("configuration", "configurations")
new_configuration.setname(name)
self.instances.configurations.appendconfiguration(new_configuration)
- setattr(cls, "addconfiguration", addconfiguration)
+ setattr(cls, "addconfiguration", addconfiguration)
def removeconfiguration(self, name):
configuration = self.getconfiguration(name)
@@ -481,7 +481,7 @@
raise ValueError, ("\"%s\" configuration doesn't exist !!!") % name
self.instances.configurations.remove(configuration)
setattr(cls, "removeconfiguration", removeconfiguration)
-
+
resources_xpath = PLCOpen_XPath(
"ppx:instances/ppx:configurations/ppx:configuration[@name=$configname]/ppx:resource[@name=$name]")
def getconfigurationResource(self, config_name, name):
@@ -562,11 +562,11 @@
cls = PLCOpenParser.GetElementClass("contentHeader", "project")
if cls:
-
+
def setpageSize(self, width, height):
self.coordinateInfo.setpageSize(width, height)
setattr(cls, "setpageSize", setpageSize)
-
+
def getpageSize(self):
return self.coordinateInfo.getpageSize()
setattr(cls, "getpageSize", getpageSize)
@@ -575,7 +575,7 @@
for language, (x, y) in scaling.items():
self.coordinateInfo.setscaling(language, x, y)
setattr(cls, "setscaling", setscaling)
-
+
def getscaling(self):
scaling = {}
scaling["FBD"] = self.coordinateInfo.getscaling("FBD")
@@ -595,7 +595,7 @@
self.pageSize.setx(width)
self.pageSize.sety(height)
setattr(cls, "setpageSize", setpageSize)
-
+
def getpageSize(self):
if self.pageSize is not None:
return self.pageSize.getx(), self.pageSize.gety()
@@ -613,7 +613,7 @@
self.sfc.scaling.setx(x)
self.sfc.scaling.sety(y)
setattr(cls, "setscaling", setscaling)
-
+
def getscaling(self, language):
if language == "FBD":
return self.fbd.scaling.getx(), self.fbd.scaling.gety()
@@ -685,7 +685,7 @@
cls = PLCOpenParser.GetElementClass("configuration", "configurations")
if cls:
-
+
def addglobalVar(self, var_type, name, location="", description=""):
globalvars = self.getglobalVars()
if len(globalvars) == 0:
@@ -701,7 +701,7 @@
var.setdocumentation(ft)
globalvars[-1].appendvariable(var)
setattr(cls, "addglobalVar", addglobalVar)
-
+
def updateElementName(self, old_name, new_name):
_updateConfigurationResourceElementName(self, old_name, new_name)
for resource in self.getresource():
@@ -727,7 +727,7 @@
search_result.extend(resource.Search(criteria, parent_infos))
return search_result
setattr(cls, "Search", Search)
-
+
cls = PLCOpenParser.GetElementClass("resource", "configuration")
if cls:
def updateElementName(self, old_name, new_name):
@@ -788,7 +788,7 @@
setattr(cls, "updateElementAddress", updateElementAddress)
def Search(self, criteria, parent_infos=[]):
- return _Search([("single", self.getsingle()),
+ return _Search([("single", self.getsingle()),
("interval", self.getinterval()),
("priority", str(self.getpriority()))],
criteria, parent_infos)
@@ -802,7 +802,7 @@
setattr(cls, "updateElementName", updateElementName)
def Search(self, criteria, parent_infos=[]):
- return _Search([("name", self.getname()),
+ return _Search([("name", self.getname()),
("type", self.gettypeName())],
criteria, parent_infos)
setattr(cls, "Search", Search)
@@ -822,22 +822,22 @@
elif vartype_content_name == "array":
base_type = vartype_content.baseType.getcontent()
base_type_name = base_type.getLocalTag()
- # Array derived directly from a user defined type
+ # Array derived directly from a user defined type
if base_type_name == "derived":
basetype_name = base_type.getname()
- # Array derived directly from a string type
+ # Array derived directly from a string type
elif base_type_name in ["string", "wstring"]:
basetype_name = base_type_name.upper()
- # Array derived directly from an elementary type
+ # Array derived directly from an elementary type
else:
basetype_name = base_type_name
return "ARRAY [%s] OF %s" % (",".join(map(lambda x : "%s..%s" % (x.getlower(), x.getupper()), vartype_content.getdimension())), basetype_name)
# Variable type is an elementary type
return vartype_content_name
setattr(cls, "gettypeAsText", gettypeAsText)
-
+
def Search(self, criteria, parent_infos=[]):
- search_result = _Search([("name", self.getname()),
+ search_result = _Search([("name", self.getname()),
("type", self.gettypeAsText()),
("location", self.getaddress())],
criteria, parent_infos)
@@ -855,7 +855,7 @@
def getdataTypeElements(self):
return self.dataTypes.getdataType()
setattr(cls, "getdataTypeElements", getdataTypeElements)
-
+
def getdataTypeElement(self, name):
elements = self.dataTypes.getdataType()
for element in elements:
@@ -870,11 +870,11 @@
new_datatype.setname(name)
new_datatype.baseType.setcontent(PLCOpenParser.CreateElement("BOOL", "dataType"))
setattr(cls, "appenddataTypeElement", appenddataTypeElement)
-
+
def insertdataTypeElement(self, index, dataType):
self.dataTypes.insertdataType(index, dataType)
setattr(cls, "insertdataTypeElement", insertdataTypeElement)
-
+
def removedataTypeElement(self, name):
found = False
for element in self.dataTypes.getdataType():
@@ -885,11 +885,11 @@
if not found:
raise ValueError, _("\"%s\" Data Type doesn't exist !!!")%name
setattr(cls, "removedataTypeElement", removedataTypeElement)
-
+
def getpouElements(self):
return self.pous.getpou()
setattr(cls, "getpouElements", getpouElements)
-
+
def getpouElement(self, name):
elements = self.pous.getpou()
for element in elements:
@@ -909,11 +909,11 @@
new_pou.appendbody(PLCOpenParser.CreateElement("body", "pou"))
new_pou.setbodyType(body_type)
setattr(cls, "appendpouElement", appendpouElement)
-
+
def insertpouElement(self, index, pou):
self.pous.insertpou(index, pou)
setattr(cls, "insertpouElement", insertpouElement)
-
+
def removepouElement(self, name):
found = False
for element in self.pous.getpou():
@@ -941,7 +941,7 @@
cls = PLCOpenParser.GetElementClass("dataType", "dataTypes")
if cls:
setattr(cls, "updateElementName", _updateBaseTypeElementName)
-
+
def Search(self, criteria, parent_infos=[]):
search_result = []
filter = criteria["filter"]
@@ -956,7 +956,7 @@
cls = PLCOpenParser.GetElementClass("dataType")
if cls:
-
+
def updateElementName(self, old_name, new_name):
content_name = self.content.getLocalTag()
if content_name in ["derived", "array", "subrangeSigned", "subrangeUnsigned"]:
@@ -987,7 +987,7 @@
if TextMatched(self.name, old_name):
self.name = new_name
setattr(cls, "updateElementName", updateElementName)
-
+
def Search(self, criteria, parent_infos=[]):
return [(tuple(parent_infos),) + result for result in TestTextElement(self.name, criteria)]
setattr(cls, "Search", Search)
@@ -995,7 +995,7 @@
cls = PLCOpenParser.GetElementClass("array", "dataType")
if cls:
setattr(cls, "updateElementName", _updateBaseTypeElementName)
-
+
def Search(self, criteria, parent_infos=[]):
search_result = self.baseType.Search(criteria, parent_infos)
for i, dimension in enumerate(self.getdimension()):
@@ -1024,11 +1024,11 @@
cls = PLCOpenParser.GetElementClass("enum", "dataType")
if cls:
-
+
def updateElementName(self, old_name, new_name):
pass
setattr(cls, "updateElementName", updateElementName)
-
+
enumerated_datatype_values_xpath = PLCOpen_XPath("ppx:values/ppx:value")
def Search(self, criteria, parent_infos=[]):
search_result = []
@@ -1044,21 +1044,21 @@
if type_content_type == "derived":
return type_content.getname()
return type_content_type.upper()
-
+
cls = PLCOpenParser.GetElementClass("pou", "pous")
if cls:
-
+
block_inputs_xpath = PLCOpen_XPath(
"ppx:interface/*[self::ppx:inputVars or self::ppx:inOutVars]/ppx:variable")
block_outputs_xpath = PLCOpen_XPath(
"ppx:interface/*[self::ppx:outputVars or self::ppx:inOutVars]/ppx:variable")
- def getblockInfos(self):
+ def getblockInfos(self):
block_infos = {
- "name" : self.getname(),
- "type" : self.getpouType(),
+ "name" : self.getname(),
+ "type" : self.getpouType(),
"extensible" : False,
- "inputs" : [],
- "outputs" : [],
+ "inputs" : [],
+ "outputs" : [],
"comment" : self.getdescription()}
if self.interface is not None:
return_type = self.interface.getreturnType()
@@ -1071,15 +1071,15 @@
block_infos["outputs"].extend(
[(var.getname(), _getvariableTypeinfos(var.type), "none")
for var in block_outputs_xpath(self)])
-
- block_infos["usage"] = ("\n (%s) => (%s)" %
- (", ".join(["%s:%s" % (input[1], input[0])
+
+ block_infos["usage"] = ("\n (%s) => (%s)" %
+ (", ".join(["%s:%s" % (input[1], input[0])
for input in block_infos["inputs"]]),
- ", ".join(["%s:%s" % (output[1], output[0])
+ ", ".join(["%s:%s" % (output[1], output[0])
for output in block_infos["outputs"]])))
return block_infos
setattr(cls, "getblockInfos", getblockInfos)
-
+
def setdescription(self, description):
doc = self.getdocumentation()
if doc is None:
@@ -1087,14 +1087,14 @@
self.setdocumentation(doc)
doc.setanyText(description)
setattr(cls, "setdescription", setdescription)
-
+
def getdescription(self):
doc = self.getdocumentation()
if doc is not None:
return doc.getanyText()
return ""
setattr(cls, "getdescription", getdescription)
-
+
def setbodyType(self, body_type):
if len(self.body) > 0:
if body_type in ["IL", "ST", "LD", "FBD", "SFC"]:
@@ -1102,66 +1102,66 @@
else:
raise ValueError, "%s isn't a valid body type!"%type
setattr(cls, "setbodyType", setbodyType)
-
+
def getbodyType(self):
if len(self.body) > 0:
return self.body[0].getcontent().getLocalTag()
setattr(cls, "getbodyType", getbodyType)
-
+
def resetexecutionOrder(self):
if len(self.body) > 0:
self.body[0].resetexecutionOrder()
setattr(cls, "resetexecutionOrder", resetexecutionOrder)
-
+
def compileexecutionOrder(self):
if len(self.body) > 0:
self.body[0].compileexecutionOrder()
setattr(cls, "compileexecutionOrder", compileexecutionOrder)
-
+
def setelementExecutionOrder(self, instance, new_executionOrder):
if len(self.body) > 0:
self.body[0].setelementExecutionOrder(instance, new_executionOrder)
setattr(cls, "setelementExecutionOrder", setelementExecutionOrder)
-
+
def addinstance(self, instance):
if len(self.body) > 0:
self.body[0].appendcontentInstance(instance)
setattr(cls, "addinstance", addinstance)
-
+
def getinstances(self):
if len(self.body) > 0:
return self.body[0].getcontentInstances()
return []
setattr(cls, "getinstances", getinstances)
-
+
def getinstance(self, id):
if len(self.body) > 0:
return self.body[0].getcontentInstance(id)
return None
setattr(cls, "getinstance", getinstance)
-
+
def getinstancesIds(self):
if len(self.body) > 0:
return self.body[0].getcontentInstancesIds()
return []
setattr(cls, "getinstancesIds", getinstancesIds)
-
+
def getinstanceByName(self, name):
if len(self.body) > 0:
return self.body[0].getcontentInstanceByName(name)
return None
setattr(cls, "getinstanceByName", getinstanceByName)
-
+
def removeinstance(self, id):
if len(self.body) > 0:
self.body[0].removecontentInstance(id)
setattr(cls, "removeinstance", removeinstance)
-
+
def settext(self, text):
if len(self.body) > 0:
self.body[0].settext(text)
setattr(cls, "settext", settext)
-
+
def gettext(self):
if len(self.body) > 0:
return self.body[0].gettext()
@@ -1178,17 +1178,17 @@
vars.append((reverse_types[varlist.getLocalTag()], varlist))
return vars
setattr(cls, "getvars", getvars)
-
+
def setvars(self, vars):
if self.interface is None:
self.interface = PLCOpenParser.CreateElement("interface", "pou")
self.interface.setcontent(vars)
setattr(cls, "setvars", setvars)
-
+
def addpouExternalVar(self, var_type, name):
self.addpouVar(var_type, name, "externalVars")
setattr(cls, "addpouExternalVar", addpouExternalVar)
-
+
def addpouVar(self, var_type, name, var_class="localVars", location="", description="", initval=""):
if self.interface is None:
self.interface = PLCOpenParser.CreateElement("interface", "pou")
@@ -1218,11 +1218,11 @@
el = PLCOpenParser.CreateElement("initialValue", "variable")
el.setvalue(initval)
var.setinitialValue(el)
-
+
varlist.appendvariable(var)
setattr(cls, "addpouVar", addpouVar)
setattr(cls, "addpouLocalVar", addpouVar)
-
+
def changepouVar(self, old_type, old_name, new_type, new_name):
if self.interface is not None:
content = self.interface.getcontent()
@@ -1236,7 +1236,7 @@
vartype_content.setname(new_type)
return
setattr(cls, "changepouVar", changepouVar)
-
+
def removepouVar(self, var_type, name):
if self.interface is not None:
content = self.interface.getcontent()
@@ -1255,14 +1255,14 @@
if self.getbodyType() in ["SFC"]:
for instance in self.getinstances():
if isinstance(instance, PLCOpenParser.GetElementClass("step", "sfcObjects")) and TextMatched(instance.getname(), name):
- return True
+ return True
return False
setattr(cls, "hasstep", hasstep)
-
+
def hasblock(self, name=None, block_type=None):
if self.getbodyType() in ["FBD", "LD", "SFC"]:
for instance in self.getinstances():
- if (isinstance(instance, PLCOpenParser.GetElementClass("block", "fbdObjects")) and
+ if (isinstance(instance, PLCOpenParser.GetElementClass("block", "fbdObjects")) and
(TextMatched(instance.getinstanceName(), name) or TextMatched(instance.gettypeName(), block_type))):
return True
if self.transitions:
@@ -1279,7 +1279,7 @@
return self.body[0].hasblock(block_type)
return False
setattr(cls, "hasblock", hasblock)
-
+
def addtransition(self, name, body_type):
if self.transitions is None:
self.addtransitions()
@@ -1291,7 +1291,7 @@
if body_type == "ST":
transition.settext(":= ;")
setattr(cls, "addtransition", addtransition)
-
+
def gettransition(self, name):
if self.transitions is not None:
for transition in self.transitions.gettransition():
@@ -1299,13 +1299,13 @@
return transition
return None
setattr(cls, "gettransition", gettransition)
-
+
def gettransitionList(self):
if self.transitions is not None:
return self.transitions.gettransition()
return []
setattr(cls, "gettransitionList", gettransitionList)
-
+
def removetransition(self, name):
if self.transitions is not None:
removed = False
@@ -1314,7 +1314,7 @@
if transition.getbodyType() in ["FBD", "LD", "SFC"]:
for instance in transition.getinstances():
if isinstance(instance, PLCOpenParser.GetElementClass("block", "fbdObjects")):
- self.removepouVar(instance.gettypeName(),
+ self.removepouVar(instance.gettypeName(),
instance.getinstanceName())
self.transitions.remove(transition)
removed = True
@@ -1332,7 +1332,7 @@
action.setname(name)
action.setbodyType(body_type)
setattr(cls, "addaction", addaction)
-
+
def getaction(self, name):
if self.actions is not None:
for action in self.actions.getaction():
@@ -1340,13 +1340,13 @@
return action
return None
setattr(cls, "getaction", getaction)
-
+
def getactionList(self):
if self.actions is not None:
return self.actions.getaction()
return []
setattr(cls, "getactionList", getactionList)
-
+
def removeaction(self, name):
if self.actions is not None:
removed = False
@@ -1355,7 +1355,7 @@
if action.getbodyType() in ["FBD", "LD", "SFC"]:
for instance in action.getinstances():
if isinstance(instance, PLCOpenParser.GetElementClass("block", "fbdObjects")):
- self.removepouVar(instance.gettypeName(),
+ self.removepouVar(instance.gettypeName(),
instance.getinstanceName())
self.actions.remove(action)
removed = True
@@ -1417,7 +1417,7 @@
if result is not None:
content.remove(variable)
setattr(cls, "removeVariableByFilter", removeVariableByFilter)
-
+
def Search(self, criteria, parent_infos=[]):
search_result = []
filter = criteria["filter"]
@@ -1494,7 +1494,7 @@
def hasblock(self, name=None, block_type=None):
if self.getbodyType() in ["FBD", "LD", "SFC"]:
for instance in self.getinstances():
- if (isinstance(instance, PLCOpenParser.GetElementClass("block", "fbdObjects")) and
+ if (isinstance(instance, PLCOpenParser.GetElementClass("block", "fbdObjects")) and
(TextMatched(instance.getinstanceName(), name) or TextMatched(instance.gettypeName(), block_type))):
return True
elif block_type is not None:
@@ -1506,7 +1506,7 @@
def updateElementAddress(self, address_model, new_leading):
self.body.updateElementAddress(address_model, new_leading)
-
+
cls = PLCOpenParser.GetElementClass("transition", "transitions")
if cls:
@@ -1526,7 +1526,7 @@
setattr(cls, "hasblock", hasblock)
setattr(cls, "updateElementName", updateElementName)
setattr(cls, "updateElementAddress", updateElementAddress)
-
+
def Search(self, criteria, parent_infos):
search_result = []
parent_infos = parent_infos[:-1] + ["T::%s::%s" % (parent_infos[-1].split("::")[1], self.getname())]
@@ -1554,7 +1554,7 @@
setattr(cls, "hasblock", hasblock)
setattr(cls, "updateElementName", updateElementName)
setattr(cls, "updateElementAddress", updateElementAddress)
-
+
def Search(self, criteria, parent_infos):
search_result = []
parent_infos = parent_infos[:-1] + ["A::%s::%s" % (parent_infos[-1].split("::")[1], self.getname())]
@@ -1571,24 +1571,24 @@
def resetcurrentExecutionOrderId(self):
object.__setattr__(self, "currentExecutionOrderId", 0)
setattr(cls, "resetcurrentExecutionOrderId", resetcurrentExecutionOrderId)
-
+
def getnewExecutionOrderId(self):
object.__setattr__(self, "currentExecutionOrderId", self.currentExecutionOrderId + 1)
return self.currentExecutionOrderId
setattr(cls, "getnewExecutionOrderId", getnewExecutionOrderId)
-
+
def resetexecutionOrder(self):
if self.content.getLocalTag() == "FBD":
for element in self.content.getcontent():
- if not isinstance(element, (PLCOpenParser.GetElementClass("comment", "commonObjects"),
- PLCOpenParser.GetElementClass("connector", "commonObjects"),
+ if not isinstance(element, (PLCOpenParser.GetElementClass("comment", "commonObjects"),
+ PLCOpenParser.GetElementClass("connector", "commonObjects"),
PLCOpenParser.GetElementClass("continuation", "commonObjects"))):
element.setexecutionOrderId(0)
self.checkedBlocksDict.clear()
else:
raise TypeError, _("Can only generate execution order on FBD networks!")
setattr(cls, "resetexecutionOrder", resetexecutionOrder)
-
+
def compileexecutionOrder(self):
if self.content.getLocalTag() == "FBD":
self.resetexecutionOrder()
@@ -1602,7 +1602,7 @@
else:
raise TypeError, _("Can only generate execution order on FBD networks!")
setattr(cls, "compileexecutionOrder", compileexecutionOrder)
-
+
def compileelementExecutionOrder(self, link):
if self.content.getLocalTag() == "FBD":
localid = link.getrefLocalId()
@@ -1626,7 +1626,7 @@
else:
raise TypeError, _("Can only generate execution order on FBD networks!")
setattr(cls, "compileelementExecutionOrder", compileelementExecutionOrder)
-
+
def setelementExecutionOrder(self, instance, new_executionOrder):
if self.content.getLocalTag() == "FBD":
old_executionOrder = instance.getexecutionOrderId()
@@ -1642,21 +1642,21 @@
else:
raise TypeError, _("Can only generate execution order on FBD networks!")
setattr(cls, "setelementExecutionOrder", setelementExecutionOrder)
-
+
def appendcontentInstance(self, instance):
if self.content.getLocalTag() in ["LD","FBD","SFC"]:
self.content.appendcontent(instance)
else:
raise TypeError, _("%s body don't have instances!")%self.content.getLocalTag()
setattr(cls, "appendcontentInstance", appendcontentInstance)
-
+
def getcontentInstances(self):
if self.content.getLocalTag() in ["LD","FBD","SFC"]:
return self.content.getcontent()
else:
raise TypeError, _("%s body don't have instances!")%self.content.getLocalTag()
setattr(cls, "getcontentInstances", getcontentInstances)
-
+
instance_by_id_xpath = PLCOpen_XPath("*[@localId=$localId]")
instance_by_name_xpath = PLCOpen_XPath("ppx:block[@instanceName=$name]")
def getcontentInstance(self, local_id):
@@ -1668,7 +1668,7 @@
else:
raise TypeError, _("%s body don't have instances!")%self.content.getLocalTag()
setattr(cls, "getcontentInstance", getcontentInstance)
-
+
def getcontentInstancesIds(self):
if self.content.getLocalTag() in ["LD","FBD","SFC"]:
return OrderedDict([(instance.getlocalId(), True)
@@ -1676,7 +1676,7 @@
else:
raise TypeError, _("%s body don't have instances!")%self.content.getLocalTag()
setattr(cls, "getcontentInstancesIds", getcontentInstancesIds)
-
+
def getcontentInstanceByName(self, name):
if self.content.getLocalTag() in ["LD","FBD","SFC"]:
instance = instance_by_name_xpath(self.content)
@@ -1686,7 +1686,7 @@
else:
raise TypeError, _("%s body don't have instances!")%self.content.getLocalTag()
setattr(cls, "getcontentInstanceByName", getcontentInstanceByName)
-
+
def removecontentInstance(self, local_id):
if self.content.getLocalTag() in ["LD","FBD","SFC"]:
instance = instance_by_id_xpath(self.content, localId=local_id)
@@ -1697,7 +1697,7 @@
else:
raise TypeError, "%s body don't have instances!"%self.content.getLocalTag()
setattr(cls, "removecontentInstance", removecontentInstance)
-
+
def settext(self, text):
if self.content.getLocalTag() in ["IL","ST"]:
self.content.setanyText(text)
@@ -1711,14 +1711,14 @@
else:
raise TypeError, _("%s body don't have text!")%self.content.getLocalTag()
setattr(cls, "gettext", gettext)
-
+
def hasblock(self, block_type):
if self.content.getLocalTag() in ["IL","ST"]:
return self.content.hasblock(block_type)
else:
raise TypeError, _("%s body don't have text!")%self.content.getLocalTag()
setattr(cls, "hasblock", hasblock)
-
+
def updateElementName(self, old_name, new_name):
if self.content.getLocalTag() in ["IL", "ST"]:
self.content.updateElementName(old_name, new_name)
@@ -1753,7 +1753,7 @@
def setx(self, x):
self.position.setx(x)
-
+
def sety(self, y):
self.position.sety(y)
@@ -1828,7 +1828,7 @@
def _translate(self, dx, dy):
self.setx(self.getx() + dx)
self.sety(self.gety() + dy)
-
+
def _translateConnections(connectionPointIn, dx, dy):
connections = connectionPointIn.getconnections()
if connections is not None:
@@ -1892,11 +1892,11 @@
def setcontentText(self, text):
self.content.setanyText(text)
setattr(cls, "setcontentText", setcontentText)
-
+
def getcontentText(self):
return self.content.getanyText()
setattr(cls, "getcontentText", getcontentText)
-
+
def updateElementName(self, old_name, new_name):
self.content.updateElementName(old_name, new_name)
setattr(cls, "updateElementName", updateElementName)
@@ -2004,7 +2004,7 @@
condition.setcontent(PLCOpenParser.CreateElement("ST", "inline"))
condition.settext(value)
setattr(cls, "setconditionContent", setconditionContent)
-
+
def getconditionContent(self):
if self.condition is not None:
content = self.condition.getcontent()
@@ -2035,21 +2035,21 @@
bbox.union(_getConnectionsBoundingBox(condition_connection))
return bbox
setattr(cls, "getBoundingBox", getBoundingBox)
-
+
def translate(self, dx, dy):
_translateSingle(self, dx, dy)
condition_connection = self.getconditionConnection()
if condition_connection is not None:
_translateConnections(condition_connection, dx, dy)
setattr(cls, "translate", translate)
-
+
def filterConnections(self, connections):
_filterConnectionsSingle(self, connections)
condition_connection = self.getconditionConnection()
if condition_connection is not None:
_filterConnections(condition_connection, self.localId, connections)
setattr(cls, "filterConnections", filterConnections)
-
+
def updateConnectionsId(self, translation):
connections_end = []
if self.connectionPointIn is not None:
@@ -2087,7 +2087,7 @@
return condition_connection.getconnections()
return None
setattr(cls, "getconnections", getconnections)
-
+
def Search(self, criteria, parent_infos=[]):
parent_infos = parent_infos + ["transition", self.getlocalId()]
search_result = []
@@ -2104,7 +2104,7 @@
_initElementClass("selectionConvergence", "sfcObjects", "multiple")
_initElementClass("simultaneousDivergence", "sfcObjects", "single")
_initElementClass("simultaneousConvergence", "sfcObjects", "multiple")
-
+
cls = _initElementClass("jumpStep", "sfcObjects", "single")
if cls:
def Search(self, criteria, parent_infos):
@@ -2117,7 +2117,7 @@
if self.reference is not None:
self.reference.setname(name)
setattr(cls, "setreferenceName", setreferenceName)
-
+
def getreferenceName(self):
if self.reference is not None:
return self.reference.getname()
@@ -2129,7 +2129,7 @@
self.inline.setcontent(PLCOpenParser.CreateElement("ST", "inline"))
self.inline.settext(content)
setattr(cls, "setinlineContent", setinlineContent)
-
+
def getinlineContent(self):
if self.inline is not None:
return self.inline.gettext()
@@ -2155,7 +2155,7 @@
if qualifier is None:
qualifier = "N"
return _Search([("inline", self.getinlineContent()),
- ("reference", self.getreferenceName()),
+ ("reference", self.getreferenceName()),
("qualifier", qualifier),
("duration", self.getduration()),
("indicator", self.getindicator())],
@@ -2318,33 +2318,33 @@
def removeconnections(self):
self.content = None
setattr(cls, "removeconnections", removeconnections)
-
+
connection_xpath = PLCOpen_XPath("ppx:connection")
connection_by_position_xpath = PLCOpen_XPath("ppx:connection[position()=$pos]")
def getconnections(self):
return connection_xpath(self)
setattr(cls, "getconnections", getconnections)
-
+
def getconnection(self, idx):
connection = connection_by_position_xpath(self, pos=idx+1)
if len(connection) > 0:
return connection[0]
return None
setattr(cls, "getconnection", getconnection)
-
+
def setconnectionId(self, idx, local_id):
connection = self.getconnection(idx)
if connection is not None:
connection.setrefLocalId(local_id)
setattr(cls, "setconnectionId", setconnectionId)
-
+
def getconnectionId(self, idx):
connection = self.getconnection(idx)
if connection is not None:
return connection.getrefLocalId()
return None
setattr(cls, "getconnectionId", getconnectionId)
-
+
def setconnectionPoints(self, idx, points):
connection = self.getconnection(idx)
if connection is not None:
@@ -2363,7 +2363,7 @@
if connection is not None:
connection.setformalParameter(parameter)
setattr(cls, "setconnectionParameter", setconnectionParameter)
-
+
def getconnectionParameter(self, idx):
connection = self.getconnection(idx)
if connection is not None:
@@ -2398,7 +2398,7 @@
content.setvalue(value)
self.setcontent(content)
setattr(cls, "setvalue", setvalue)
-
+
def getvalue(self):
return self.content.getvalue()
setattr(cls, "getvalue", getvalue)
@@ -2420,7 +2420,7 @@
cls = PLCOpenParser.GetElementClass("arrayValue", "value")
if cls:
arrayValue_model = re.compile("([0-9]+)\((.*)\)$")
-
+
def setvalue(self, value):
elements = []
for item in extractValues(value[1:-1]):
@@ -2436,7 +2436,7 @@
elements.append(element)
self.value = elements
setattr(cls, "setvalue", setvalue)
-
+
def getvalue(self):
values = []
for element in self.value:
@@ -2457,7 +2457,7 @@
cls = PLCOpenParser.GetElementClass("structValue", "value")
if cls:
structValue_model = re.compile("(.*):=(.*)")
-
+
def setvalue(self, value):
elements = []
for item in extractValues(value[1:-1]):
@@ -2470,11 +2470,10 @@
elements.append(element)
self.value = elements
setattr(cls, "setvalue", setvalue)
-
+
def getvalue(self):
values = []
for element in self.value:
values.append("%s := %s"%(element.getmember(), element.getvalue()))
return "(%s)"%", ".join(values)
setattr(cls, "getvalue", getvalue)
-
--- a/plcopen/structures.py Fri Aug 11 15:18:19 2017 +0300
+++ b/plcopen/structures.py Mon Aug 14 19:13:01 2017 +0300
@@ -92,7 +92,7 @@
"""
take a .csv file and translate it it a "csv_table"
-"""
+"""
def csv_file_to_table(file):
return [ map(string.strip,line.split(';')) for line in file.xreadlines()]
@@ -119,18 +119,18 @@
variable_from_csv = dict([(champ, val) for champ, val in zip(variables, fields[1:]) if champ!=''])
standard_funtions_input_variables[variable_from_csv['name']] = variable_from_csv['type']
return standard_funtions_input_variables
-
+
"""
translate .csv file input declaration into PLCOpenEditor interessting values
in : "(ANY_NUM, ANY_NUM)" and { ParameterName: Type, ...}
-return [("IN1","ANY_NUM","none"),("IN2","ANY_NUM","none")]
+return [("IN1","ANY_NUM","none"),("IN2","ANY_NUM","none")]
"""
def csv_input_translate(str_decl, variables, base):
decl = str_decl.replace('(','').replace(')','').replace(' ','').split(',')
params = []
-
+
len_of_not_predifined_variable = len([True for param_type in decl if param_type not in variables])
-
+
for param_type in decl:
if param_type in variables.keys():
param_name = param_type
@@ -147,7 +147,7 @@
"""
Returns this kind of declaration for all standard functions
- [{"name" : "Numerical", 'list': [ {
+ [{"name" : "Numerical", 'list': [ {
'baseinputnumber': 1,
'comment': 'Addition',
'extensible': True,
@@ -158,19 +158,19 @@
'type': 'function'}, ...... ] },.....]
"""
def get_standard_funtions(table):
-
+
variables = get_standard_funtions_input_variables(table)
-
+
fonctions = find_section("Standard_functions_type",table)
Standard_Functions_Decl = []
Current_section = None
-
+
translate = {
"extensible" : lambda x: {"yes":True, "no":False}[x],
"inputs" : lambda x:csv_input_translate(x,variables,baseinputnumber),
"outputs":lambda x:[("OUT",x,"none")]}
-
+
for fields in table:
if fields[1]:
# If function section name given
@@ -191,14 +191,14 @@
if param in translate:
Function_decl[param] = translate[param](value)
Function_decl["type"] = "function"
-
+
if Function_decl["name"].startswith('*') or Function_decl["name"].endswith('*') :
input_ovrloading_types = GetSubTypes(Function_decl["inputs"][0][1])
output_types = GetSubTypes(Function_decl["outputs"][0][1])
else:
input_ovrloading_types = [None]
output_types = [None]
-
+
funcdeclname_orig = Function_decl["name"]
funcdeclname = Function_decl["name"].strip('*_')
fdc = Function_decl["inputs"][:]
@@ -210,14 +210,14 @@
Function_decl["inputs"] += [(decl_tpl[0], intype, decl_tpl[2])]
else:
Function_decl["inputs"] += [(decl_tpl)]
-
+
if funcdeclname_orig.startswith('*'):
- funcdeclin = intype + '_' + funcdeclname
+ funcdeclin = intype + '_' + funcdeclname
else:
funcdeclin = funcdeclname
else:
funcdeclin = funcdeclname
-
+
for outype in output_types:
if outype != None:
decl_tpl = Function_decl["outputs"][0]
@@ -234,7 +234,7 @@
filter_name = Function_decl["filter"]
store = True
for (InTypes, OutTypes) in ANY_TO_ANY_FILTERS.get(filter_name,[]):
- outs = reduce(lambda a,b: a or b,
+ outs = reduce(lambda a,b: a or b,
map(lambda testtype : IsOfType(
Function_decl["outputs"][0][1],
testtype), OutTypes))
@@ -253,7 +253,7 @@
Current_section["list"].append(Function_decl_copy)
else:
raise "First function must be in a category"
-
+
return Standard_Functions_Decl
StdBlckLst.extend(get_standard_funtions(csv_file_to_table(open(StdFuncsCSV))))
@@ -266,10 +266,10 @@
words = desc["comment"].split('"')
if len(words) > 1:
desc["comment"] = words[1]
- desc["usage"] = ("\n (%s) => (%s)" %
- (", ".join(["%s:%s" % (input[1], input[0])
+ desc["usage"] = ("\n (%s) => (%s)" %
+ (", ".join(["%s:%s" % (input[1], input[0])
for input in desc["inputs"]]),
- ", ".join(["%s:%s" % (output[1], output[0])
+ ", ".join(["%s:%s" % (output[1], output[0])
for output in desc["outputs"]])))
BlkLst = StdBlckDct.setdefault(desc["name"],[])
BlkLst.append((section["name"], desc))
@@ -321,7 +321,7 @@
# Keywords for Structured Text
ST_BLOCK_START_KEYWORDS = ["IF", "ELSIF", "ELSE", "CASE", "FOR", "WHILE", "REPEAT"]
ST_BLOCK_END_KEYWORDS = ["END_IF", "END_CASE", "END_FOR", "END_WHILE", "END_REPEAT"]
-ST_KEYWORDS = ["TRUE", "FALSE", "THEN", "OF", "TO", "BY", "DO", "DO", "UNTIL", "EXIT",
+ST_KEYWORDS = ["TRUE", "FALSE", "THEN", "OF", "TO", "BY", "DO", "DO", "UNTIL", "EXIT",
"RETURN", "NOT", "MOD", "AND", "XOR", "OR"] + ST_BLOCK_START_KEYWORDS + ST_BLOCK_END_KEYWORDS
# All the keywords of IEC
@@ -338,5 +338,3 @@
SFC_KEYWORDS, IL_KEYWORDS, ST_KEYWORDS])]:
for keywords in keywords_list:
all_keywords.extend([keyword for keyword in keywords if keyword not in all_keywords])
-
-
--- a/py_ext/PythonEditor.py Fri Aug 11 15:18:19 2017 +0300
+++ b/py_ext/PythonEditor.py Mon Aug 14 19:13:01 2017 +0300
@@ -32,12 +32,12 @@
KEYWORDS = keyword.kwlist
COMMENT_HEADER = "#"
-
+
def SetCodeLexer(self):
self.SetLexer(stc.STC_LEX_PYTHON)
-
+
# Line numbers in margin
- self.StyleSetSpec(stc.STC_STYLE_LINENUMBER,'fore:#000000,back:#99A9C2,size:%(size)d' % faces)
+ self.StyleSetSpec(stc.STC_STYLE_LINENUMBER,'fore:#000000,back:#99A9C2,size:%(size)d' % faces)
# Highlighted brace
self.StyleSetSpec(stc.STC_STYLE_BRACELIGHT,'fore:#00009D,back:#FFFF00,size:%(size)d' % faces)
# Unmatched brace
@@ -69,15 +69,14 @@
# Identifiers. I leave this as not bold because everything seems
# to be an identifier if it doesn't match the above criterae
self.StyleSetSpec(stc.STC_P_IDENTIFIER, 'fore:#000000,size:%(size)d' % faces)
-
+
#-------------------------------------------------------------------------------
# CFileEditor Main Frame Class
#-------------------------------------------------------------------------------
class PythonEditor(CodeFileEditor):
-
+
CONFNODEEDITOR_TABS = [
(_("Python code"), "_create_CodePanel")]
CODE_EDITOR = PythonCodeEditor
-
--- a/py_ext/py_ext.py Fri Aug 11 15:18:19 2017 +0300
+++ b/py_ext/py_ext.py Mon Aug 14 19:13:01 2017 +0300
@@ -30,10 +30,10 @@
class PythonLibrary(POULibrary):
def GetLibraryPath(self):
- return paths.AbsNeighbourFile(__file__, "pous.xml")
+ return paths.AbsNeighbourFile(__file__, "pous.xml")
def Generate_C(self, buildpath, varlist, IECCFLAGS):
-
+
plc_python_filepath = paths.AbsNeighbourFile(__file__, "plc_python.c")
plc_python_file = open(plc_python_filepath, 'r')
plc_python_code = plc_python_file.read()
@@ -44,21 +44,19 @@
"PYTHON_POLL"]:
python_eval_fb_list.append(v)
python_eval_fb_count = max(1, len(python_eval_fb_list))
-
+
# prepare python code
plc_python_code = plc_python_code % {
"python_eval_fb_count": python_eval_fb_count }
-
+
Gen_Pythonfile_path = os.path.join(buildpath, "py_ext.c")
pythonfile = open(Gen_Pythonfile_path,'w')
pythonfile.write(plc_python_code)
pythonfile.close()
-
+
return (["py_ext"], [(Gen_Pythonfile_path, IECCFLAGS)], True), ""
class PythonFile(PythonFileCTNMixin):
-
+
def GetIconName(self):
return "Pyfile"
-
-
--- a/runtime/PLCObject.py Fri Aug 11 15:18:19 2017 +0300
+++ b/runtime/PLCObject.py Mon Aug 14 19:13:01 2017 +0300
@@ -143,8 +143,8 @@
self.PLClibraryHandle = ctypes.CDLL(self.CurrentPLCFilename, handle=self._PLClibraryHandle)
self.PLC_ID = ctypes.c_char_p.in_dll(self.PLClibraryHandle, "PLC_ID")
- if len(md5) == 32 :
- self.PLC_ID.value = md5
+ if len(md5) == 32 :
+ self.PLC_ID.value = md5
self._startPLC = self.PLClibraryHandle.startPLC
self._startPLC.restype = ctypes.c_int
@@ -556,5 +556,3 @@
return (-1, "RemoteExec script failed!\n\nLine %d: %s\n\t%s" %
(line_no, e_value, script.splitlines()[line_no - 1]))
return (0, kwargs.get("returnVal", None))
-
-
--- a/runtime/ServicePublisher.py Fri Aug 11 15:18:19 2017 +0300
+++ b/runtime/ServicePublisher.py Mon Aug 14 19:13:01 2017 +0300
@@ -30,20 +30,20 @@
def __init__(self):
# type: fully qualified service type name
self.serviceproperties = {'description':'Beremiz remote PLC'}
-
+
self.name = None
self.ip_32b = None
self.port = None
self.server = None
self.service_name = None
self.retrytimer = None
-
+
def RegisterService(self, name, ip, port):
try:
self._RegisterService(name, ip, port)
except Exception,e:
self.retrytimer = threading.Timer(2,self.RegisterService,[name, ip, port])
- self.retrytimer.start()
+ self.retrytimer.start()
def _RegisterService(self, name, ip, port):
# name: fully qualified service name
@@ -66,20 +66,20 @@
self.port,
properties = self.serviceproperties))
self.retrytimer=None
-
+
def UnRegisterService(self):
if self.retrytimer is not None:
self.retrytimer.cancel()
self.server.unregisterService(
- Zeroconf.ServiceInfo(service_type,
- self.service_name,
- self.ip_32b,
- self.port,
+ Zeroconf.ServiceInfo(service_type,
+ self.service_name,
+ self.ip_32b,
+ self.port,
properties = self.serviceproperties))
self.server.close()
self.server = None
-
+
def gethostaddr(self, dst = '224.0.1.41'):
s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
try:
--- a/svgui/pyjs/build.py Fri Aug 11 15:18:19 2017 +0300
+++ b/svgui/pyjs/build.py Mon Aug 14 19:13:01 2017 +0300
@@ -306,7 +306,7 @@
# Second, (dynamic only), post-analyse the places where modules
# haven't changed
# Third, write everything out.
-
+
for platform in app_platforms:
mod_code[platform] = {}
@@ -337,11 +337,11 @@
print appcode
#mod_code[platform][app_name] = appcode
- # platform.Module.cache.js
+ # platform.Module.cache.js
modules_done = ['pyjslib', 'sys', '_pyjs.js']
#modules_to_do = [app_name] + app_translator.library_modules
- modules_to_do = [app_name] + app_translator.library_modules
+ modules_to_do = [app_name] + app_translator.library_modules
dependencies = {}
@@ -403,9 +403,9 @@
deps = uniquify(deps)
#print "modname:", mod_name, deps
dependencies[mod_name] = deps
-
+
# work out the dependency ordering of the modules
-
+
mod_levels[platform] = make_deps(None, dependencies, modules_done)
# now write everything out
@@ -473,7 +473,7 @@
app_libs_ += mod_cache_html_output.read()
# write out the dependency ordering of the modules
-
+
app_modnames = []
for md in mod_levels[platform]:
@@ -512,7 +512,7 @@
file_name = "%s.%s.%s" % (platform.lower(), app_name, digest)
else:
file_name = "%s.%s" % (platform.lower(), app_name)
- file_name += ".cache.html"
+ file_name += ".cache.html"
out_path = join(output, file_name)
out_file = open(out_path, 'w')
out_file.write(file_contents)
@@ -599,7 +599,7 @@
if has_nodeps(mod, deps):
res.append(mod)
return res
-
+
# this function takes a dictionary of dependent modules and
# creates a list of lists. the first list will be modules
# that have no dependencies; the second list will be those
@@ -721,4 +721,3 @@
if __name__ == "__main__":
main()
-
--- a/svgui/pyjs/jsonrpc/django/jsonrpc.py Fri Aug 11 15:18:19 2017 +0300
+++ b/svgui/pyjs/jsonrpc/django/jsonrpc.py Mon Aug 14 19:13:01 2017 +0300
@@ -19,13 +19,13 @@
# (r'^service1/$', 'djangoapp.views.jsonservice'),
class JSONRPCService(JSONRPCServiceBase):
-
+
def __call__(self, request, extra=None):
return self.process(request.raw_post_data)
def jsonremote(service):
"""Make JSONRPCService a decorator so that you can write :
-
+
from jsonrpc import JSONRPCService
chatservice = JSONRPCService()
@@ -62,7 +62,7 @@
# part of the app:
# (r'^formsservice/$', 'djangoapp.views.processor'),
-from django import forms
+from django import forms
def builderrors(form):
d = {}
@@ -223,4 +223,3 @@
for item in serialize('python', l, fields=fields):
res.append(dict_datetimeflatten(item))
return res
-
--- a/svgui/pyjs/jsonrpc/jsonrpc.py Fri Aug 11 15:18:19 2017 +0300
+++ b/svgui/pyjs/jsonrpc/jsonrpc.py Mon Aug 14 19:13:01 2017 +0300
@@ -39,5 +39,4 @@
return self.error(id, 100, 'method "%s" does not exist' % method)
def listmethods(self):
- return self.methods.keys()
-
+ return self.methods.keys()
--- a/svgui/pyjs/lib/pyjslib.py Fri Aug 11 15:18:19 2017 +0300
+++ b/svgui/pyjs/lib/pyjslib.py Mon Aug 14 19:13:01 2017 +0300
@@ -20,7 +20,7 @@
# must declare import _before_ importing sys
def import_module(path, parent_module, module_name, dynamic=1, async=False):
- """
+ """
"""
JS("""
@@ -38,7 +38,7 @@
}
var override_name = sys.platform + "." + module_name;
- if (((sys.overrides != null) &&
+ if (((sys.overrides != null) &&
(sys.overrides.has_key(override_name))))
{
cache_file = sys.overrides.__getitem__(override_name) ;
@@ -67,7 +67,7 @@
module_load_request[module_name] = 1;
}
- /* following a load, this first executes the script
+ /* following a load, this first executes the script
* "preparation" function MODULENAME_loaded_fn()
* and then sets up the loaded module in the namespace
* of the parent.
@@ -201,7 +201,7 @@
self.parent_mod = parent_mod
def next(self):
-
+
for i in range(len(self.app_modlist[self.idx])):
app = self.app_modlist[self.idx][i]
import_module(self.path, self.parent_mod, app, self.dynamic, True);
@@ -1109,7 +1109,7 @@
if pyjslib.isUndefined(object_):
return False
if not pyjslib.isObject(object_):
-
+
return False
if _isinstance(classinfo, Tuple):
for ci in classinfo:
@@ -1362,4 +1362,3 @@
if bases:
JS("bss = bases.l;")
JS(" return pyjs_type(clsname, bss, mths); ")
-
--- a/svgui/pyjs/lib/sys.py Fri Aug 11 15:18:19 2017 +0300
+++ b/svgui/pyjs/lib/sys.py Mon Aug 14 19:13:01 2017 +0300
@@ -5,11 +5,11 @@
overrides = None # to be updated by app, on compile
# the remote path for loading modules
-loadpath = None
+loadpath = None
-stacktrace = None
+stacktrace = None
-appname = None
+appname = None
def setloadpath(lp):
global loadpath
--- a/svgui/pyjs/pyjs.py Fri Aug 11 15:18:19 2017 +0300
+++ b/svgui/pyjs/pyjs.py Mon Aug 14 19:13:01 2017 +0300
@@ -345,7 +345,7 @@
# added to the dependencies, and it's half way up the
# module import directory structure!
child_name = name[-1]
- self.imported_modules_as.append(child_name)
+ self.imported_modules_as.append(child_name)
print >> self.output, gen_mod_import(self.raw_module_name,
strip_py(importName),
self.dynamic)
@@ -427,7 +427,7 @@
print >>self.output, "%s = function%s {" % (function_name, function_args)
self._default_args_handler(node, normal_arg_names, None)
- local_arg_names = normal_arg_names + declared_arg_names
+ local_arg_names = normal_arg_names + declared_arg_names
if node.varargs:
self._varargs_handler(node, varargname, declared_arg_names, None)
@@ -539,12 +539,12 @@
except ValueError:
# Must be a function call ...
return ("pyjs_kwargs_function_call("+call_name+", "
- + star_arg_name
+ + star_arg_name
+ ", ["+fn_args+"]"
+ ")" )
else:
return ("pyjs_kwargs_method_call("+call_this+", '"+method_name+"', "
- + star_arg_name
+ + star_arg_name
+ ", ["+fn_args+"]"
+ ")")
else:
@@ -628,7 +628,7 @@
def modpfx(self):
return strip_py(self.module_prefix)
-
+
def _name(self, v, current_klass, top_level=False,
return_none_for_module=False):
@@ -904,7 +904,7 @@
# default arguments
self._default_args_handler(node, normal_arg_names, current_klass)
- local_arg_names = normal_arg_names + declared_arg_names
+ local_arg_names = normal_arg_names + declared_arg_names
if node.varargs:
self._varargs_handler(node, varargname, declared_arg_names, current_klass)
@@ -1170,7 +1170,7 @@
def _discard(self, node, current_klass):
-
+
if isinstance(node.expr, ast.CallFunc):
debugStmt = self.debug and not self._isNativeFunc(node)
if debugStmt and isinstance(node.expr.node, ast.Name) and \
@@ -1774,4 +1774,3 @@
if __name__ == "__main__":
main()
-
--- a/svgui/svgui.py Fri Aug 11 15:18:19 2017 +0300
+++ b/svgui/svgui.py Mon Aug 14 19:13:01 2017 +0300
@@ -35,7 +35,7 @@
class SVGUILibrary(POULibrary):
def GetLibraryPath(self):
- return paths.AbsNeighbourFile(__file__, "pous.xml")
+ return paths.AbsNeighbourFile(__file__, "pous.xml")
class SVGUI(PythonFileCTNMixin):
@@ -70,18 +70,18 @@
def CTNGenerate_C(self, buildpath, locations):
"""
- Return C code generated by iec2c compiler
+ Return C code generated by iec2c compiler
when _generate_softPLC have been called
@param locations: ignored
@return: [(C_file_name, CFLAGS),...] , LDFLAGS_TO_APPEND
"""
-
+
current_location = self.GetCurrentLocation()
# define a unique name for the generated C file
location_str = "_".join(map(lambda x:str(x), current_location))
-
+
res = ([], "", False)
-
+
svgfile=self._getSVGpath()
if os.path.exists(svgfile):
res += (("gui.svg", file(svgfile,"rb")),)
@@ -103,25 +103,25 @@
svguilibfile.close()
jsmodules = {"LiveSVGPage": "svguilib.js"}
res += (("svguilib.js", file(svguilibpath,"rb")),)
-
+
runtimefile_path = os.path.join(buildpath, "runtime_%s.py"%location_str)
runtimefile = open(runtimefile_path, 'w')
runtimefile.write(svguiservercode % {"svgfile" : "gui.svg"})
runtimefile.write("""
def _runtime_%(location)s_start():
website.LoadHMI(%(svgui_class)s, %(jsmodules)s)
-
+
def _runtime_%(location)s_stop():
website.UnLoadHMI()
-
+
""" % {"location": location_str,
"svgui_class": "SVGUI_HMI",
"jsmodules" : str(jsmodules),
})
runtimefile.close()
-
+
res += (("runtime_%s.py"%location_str, file(runtimefile_path,"rb")),)
-
+
return res
def _ImportSVG(self):
@@ -132,7 +132,7 @@
shutil.copy(svgpath, self._getSVGpath())
else:
self.GetCTRoot().logger.write_error(_("No such SVG file: %s\n")%svgpath)
- dialog.Destroy()
+ dialog.Destroy()
def _StartInkscape(self):
svgfile = self._getSVGpath()
--- a/svgui/svgui_server.py Fri Aug 11 15:18:19 2017 +0300
+++ b/svgui/svgui_server.py Mon Aug 14 19:13:01 2017 +0300
@@ -38,7 +38,7 @@
return currentId
class SvguiWidget:
-
+
def __init__(self, classname, id, **kwargs):
self.classname = classname
self.id = id
@@ -50,7 +50,7 @@
def setinput(self, attrname, value):
self.inputs[attrname] = value
-
+
def getinput(self, attrname, default=None):
if not self.inputs.has_key(attrname):
self.inputs[attrname] = default
@@ -61,14 +61,14 @@
self.outputs[attrname] = value
self.changed = True
self.RefreshInterface()
-
+
def updateoutputs(self, **kwargs):
for attrname, value in kwargs.iteritems():
if self.outputs.get(attrname) != value:
self.outputs[attrname] = value
self.changed = True
self.RefreshInterface()
-
+
def RefreshInterface(self):
interface = website.getHMI()
if isinstance(interface, SVGUI_HMI) and self.changed and not self.inhibit:
@@ -77,7 +77,7 @@
if d is not None:
self.inhibit = True
d.addCallback(self.InterfaceRefreshed)
-
+
def InterfaceRefreshed(self, result):
self.inhibit = False
if self.changed:
@@ -103,23 +103,23 @@
class SVGUI_HMI(website.PLCHMI):
jsClass = u"LiveSVGPage.LiveSVGWidget"
-
- docFactory = loaders.stan(tags.div(render=tags.directive('liveElement'))[
+
+ docFactory = loaders.stan(tags.div(render=tags.directive('liveElement'))[
tags.xml(loaders.xmlfile(os.path.join(WorkingDir, svgfile))),
])
-
+
def HMIinitialisation(self):
gadgets = []
for gadget in svguiWidgets.values():
gadgets.append(unicode(json.dumps(gadget, default=get_object_init_state, indent=2), 'ascii'))
d = self.callRemote('init', gadgets)
d.addCallback(self.HMIinitialised)
-
+
def sendData(self,data):
if self.initialised:
return self.callRemote('receiveData',unicode(json.dumps(data, default=get_object_current_state, indent=2), 'ascii'))
return None
-
+
def setattr(self, id, attrname, value):
svguiWidgets[id].setinput(attrname, value)
@@ -148,4 +148,3 @@
if gad is not None:
return gad.getinput(attrname, default)
return default
-
--- a/svgui/svguilib.py Fri Aug 11 15:18:19 2017 +0300
+++ b/svgui/svguilib.py Mon Aug 14 19:13:01 2017 +0300
@@ -23,7 +23,7 @@
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
class button:
-
+
def __init__(self, parent, id, args):
self.parent = parent
self.id = id
@@ -40,19 +40,19 @@
self.up = not self.state
else:
self.up = True
-
+
# Add event on each element of the button
if self.active:
self.back_elt.addEventListener("mouseup", self, False)
self.back_elt.addEventListener("mousedown", self, False)
self.back_elt.addEventListener("mouseover", self, False)
self.back_elt.addEventListener("mouseout", self, False)
-
+
self.sele_elt.addEventListener("mouseup", self, False)
self.sele_elt.addEventListener("mousedown", self, False)
self.sele_elt.addEventListener("mouseover", self, False)
self.sele_elt.addEventListener("mouseout", self, False)
-
+
blockSVGElementDrag(self.back_elt)
blockSVGElementDrag(self.sele_elt)
@@ -66,7 +66,7 @@
else:
self.sele_elt.removeAttribute("display")
self.back_elt.setAttribute("display", "none")
-
+
def updateValues(self, values):
if values.state != self.state:
self.state = values.state
@@ -80,9 +80,9 @@
if evt.type == "mousedown":
evt.stopPropagation()
setCurrentObject(self)
-
+
self.dragging = True
-
+
if self.toggle:
self.up = self.state
else:
@@ -90,18 +90,18 @@
self.state = True
updateAttr(self.id, 'state', self.state)
self.updateElements()
-
+
if isCurrentObject(self) and self.dragging:
# Quand le bouton est survole
if evt.type == "mouseover" and self.toggle:
self.up = self.state
self.updateElements()
-
+
# Quand le curseur quitte la zone du bouton
- elif evt.type == "mouseout" and self.toggle:
+ elif evt.type == "mouseout" and self.toggle:
self.up = not self.state
self.updateElements()
-
+
# Quand le bouton de la souris est relache
elif evt.type == "mouseup":
evt.stopPropagation()
@@ -116,7 +116,7 @@
self.dragging = False
class textControl:
-
+
def __init__(self, parent, id, args):
self.parent = parent
self.id = id
@@ -126,17 +126,15 @@
else:
self.text = ""
self.updateElements()
-
+
def updateValues(self, values):
if values.text != self.value:
self.text = values.text
updateAttr(self.id, 'text', self.text)
self.updateElements()
-
+
def updateElements(self):
self.back_elt.firstChild.firstChild.textContent = self.text
-
+
def handleEvent(self, evt):
pass
-
-
--- a/targets/__init__.py Fri Aug 11 15:18:19 2017 +0300
+++ b/targets/__init__.py Mon Aug 14 19:13:01 2017 +0300
@@ -41,14 +41,14 @@
def _GetLocalTargetClassFactory(name):
return lambda:getattr(__import__(name,globals(),locals()), name+"_target")
-targets = dict([(name, {"xsd":path.join(_base_path, name, "XSD"),
+targets = dict([(name, {"xsd":path.join(_base_path, name, "XSD"),
"class":_GetLocalTargetClassFactory(name),
- "code": { fname: path.join(_base_path, name, fname)
+ "code": { fname: path.join(_base_path, name, fname)
for fname in listdir(path.join(_base_path, name))
if fname.startswith("plc_%s_main"%name) and
fname.endswith(".c")}})
- for name in listdir(_base_path)
- if path.isdir(path.join(_base_path, name))
+ for name in listdir(_base_path)
+ if path.isdir(path.join(_base_path, name))
and not name.startswith("__")])
toolchains = {"gcc": path.join(_base_path, "XSD_toolchain_gcc"),
@@ -67,7 +67,7 @@
DictXSD_toolchain["toolchain_"+toolchainname] = \
open(xsdfilename).read()
- # Get all xsd targets
+ # Get all xsd targets
for targetname,nfo in targets.iteritems():
xsd_string = open(nfo["xsd"]).read()
targetchoices += xsd_string%DictXSD_toolchain
@@ -86,4 +86,3 @@
def GetCode(name):
filename = paths.AbsNeighbourFile(__file__,name)
return open(filename).read()
-
--- a/targets/toolchain_makefile.py Fri Aug 11 15:18:19 2017 +0300
+++ b/targets/toolchain_makefile.py Mon Aug 14 19:13:01 2017 +0300
@@ -33,7 +33,7 @@
class toolchain_makefile():
def __init__(self, CTRInstance):
self.CTRInstance = CTRInstance
- self.md5key = None
+ self.md5key = None
self.buildpath = None
self.SetBuildPath(self.CTRInstance._getBuildPath())
@@ -83,7 +83,7 @@
def build(self):
srcfiles= []
cflags = []
- wholesrcdata = ""
+ wholesrcdata = ""
for Location, CFilesAndCFLAGS, DoCalls in self.CTRInstance.LocationCFilesAndCFLAGS:
# Get CFiles list to give it to makefile
for CFile, CFLAGS in CFilesAndCFLAGS:
@@ -92,7 +92,7 @@
srcfiles.append(CFileName)
if CFLAGS not in cflags:
cflags.append(CFLAGS)
-
+
oldmd5 = self.md5key
self.md5key = hashlib.md5(wholesrcdata).hexdigest()
@@ -108,8 +108,8 @@
"md5": self.md5key,
"buildpath": self.buildpath
}
-
- # clean sequence of multiple whitespaces
+
+ # clean sequence of multiple whitespaces
cmd = re.sub(r"[ ]+", " ", target.getCommand().strip())
command = [ token % beremizcommand for token in cmd.split(' ')]
@@ -125,4 +125,3 @@
else :
self.CTRInstance.logger.write(_("Source didn't change, no build.\n"))
return True
-
--- a/util/ProcessLogger.py Fri Aug 11 15:18:19 2017 +0300
+++ b/util/ProcessLogger.py Mon Aug 14 19:13:01 2017 +0300
@@ -53,7 +53,7 @@
self.retval = self.Proc.poll()
else:
self.retval = self.Proc.returncode
-
+
outchunk = self.fd.readline()
if self.callback : self.callback(outchunk)
while outchunk != '' and not self.killed :
@@ -108,7 +108,7 @@
self.errdata = []
self.keyword = keyword
self.kill_it = kill_it
- self.startsem = Semaphore(0)
+ self.startsem = Semaphore(0)
self.finishsem = Semaphore(0)
self.endlock = Lock()
@@ -130,7 +130,7 @@
self.timeout.start()
else:
self.timeout = None
-
+
self.Proc = subprocess.Popen( self.Command, **popenargs )
self.outt = outputThread(
@@ -169,7 +169,7 @@
self.logger.write_warning(_("exited with status {a1} (pid {a2})\n").format(a1 = str(ecode), a2 = str(pid)))
def finish(self, pid,ecode):
- # avoid running function before start is finished
+ # avoid running function before start is finished
self.startsem.acquire()
if self.timeout:
self.timeout.cancel()
@@ -185,7 +185,7 @@
# avoid running kill before start is finished
self.startsem.acquire()
self.startsem.release()
-
+
self.outt.killed = True
self.errt.killed = True
if wx.Platform == '__WXMSW__':
@@ -215,4 +215,3 @@
def spin(self):
self.finishsem.acquire()
return [self.exitcode, "".join(self.outdata), "".join(self.errdata)]
-
--- a/util/TranslationCatalogs.py Fri Aug 11 15:18:19 2017 +0300
+++ b/util/TranslationCatalogs.py Mon Aug 14 19:13:01 2017 +0300
@@ -22,7 +22,7 @@
# along with this program; if not, write to the Free Software
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
-import os
+import os
import wx
--- a/util/Zeroconf.py Fri Aug 11 15:18:19 2017 +0300
+++ b/util/Zeroconf.py Mon Aug 14 19:13:01 2017 +0300
@@ -19,7 +19,7 @@
You should have received a copy of the GNU Lesser 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
-
+
"""
"""0.12 update - allow selection of binding interface
@@ -101,7 +101,7 @@
_BROWSER_TIME = 500
# Some DNS constants
-
+
_MDNS_ADDR = '224.0.0.251'
_MDNS_PORT = 5353;
_DNS_PORT = 53;
@@ -208,7 +208,7 @@
class DNSEntry(object):
"""A DNS entry"""
-
+
def __init__(self, name, type, clazz):
self.key = string.lower(name)
self.name = name
@@ -256,7 +256,7 @@
class DNSQuestion(DNSEntry):
"""A DNS question entry"""
-
+
def __init__(self, name, type, clazz):
if not name.endswith(".local."):
raise NonLocalNameException
@@ -273,7 +273,7 @@
class DNSRecord(DNSEntry):
"""A DNS record - like a DNS entry, but has a TTL"""
-
+
def __init__(self, name, type, clazz, ttl):
DNSEntry.__init__(self, name, type, clazz)
self.ttl = ttl
@@ -334,7 +334,7 @@
class DNSAddress(DNSRecord):
"""A DNS address record"""
-
+
def __init__(self, name, type, clazz, ttl, address):
DNSRecord.__init__(self, name, type, clazz, ttl)
self.address = address
@@ -378,10 +378,10 @@
def __repr__(self):
"""String representation"""
return self.cpu + " " + self.os
-
+
class DNSPointer(DNSRecord):
"""A DNS pointer record"""
-
+
def __init__(self, name, type, clazz, ttl, alias):
DNSRecord.__init__(self, name, type, clazz, ttl)
self.alias = alias
@@ -402,7 +402,7 @@
class DNSText(DNSRecord):
"""A DNS text record"""
-
+
def __init__(self, name, type, clazz, ttl, text):
DNSRecord.__init__(self, name, type, clazz, ttl)
self.text = text
@@ -426,7 +426,7 @@
class DNSService(DNSRecord):
"""A DNS service record"""
-
+
def __init__(self, name, type, clazz, ttl, priority, weight, port, server):
DNSRecord.__init__(self, name, type, clazz, ttl)
self.priority = priority
@@ -453,7 +453,7 @@
class DNSIncoming(object):
"""Object representation of an incoming DNS packet"""
-
+
def __init__(self, data):
"""Constructor from string holding bytes of packet"""
self.offset = 0
@@ -464,7 +464,7 @@
self.numAnswers = 0
self.numAuthorities = 0
self.numAdditionals = 0
-
+
self.readHeader()
self.readQuestions()
self.readOthers()
@@ -491,7 +491,7 @@
name = self.readName()
info = struct.unpack(format, self.data[self.offset:self.offset+length])
self.offset += length
-
+
question = DNSQuestion(name, info[0], info[1])
self.questions.append(question)
@@ -561,7 +561,7 @@
if rec is not None:
self.answers.append(rec)
-
+
def isQuery(self):
"""Returns true if this is a query"""
return (self.flags & _FLAGS_QR_MASK) == _FLAGS_QR_QUERY
@@ -574,7 +574,7 @@
"""Reads a UTF-8 string of a given length from the packet"""
result = self.data[offset:offset+len].decode('utf-8')
return result
-
+
def readName(self):
"""Reads a domain name from the packet"""
result = ''
@@ -607,11 +607,11 @@
self.offset = off
return result
-
-
+
+
class DNSOutgoing(object):
"""Object representation of an outgoing packet"""
-
+
def __init__(self, flags, multicast = 1):
self.finished = 0
self.id = 0
@@ -620,7 +620,7 @@
self.names = {}
self.data = []
self.size = 12
-
+
self.questions = []
self.answers = []
self.authorities = []
@@ -660,7 +660,7 @@
format = '!H'
self.data.insert(index, struct.pack(format, value))
self.size += 2
-
+
def writeShort(self, value):
"""Writes an unsigned short to the packet"""
format = '!H'
@@ -739,7 +739,7 @@
self.size += 2
record.write(self)
self.size -= 2
-
+
length = len(''.join(self.data[index:]))
self.insertShort(index, length) # Here is the short we adjusted for
@@ -758,7 +758,7 @@
self.writeRecord(authority, 0)
for additional in self.additionals:
self.writeRecord(additional, 0)
-
+
self.insertShort(0, len(self.additionals))
self.insertShort(0, len(self.authorities))
self.insertShort(0, len(self.answers))
@@ -773,7 +773,7 @@
class DNSCache(object):
"""A cache of DNS entries"""
-
+
def __init__(self):
self.cache = {}
@@ -872,7 +872,7 @@
result = self.readers.keys()
self.condition.release()
return result
-
+
def addReader(self, reader, socket):
self.condition.acquire()
self.readers[socket] = reader
@@ -897,7 +897,7 @@
It requires registration with an Engine object in order to have
the read() method called when a socket is availble for reading."""
-
+
def __init__(self, zeroconf):
self.zeroconf = zeroconf
self.zeroconf.engine.addReader(self, self.zeroconf.socket)
@@ -924,7 +924,7 @@
class Reaper(threading.Thread):
"""A Reaper is used by this module to remove cache entries that
have expired."""
-
+
def __init__(self, zeroconf):
threading.Thread.__init__(self)
self.zeroconf = zeroconf
@@ -948,7 +948,7 @@
The listener object will have its addService() and
removeService() methods called when this browser
discovers changes in the services availability."""
-
+
def __init__(self, zeroconf, type, listener):
"""Creates a browser for a specific type"""
threading.Thread.__init__(self)
@@ -959,7 +959,7 @@
self.nextTime = currentTimeMillis()
self.delay = _BROWSER_TIME
self.list = []
-
+
self.done = 0
self.zeroconf.addListener(self, DNSQuestion(self.type, _TYPE_PTR, _CLASS_IN))
@@ -1019,11 +1019,11 @@
if event is not None:
event(self.zeroconf)
-
+
class ServiceInfo(object):
"""Service information"""
-
+
def __init__(self, type, name, address=None, port=None, weight=0, priority=0, properties=None, server=None):
"""Create a service description.
@@ -1089,7 +1089,7 @@
index += 1
strs.append(text[index:index+length])
index += length
-
+
for s in strs:
eindex = s.find('=')
if eindex == -1:
@@ -1112,7 +1112,7 @@
except:
traceback.print_exc()
self.properties = None
-
+
def getType(self):
"""Type accessor"""
return self.type
@@ -1200,7 +1200,7 @@
result = 1
finally:
zeroconf.removeListener(self)
-
+
return result
def __eq__(self, other):
@@ -1225,7 +1225,7 @@
result += self.text[:17] + "..."
result += "]"
return result
-
+
class Zeroconf(object):
"""Implementation of Zeroconf Multicast DNS Service Discovery
@@ -1274,7 +1274,7 @@
self.cache = DNSCache()
self.condition = threading.Condition()
-
+
self.engine = Engine(self)
self.listener = Listener(self)
self.reaper = Reaper(self)
@@ -1465,7 +1465,7 @@
record = entry
else:
self.cache.add(record)
-
+
self.updateRecord(now, record)
def handleQuery(self, msg, addr, port):
@@ -1479,7 +1479,7 @@
out = DNSOutgoing(_FLAGS_QR_RESPONSE | _FLAGS_AA, 0)
for question in msg.questions:
out.addQuestion(question)
-
+
for question in msg.questions:
if question.type == _TYPE_PTR:
for service in self.services.values():
@@ -1491,16 +1491,16 @@
try:
if out is None:
out = DNSOutgoing(_FLAGS_QR_RESPONSE | _FLAGS_AA)
-
+
# Answer A record queries for any service addresses we know
if question.type == _TYPE_A or question.type == _TYPE_ANY:
for service in self.services.values():
if service.server == question.name.lower():
out.addAnswer(msg, DNSAddress(question.name, _TYPE_A, _CLASS_IN | _CLASS_UNIQUE, _DNS_TTL, service.address))
-
+
service = self.services.get(question.name.lower(), None)
if not service: continue
-
+
if question.type == _TYPE_SRV or question.type == _TYPE_ANY:
out.addAnswer(msg, DNSService(question.name, _TYPE_SRV, _CLASS_IN | _CLASS_UNIQUE, _DNS_TTL, service.priority, service.weight, service.port, service.server))
if question.type == _TYPE_TXT or question.type == _TYPE_ANY:
@@ -1509,7 +1509,7 @@
out.addAdditionalAnswer(DNSAddress(service.server, _TYPE_A, _CLASS_IN | _CLASS_UNIQUE, _DNS_TTL, service.address))
except:
traceback.print_exc()
-
+
if out is not None and out.answers:
out.id = msg.id
self.send(out, addr, port)
@@ -1534,11 +1534,11 @@
self.unregisterAllServices()
self.socket.setsockopt(socket.SOL_IP, socket.IP_DROP_MEMBERSHIP, socket.inet_aton(_MDNS_ADDR) + socket.inet_aton('0.0.0.0'))
self.socket.close()
-
+
# Test a few module features, including service registration, service
# query (for Zoe), and service unregistration.
-if __name__ == '__main__':
+if __name__ == '__main__':
print "Multicast DNS Service Discovery for Python, version", __version__
r = Zeroconf()
print "1. Testing registration of a service..."
--- a/wxglade_hmi/wxglade_hmi.py Fri Aug 11 15:18:19 2017 +0300
+++ b/wxglade_hmi/wxglade_hmi.py Mon Aug 14 19:13:01 2017 +0300
@@ -56,7 +56,7 @@
path = None
try:
from wxglade import __file__ as fileName
- path = os.path.dirname(fileName)
+ path = os.path.dirname(fileName)
return path
except ImportError:
pass
@@ -66,7 +66,7 @@
path = defLibDir
return path
-
+
def launch_wxglade(self, options, wait=False):
path = self.GetWxGladePath()
glade = os.path.join(path, 'wxglade.py')
@@ -82,24 +82,24 @@
return PythonFileCTNMixin.OnCTNSave(self, from_project_path)
def CTNGenerate_C(self, buildpath, locations):
-
+
hmi_frames = []
-
+
wxgfile_path=self._getWXGLADEpath()
if os.path.exists(wxgfile_path):
wxgfile = open(wxgfile_path, 'r')
wxgtree = minidom.parse(wxgfile)
wxgfile.close()
-
+
for node in wxgtree.childNodes[1].childNodes:
if node.nodeType == wxgtree.ELEMENT_NODE:
hmi_frames.append({
"name" : node.getAttribute("name"),
"class" : node.getAttribute("class"),
"handlers" : [
- hnode.firstChild.data for hnode in
+ hnode.firstChild.data for hnode in
node.getElementsByTagName("handler")]})
-
+
hmipyfile_path=os.path.join(self._getBuildPath(), "hmi.py")
if wx.Platform == '__WXMSW__':
wxgfile_path = "\"%s\""%wxgfile_path
@@ -107,20 +107,20 @@
else:
wxghmipyfile_path = hmipyfile_path
self.launch_wxglade(['-o', wxghmipyfile_path, '-g', 'python', wxgfile_path], wait=True)
-
+
hmipyfile = open(hmipyfile_path, 'r')
define_hmi = hmipyfile.read().decode('utf-8')
hmipyfile.close()
-
+
else:
define_hmi = ""
-
- declare_hmi = "\n".join(["%(name)s = None\n" % x +
+
+ declare_hmi = "\n".join(["%(name)s = None\n" % x +
"\n".join(["%(class)s.%(h)s = %(h)s"%
dict(x,h=h) for h in x['handlers']])
for x in hmi_frames])
global_hmi = ("global %s\n"%",".join(
- [x["name"] for x in hmi_frames])
+ [x["name"] for x in hmi_frames])
if len(hmi_frames) > 0 else "")
init_hmi = "\n".join(["""\
def OnCloseFrame(evt):
@@ -131,9 +131,9 @@
%(name)s.Show()
""" % x for x in hmi_frames])
cleanup_hmi = "\n".join(
- ["if %(name)s is not None: %(name)s.Destroy()" % x
+ ["if %(name)s is not None: %(name)s.Destroy()" % x
for x in hmi_frames])
-
+
self.PreSectionsTexts = {
"globals":define_hmi,
"start":global_hmi,
@@ -174,4 +174,3 @@
if wx.Platform == '__WXMSW__':
wxg_filename = "\"%s\""%wxg_filename
self.launch_wxglade([wxg_filename])
-
--- a/xmlclass/xmlclass.py Fri Aug 11 15:18:19 2017 +0300
+++ b/xmlclass/xmlclass.py Mon Aug 14 19:13:01 2017 +0300
@@ -93,7 +93,7 @@
def dst(self, dt):
return ZERO
-[SYNTAXELEMENT, SYNTAXATTRIBUTE, SIMPLETYPE, COMPLEXTYPE, COMPILEDCOMPLEXTYPE,
+[SYNTAXELEMENT, SYNTAXATTRIBUTE, SIMPLETYPE, COMPLEXTYPE, COMPILEDCOMPLEXTYPE,
ATTRIBUTESGROUP, ELEMENTSGROUP, ATTRIBUTE, ELEMENT, CHOICE, ANY, TAG, CONSTRAINT,
] = range(13)
@@ -140,7 +140,7 @@
def GetNormalizedString(attr, extract=True):
"""
- Function that normalizes a string according to XML 1.0. Replace
+ Function that normalizes a string according to XML 1.0. Replace
tabulations, line feed and carriage return by white space
@param attr: tree node containing data to extract or data to normalize
@param extract: attr is a tree node or not
@@ -155,14 +155,14 @@
def GetToken(attr, extract=True):
"""
- Function that tokenizes a string according to XML 1.0. Remove any leading
- and trailing white space and replace internal sequence of two or more
+ Function that tokenizes a string according to XML 1.0. Remove any leading
+ and trailing white space and replace internal sequence of two or more
spaces by only one white space
@param attr: tree node containing data to extract or data to tokenize
@param extract: attr is a tree node or not
@return: data tokenized as string
"""
- return " ".join([part for part in
+ return " ".join([part for part in
GetNormalizedString(attr, extract).split(" ")
if part])
@@ -186,7 +186,7 @@
raise ValueError("\"%s\" isn't a valid hexadecimal integer!" % value)
-def GenerateIntegerExtraction(minInclusive=None, maxInclusive=None,
+def GenerateIntegerExtraction(minInclusive=None, maxInclusive=None,
minExclusive=None, maxExclusive=None):
"""
Function that generates an extraction function for integer defining min and
@@ -517,7 +517,7 @@
check that all extracted items match the model
@param attr: tree node containing data to extract or data as a string
@param extract: attr is a tree node or not
- @return: data as a list of string if matching
+ @return: data as a list of string if matching
"""
if extract:
value = GetAttributeValue(attr)
@@ -535,18 +535,18 @@
return GetModelNameList
def GenerateAnyInfos(infos):
-
+
def GetTextElement(tree):
if infos["namespace"][0] == "##any":
return tree.xpath("p")[0]
return tree.xpath("ns:p", namespaces={"ns": infos["namespace"][0]})[0]
-
+
def ExtractAny(tree):
return GetTextElement(tree).text
-
+
def GenerateAny(tree, value):
GetTextElement(tree).text = etree.CDATA(value)
-
+
def InitialAny():
if infos["namespace"][0] == "##any":
element_name = "p"
@@ -555,9 +555,9 @@
p = etree.Element(element_name)
p.text = etree.CDATA("")
return p
-
+
return {
- "type": COMPLEXTYPE,
+ "type": COMPLEXTYPE,
"extract": ExtractAny,
"generate": GenerateAny,
"initial": InitialAny,
@@ -574,16 +574,16 @@
return True
else:
return None
-
+
def GenerateTag(value, name=None, indent=0):
if name is not None and not (infos["minOccurs"] == 0 and value is None):
ind1, ind2 = getIndent(indent, name)
return ind1 + "<%s/>\n" % name
else:
return ""
-
+
return {
- "type": TAG,
+ "type": TAG,
"extract": ExtractTag,
"generate": GenerateTag,
"initial": lambda: None,
@@ -595,7 +595,7 @@
namespace, name = DecomposeQualifiedName(infos)
return factory.GetQualifiedNameInfos(name, namespace)
return infos
-
+
def GetElementInitialValue(factory, infos):
infos["elmt_type"] = FindTypeInfos(factory, infos["elmt_type"])
if infos["minOccurs"] == 1:
@@ -667,7 +667,7 @@
prefix = ("%s:" % factory.TargetNamespace
if factory.TargetNamespace is not None else "")
choices_xpath = "|".join(map(lambda x: prefix + x, choices_dict.keys()))
-
+
def GetContentInitial():
content_name, infos = choices[0]
if content_name == "sequence":
@@ -678,7 +678,7 @@
else:
content_value = GetElementInitialValue(factory, infos)
return content_value
-
+
return {
"type": COMPLEXTYPE,
"choices_xpath": etree.XPath(choices_xpath, namespaces=factory.NSMAP),
@@ -693,13 +693,13 @@
def DecomposeQualifiedName(name):
result = QName_model.match(name)
if not result:
- raise ValueError("\"%s\" isn't a valid QName value!" % name)
+ raise ValueError("\"%s\" isn't a valid QName value!" % name)
parts = result.groups()[0].split(':')
if len(parts) == 1:
return None, parts[0]
return parts
-
-def GenerateElement(element_name, attributes, elements_model,
+
+def GenerateElement(element_name, attributes, elements_model,
accept_text=False):
def ExtractElement(factory, node):
attrs = factory.ExtractNodeAttrs(element_name, node, attributes)
@@ -746,20 +746,20 @@
else:
self.BaseFolder = self.FileName = None
self.Debug = debug
-
+
# Dictionary for stocking Classes and Types definitions created from
# the XML tree
self.XMLClassDefinitions = {}
-
+
self.DefinedNamespaces = {}
self.NSMAP = {}
self.Namespaces = {}
self.SchemaNamespace = None
self.TargetNamespace = None
self.etreeNamespaceFormat = "%s"
-
+
self.CurrentCompilations = []
-
+
# Dictionaries for stocking Classes and Types generated
self.ComputeAfter = []
if self.FileName is not None:
@@ -920,15 +920,15 @@
def ParseSchema(self):
pass
-
+
def AddEquivalentClass(self, name, base):
if name != base:
equivalences = self.EquivalentClassesParent.setdefault(self.etreeNamespaceFormat % base, {})
equivalences[self.etreeNamespaceFormat % name] = True
-
+
def AddDistinctionBetweenParentsInLookupClass(
self, lookup_classes, parent, typeinfos):
- parent = (self.etreeNamespaceFormat % parent
+ parent = (self.etreeNamespaceFormat % parent
if parent is not None else None)
parent_class = lookup_classes.get(parent)
if parent_class is not None:
@@ -939,7 +939,7 @@
lookup_classes[parent] = [typeinfos, parent_class]
else:
lookup_classes[parent] = typeinfos
-
+
def AddToLookupClass(self, name, parent, typeinfos):
lookup_name = self.etreeNamespaceFormat % name
if isinstance(typeinfos, (StringType, UnicodeType)):
@@ -958,7 +958,7 @@
self.AddDistinctionBetweenParentsInLookupClass(
lookup_classes, parent, typeinfos)
self.ComputedClassesLookUp[lookup_name] = lookup_classes
-
+
def ExtractTypeInfos(self, name, parent, typeinfos):
if isinstance(typeinfos, (StringType, UnicodeType)):
namespace, type_name = DecomposeQualifiedName(typeinfos)
@@ -986,12 +986,12 @@
return self.CreateClass(name, parent, typeinfos)
elif typeinfos["type"] == SIMPLETYPE:
return typeinfos
-
+
def GetEquivalentParents(self, parent):
return reduce(lambda x, y: x + y,
[[p] + self.GetEquivalentParents(p)
for p in self.EquivalentClassesParent.get(parent, {}).keys()], [])
-
+
"""
Methods that generates the classes
"""
@@ -1028,7 +1028,7 @@
if result is not None and \
not isinstance(result, (UnicodeType, StringType)):
self.Namespaces[self.TargetNamespace][result["name"]] = result
-
+
for name, parents in self.ComputedClassesLookUp.iteritems():
if isinstance(parents, DictType):
computed_classes = parents.items()
@@ -1042,7 +1042,7 @@
parents = dict(computed_classes)
self.ComputedClassesLookUp[name] = parents
parents[equivalent_parent] = computed_class
-
+
return self.ComputedClasses
def CreateClass(self, name, parent, classinfos, baseclass = False):
@@ -1050,11 +1050,11 @@
classname = "%s_%s" % (parent, name)
else:
classname = name
-
+
# Checks that classe haven't been generated yet
if self.AlreadyComputed.get(classname, False):
return self.ComputedClassesInfos.get(classname, None)
-
+
# If base classes haven't been generated
bases = []
base_infos = classinfos.get("base", None)
@@ -1088,12 +1088,12 @@
bases.append(DefaultElementClass)
bases = tuple(bases)
classmembers = {"__doc__": classinfos.get("doc", ""), "IsBaseClass": baseclass}
-
+
self.AlreadyComputed[classname] = True
-
+
for attribute in classinfos["attributes"]:
infos = self.ExtractTypeInfos(attribute["name"], name, attribute["attr_type"])
- if infos is not None:
+ if infos is not None:
if infos["type"] != SIMPLETYPE:
raise ValueError("\"%s\" type is not a simple type!" % attribute["attr_type"])
attrname = attribute["name"]
@@ -1105,7 +1105,7 @@
else:
raise ValueError("\"%s\" type unrecognized!" % attribute["attr_type"])
attribute["attr_type"] = infos
-
+
for element in classinfos["elements"]:
if element["type"] == CHOICE:
elmtname = element["name"]
@@ -1141,13 +1141,13 @@
classmembers["delete%s" % elmtname] = generateDeleteMethod(elmtname)
classmembers["set%s" % elmtname] = generateSetMethod(elmtname)
classmembers["get%s" % elmtname] = generateGetMethod(elmtname)
-
+
classmembers["_init_"] = generateInitMethod(self, classinfos)
classmembers["StructurePattern"] = GetStructurePattern(classinfos)
classmembers["getElementAttributes"] = generateGetElementAttributes(self, classinfos)
classmembers["getElementInfos"] = generateGetElementInfos(self, classinfos)
classmembers["setElementValue"] = generateSetElementValue(self, classinfos)
-
+
class_definition = classobj(str(name), bases, classmembers)
setattr(class_definition, "__getattr__", generateGetattrMethod(self, class_definition, classinfos))
setattr(class_definition, "__setattr__", generateSetattrMethod(self, class_definition, classinfos))
@@ -1155,16 +1155,16 @@
"name": classname,
"initial": generateClassCreateFunction(class_definition),
}
-
+
if self.FileName is not None:
self.ComputedClasses[self.FileName][classname] = class_definition
else:
self.ComputedClasses[classname] = class_definition
self.ComputedClassesInfos[classname] = class_infos
-
+
self.AddToLookupClass(name, parent, class_definition)
self.AddToLookupClass(classname, None, class_definition)
-
+
return class_infos
"""
@@ -1183,7 +1183,7 @@
else:
for classname, xmlclass in items:
print "%s: %s" % (classname, str(xmlclass))
-
+
def PrintClassNames(self):
classnames = self.XMLClassDefinitions.keys()
classnames.sort()
@@ -1191,7 +1191,7 @@
print classname
"""
-Method that generate the method for generating the xml tree structure model by
+Method that generate the method for generating the xml tree structure model by
following the attributes list defined
"""
def ComputeMultiplicity(name, infos):
@@ -1213,7 +1213,7 @@
if infos["maxOccurs"] == "unbounded":
return "(?:%s){%d,}" % (name, infos["minOccurs"], name)
else:
- return "(?:%s){%d,%d}" % (name, infos["minOccurs"],
+ return "(?:%s){%d,%d}" % (name, infos["minOccurs"],
infos["maxOccurs"])
def GetStructurePattern(classinfos):
@@ -1256,7 +1256,7 @@
attributes = dict([(attr["name"], attr) for attr in classinfos["attributes"] if attr["use"] != "prohibited"])
optional_attributes = dict([(attr["name"], True) for attr in classinfos["attributes"] if attr["use"] == "optional"])
elements = dict([(element["name"], element) for element in classinfos["elements"]])
-
+
def getattrMethod(self, name):
if attributes.has_key(name):
attribute_infos = attributes[name]
@@ -1269,7 +1269,7 @@
elif attribute_infos.has_key("default"):
return attribute_infos["attr_type"]["extract"](attribute_infos["default"], extract=False)
return None
-
+
elif elements.has_key(name):
element_infos = elements[name]
element_infos["elmt_type"] = FindTypeInfos(factory, element_infos["elmt_type"])
@@ -1279,7 +1279,7 @@
return content
elif len(content) > 0:
return content[0]
- return None
+ return None
elif element_infos["type"] == ANY:
return element_infos["elmt_type"]["extract"](self)
elif name == "content" and element_infos["elmt_type"]["type"] == SIMPLETYPE:
@@ -1290,7 +1290,7 @@
values = self.findall(element_name)
if element_infos["elmt_type"]["type"] == SIMPLETYPE:
return map(lambda value:
- element_infos["elmt_type"]["extract"](value.text, extract=False),
+ element_infos["elmt_type"]["extract"](value.text, extract=False),
values)
return values
else:
@@ -1298,19 +1298,19 @@
if element_infos["elmt_type"]["type"] == SIMPLETYPE:
return element_infos["elmt_type"]["extract"](value.text, extract=False)
return value
-
+
elif classinfos.has_key("base"):
return classinfos["base"].__getattr__(self, name)
-
+
return DefaultElementClass.__getattribute__(self, name)
-
+
return getattrMethod
def generateSetattrMethod(factory, class_definition, classinfos):
attributes = dict([(attr["name"], attr) for attr in classinfos["attributes"] if attr["use"] != "prohibited"])
optional_attributes = dict([(attr["name"], True) for attr in classinfos["attributes"] if attr["use"] == "optional"])
elements = OrderedDict([(element["name"], element) for element in classinfos["elements"]])
-
+
def setattrMethod(self, name, value):
if attributes.has_key(name):
attribute_infos = attributes[name]
@@ -1323,26 +1323,26 @@
elif attribute_infos.has_key("fixed"):
return
return self.set(name, attribute_infos["attr_type"]["generate"](value))
-
+
elif elements.has_key(name):
element_infos = elements[name]
element_infos["elmt_type"] = FindTypeInfos(factory, element_infos["elmt_type"])
if element_infos["type"] == ANY:
element_infos["elmt_type"]["generate"](self, value)
-
+
elif name == "content" and element_infos["elmt_type"]["type"] == SIMPLETYPE:
self.text = element_infos["elmt_type"]["generate"](value)
-
+
else:
prefix = ("%s:" % factory.TargetNamespace
if factory.TargetNamespace is not None else "")
element_xpath = (prefix + name
if name != "content"
else elements["content"]["elmt_type"]["choices_xpath"].path)
-
+
for element in self.xpath(element_xpath, namespaces=factory.NSMAP):
self.remove(element)
-
+
if value is not None:
element_idx = elements.keys().index(name)
if element_idx > 0:
@@ -1351,27 +1351,27 @@
if x != "content"
else elements["content"]["elmt_type"]["choices_xpath"].path,
elements.keys()[:element_idx]))
-
+
insertion_point = len(self.xpath(previous_elements_xpath, namespaces=factory.NSMAP))
else:
insertion_point = 0
-
+
if not isinstance(value, ListType):
value = [value]
-
+
for element in reversed(value):
if element_infos["elmt_type"]["type"] == SIMPLETYPE:
tmp_element = etree.Element(factory.etreeNamespaceFormat % name)
tmp_element.text = element_infos["elmt_type"]["generate"](element)
element = tmp_element
self.insert(insertion_point, element)
-
+
elif classinfos.has_key("base"):
return classinfos["base"].__setattr__(self, name, value)
-
+
else:
raise AttributeError("'%s' can't have an attribute '%s'." % (self.__class__.__name__, name))
-
+
return setattrMethod
def gettypeinfos(name, facets):
@@ -1398,7 +1398,7 @@
attr_list.extend(classinfos["base"].getElementAttributes(self))
for attr in classinfos["attributes"]:
if attr["use"] != "prohibited":
- attr_params = {"name" : attr["name"], "use" : attr["use"],
+ attr_params = {"name" : attr["name"], "use" : attr["use"],
"type" : gettypeinfos(attr["attr_type"]["basename"], attr["attr_type"]["facets"]),
"value" : getattr(self, attr["name"], "")}
attr_list.append(attr_params)
@@ -1408,7 +1408,7 @@
def generateGetElementInfos(factory, classinfos):
attributes = dict([(attr["name"], attr) for attr in classinfos["attributes"] if attr["use"] != "prohibited"])
elements = dict([(element["name"], element) for element in classinfos["elements"]])
-
+
def getElementInfos(self, name, path=None, derived=False):
attr_type = "element"
value = None
@@ -1419,14 +1419,14 @@
if attributes.has_key(parts[0]):
if len(parts) != 1:
raise ValueError("Wrong path!")
- attr_type = gettypeinfos(attributes[parts[0]]["attr_type"]["basename"],
+ attr_type = gettypeinfos(attributes[parts[0]]["attr_type"]["basename"],
attributes[parts[0]]["attr_type"]["facets"])
value = getattr(self, parts[0], "")
elif elements.has_key(parts[0]):
if elements[parts[0]]["elmt_type"]["type"] == SIMPLETYPE:
if len(parts) != 1:
raise ValueError("Wrong path!")
- attr_type = gettypeinfos(elements[parts[0]]["elmt_type"]["basename"],
+ attr_type = gettypeinfos(elements[parts[0]]["elmt_type"]["basename"],
elements[parts[0]]["elmt_type"]["facets"])
value = getattr(self, parts[0], "")
elif parts[0] == "content":
@@ -1463,8 +1463,8 @@
if self.content is not None:
children.extend(self.content.getElementInfos(value)["children"])
elif element["elmt_type"]["type"] == SIMPLETYPE:
- children.append({"name": element_name, "require": element["minOccurs"] != 0,
- "type": gettypeinfos(element["elmt_type"]["basename"],
+ children.append({"name": element_name, "require": element["minOccurs"] != 0,
+ "type": gettypeinfos(element["elmt_type"]["basename"],
element["elmt_type"]["facets"]),
"value": getattr(self, element_name, None)})
else:
@@ -1478,7 +1478,7 @@
def generateSetElementValue(factory, classinfos):
attributes = dict([(attr["name"], attr) for attr in classinfos["attributes"] if attr["use"] != "prohibited"])
elements = dict([(element["name"], element) for element in classinfos["elements"]])
-
+
def setElementValue(self, path, value):
if path is not None:
parts = path.split(".", 1)
@@ -1489,7 +1489,7 @@
setattr(self, parts[0], value)
elif attributes[parts[0]]["use"] == "optional" and value == "":
if attributes[parts[0]].has_key("default"):
- setattr(self, parts[0],
+ setattr(self, parts[0],
attributes[parts[0]]["attr_type"]["extract"](
attributes[parts[0]]["default"], False))
else:
@@ -1680,39 +1680,39 @@
NAMESPACE_PATTERN = re.compile("xmlns(?:\:[^\=]*)?=\"[^\"]*\" ")
class DefaultElementClass(etree.ElementBase):
-
+
StructurePattern = re.compile("$")
-
+
def _init_(self):
pass
-
+
def getLocalTag(self):
return etree.QName(self.tag).localname
-
+
def tostring(self):
return NAMESPACE_PATTERN.sub("", etree.tostring(self, pretty_print=True, encoding='utf-8')).decode('utf-8')
class XMLElementClassLookUp(etree.PythonElementClassLookup):
-
+
def __init__(self, classes, *args, **kwargs):
etree.PythonElementClassLookup.__init__(self, *args, **kwargs)
self.LookUpClasses = classes
-
+
def GetElementClass(self, element_tag, parent_tag=None, default=DefaultElementClass):
element_class = self.LookUpClasses.get(element_tag, (default, None))
if not isinstance(element_class, DictType):
if isinstance(element_class[0], (StringType, UnicodeType)):
return self.GetElementClass(element_class[0], default=default)
return element_class[0]
-
+
element_with_parent_class = element_class.get(parent_tag, default)
if isinstance(element_with_parent_class, (StringType, UnicodeType)):
return self.GetElementClass(element_with_parent_class, default=default)
return element_with_parent_class
-
+
def lookup(self, document, element):
parent = element.getparent()
- element_class = self.GetElementClass(element.tag,
+ element_class = self.GetElementClass(element.tag,
parent.tag if parent is not None else None)
if isinstance(element_class, ListType):
children = "".join([
@@ -1741,24 +1741,24 @@
self.RootNSMAP = namespaces
self.BaseClass = base_class
self.XSDSchema = xsd_schema
-
+
def set_element_class_lookup(self, class_lookup):
etree.XMLParser.set_element_class_lookup(self, class_lookup)
self.ClassLookup = class_lookup
-
+
def LoadXMLString(self, xml_string):
tree = etree.fromstring(xml_string, self)
if not self.XSDSchema.validate(tree):
error = self.XSDSchema.error_log.last_error
return tree, (error.line, error.message)
- return tree, None
-
+ return tree, None
+
def Dumps(self, xml_obj):
return etree.tostring(xml_obj, encoding='utf-8')
-
+
def Loads(self, xml_string):
return etree.fromstring(xml_string, self)
-
+
def CreateRoot(self):
if self.BaseClass is not None:
root = self.makeelement(
@@ -1767,14 +1767,14 @@
root._init_()
return root
return None
-
+
def GetElementClass(self, element_tag, parent_tag=None):
return self.ClassLookup.GetElementClass(
- self.DefaultNamespaceFormat % element_tag,
- self.DefaultNamespaceFormat % parent_tag
- if parent_tag is not None else parent_tag,
+ self.DefaultNamespaceFormat % element_tag,
+ self.DefaultNamespaceFormat % parent_tag
+ if parent_tag is not None else parent_tag,
None)
-
+
def CreateElement(self, element_tag, parent_tag=None, class_idx=None):
element_class = self.GetElementClass(element_tag, parent_tag)
if isinstance(element_class, ListType):
@@ -1787,14 +1787,14 @@
DefaultElementClass.__setattr__(new_element, "tag", self.DefaultNamespaceFormat % element_tag)
new_element._init_()
return new_element
-
+
def GenerateParser(factory, xsdstring):
ComputedClasses = factory.CreateClasses()
-
+
if factory.FileName is not None:
ComputedClasses = ComputedClasses[factory.FileName]
BaseClass = [(name, XSDclass) for name, XSDclass in ComputedClasses.items() if XSDclass.IsBaseClass]
-
+
parser = XMLClassParser(
factory.NSMAP,
factory.etreeNamespaceFormat,
@@ -1803,6 +1803,5 @@
strip_cdata = False, remove_blank_text=True)
class_lookup = XMLElementClassLookUp(factory.ComputedClassesLookUp)
parser.set_element_class_lookup(class_lookup)
-
+
return parser
-
--- a/xmlclass/xsdschema.py Fri Aug 11 15:18:19 2017 +0300
+++ b/xmlclass/xsdschema.py Mon Aug 14 19:13:01 2017 +0300
@@ -62,14 +62,14 @@
text += "</%s>\n" % name
return text
return generateXMLTextMethod
-
+
DEFAULT_FACETS = GenerateDictFacets(["pattern", "whiteSpace", "enumeration"])
NUMBER_FACETS = GenerateDictFacets(DEFAULT_FACETS.keys() + ["maxInclusive", "maxExclusive", "minInclusive", "minExclusive"])
DECIMAL_FACETS = GenerateDictFacets(NUMBER_FACETS.keys() + ["totalDigits", "fractionDigits"])
STRING_FACETS = GenerateDictFacets(DEFAULT_FACETS.keys() + ["length", "minLength", "maxLength"])
-ALL_FACETS = ["pattern", "whiteSpace", "enumeration", "maxInclusive",
- "maxExclusive", "minInclusive", "minExclusive", "totalDigits",
+ALL_FACETS = ["pattern", "whiteSpace", "enumeration", "maxInclusive",
+ "maxExclusive", "minInclusive", "minExclusive", "totalDigits",
"fractionDigits", "length", "minLength", "maxLength"]
@@ -81,12 +81,12 @@
# Documentation elements
def ReduceAppInfo(factory, attributes, elements):
- return {"type": "appinfo", "source": attributes.get("source", None),
+ return {"type": "appinfo", "source": attributes.get("source", None),
"content": "\n".join(elements)}
def ReduceDocumentation(factory, attributes, elements):
- return {"type": "documentation", "source": attributes.get("source", None),
+ return {"type": "documentation", "source": attributes.get("source", None),
"language": attributes.get("lang", "any"), "content": "\n".join(elements)}
@@ -124,7 +124,7 @@
def ReduceList(factory, attributes, elements):
annotations, children = factory.ReduceElements(elements)
list = {"type": "list", "itemType": attributes.get("itemType", None), "doc": annotations}
-
+
if len(children) > 0 and children[0]["type"] == SIMPLETYPE:
if list["itemType"] is None:
list["itemType"] = children[0]
@@ -138,7 +138,7 @@
def ReduceUnion(factory, attributes, elements):
annotations, children = factory.ReduceElements(elements)
union = {"type": "union", "memberTypes": attributes.get("memberTypes", []), "doc": annotations}
-
+
for child in children:
if child["type"] == SIMPLETYPE:
union["memberTypes"].appendchild
@@ -153,29 +153,29 @@
simpleType = {"type": SIMPLETYPE, "final": attributes.get("final", [])}
if attributes.has_key("name"):
simpleType["name"] = attributes["name"]
-
+
if typeinfos["type"] in ["restriction", "extension"]:
# Search for base type definition
if isinstance(typeinfos["base"], (StringType, UnicodeType)):
basetypeinfos = factory.FindSchemaElement(typeinfos["base"], SIMPLETYPE)
if basetypeinfos is None:
- raise "\"%s\" isn't defined!" % typeinfos["base"]
+ raise "\"%s\" isn't defined!" % typeinfos["base"]
else:
basetypeinfos = typeinfos["base"]
-
+
# Check that base type is a simple type
if basetypeinfos["type"] != SIMPLETYPE:
raise ValueError("Base type given isn't a simpleType!")
-
+
simpleType["basename"] = basetypeinfos["basename"]
-
+
# Check that derivation is allowed
if basetypeinfos.has_key("final"):
if "#all" in basetypeinfos["final"]:
raise ValueError("Base type can't be derivated!")
if "restriction" in basetypeinfos["final"] and typeinfos["type"] == "restriction":
raise ValueError("Base type can't be derivated by restriction!")
-
+
# Extract simple type facets
for facet in typeinfos.get("facets", []):
facettype = facet["type"]
@@ -286,12 +286,12 @@
elif basevalue is not None and value > basevalue:
raise ValueError("\"totalDigits\" can't be greater than \"totalDigits\" defined in base type!")
facets[facettype] = (value, facet.get("fixed", False))
-
- # Report not redefined facet from base type to new created type
+
+ # Report not redefined facet from base type to new created type
for facettype, facetvalue in basetypeinfos["facets"].items():
if not facets.has_key(facettype):
facets[facettype] = facetvalue
-
+
# Generate extract value for new created type
def ExtractSimpleTypeValue(attr, extract=True):
value = basetypeinfos["extract"](attr, extract)
@@ -317,7 +317,7 @@
model = re.compile("(?:%s)?$" % "|".join(map(lambda x: "(?:%s)" % x, facetvalue)))
result = model.match(value)
if result is None:
- if len(facetvalue) > 1:
+ if len(facetvalue) > 1:
raise ValueError("value doesn't follow any of the patterns %s" % ",".join(facetvalue))
else:
raise ValueError("value doesn't follow the pattern %s" % facetvalue[0])
@@ -327,7 +327,7 @@
elif facetvalue == "collapse":
value = GetToken(value, False)
return value
-
+
def CheckSimpleTypeValue(value):
for facetname, (facetvalue, facetfixed) in facets.items():
if facetvalue is not None:
@@ -351,12 +351,12 @@
model = re.compile("(?:%s)?$" % "|".join(map(lambda x: "(?:%s)" % x, facetvalue)))
result = model.match(value)
if result is None:
- if len(facetvalue) > 1:
+ if len(facetvalue) > 1:
raise ValueError("value doesn't follow any of the patterns %s" % ",".join(facetvalue))
else:
raise ValueError("value doesn't follow the pattern %s" % facetvalue[0])
return True
-
+
def SimpleTypeInitialValue():
for facetname, (facetvalue, facetfixed) in facets.items():
if facetvalue is not None:
@@ -375,9 +375,9 @@
elif facetname == "maxExclusive" and facetvalue <= 0:
return facetvalue - 1
return basetypeinfos["initial"]()
-
+
GenerateSimpleType = basetypeinfos["generate"]
-
+
elif typeinfos["type"] == "list":
# Search for item type definition
if isinstance(typeinfos["itemType"], (StringType, UnicodeType)):
@@ -386,41 +386,41 @@
raise "\"%s\" isn't defined!" % typeinfos["itemType"]
else:
itemtypeinfos = typeinfos["itemType"]
-
+
# Check that item type is a simple type
if itemtypeinfos["type"] != SIMPLETYPE:
raise ValueError, "Item type given isn't a simpleType!"
-
+
simpleType["basename"] = "list"
-
+
# Check that derivation is allowed
if itemtypeinfos.has_key("final"):
if itemtypeinfos["final"].has_key("#all"):
raise ValueError("Item type can't be derivated!")
if itemtypeinfos["final"].has_key("list"):
raise ValueError("Item type can't be derivated by list!")
-
+
# Generate extract value for new created type
def ExtractSimpleTypeValue(attr, extract = True):
values = []
for value in GetToken(attr, extract).split(" "):
values.append(itemtypeinfos["extract"](value, False))
return values
-
+
def CheckSimpleTypeValue(value):
for item in value:
result = itemtypeinfos["check"](item)
if not result:
return result
return True
-
+
SimpleTypeInitialValue = lambda: []
-
+
GenerateSimpleType = GenerateSimpleTypeXMLText(lambda x: " ".join(map(itemtypeinfos["generate"], x)))
-
+
facets = GenerateDictFacets(["length", "maxLength", "minLength", "enumeration", "pattern"])
facets["whiteSpace"] = ("collapse", False)
-
+
elif typeinfos["type"] == "union":
# Search for member types definition
membertypesinfos = []
@@ -431,22 +431,22 @@
raise ValueError("\"%s\" isn't defined!" % membertype)
else:
infos = membertype
-
+
# Check that member type is a simple type
if infos["type"] != SIMPLETYPE:
raise ValueError("Member type given isn't a simpleType!")
-
+
# Check that derivation is allowed
if infos.has_key("final"):
if infos["final"].has_key("#all"):
raise ValueError("Item type can't be derivated!")
if infos["final"].has_key("union"):
raise ValueError("Member type can't be derivated by union!")
-
+
membertypesinfos.append(infos)
-
+
simpleType["basename"] = "union"
-
+
# Generate extract value for new created type
def ExtractSimpleTypeValue(attr, extract = True):
if extract:
@@ -459,25 +459,25 @@
except:
pass
raise ValueError("\"%s\" isn't valid for type defined for union!")
-
+
def CheckSimpleTypeValue(value):
for infos in membertypesinfos:
result = infos["check"](value)
if result:
return result
return False
-
+
SimpleTypeInitialValue = membertypesinfos[0]["initial"]
-
+
def GenerateSimpleTypeFunction(value):
if isinstance(value, BooleanType):
return {True: "true", False: "false"}[value]
else:
return str(value)
GenerateSimpleType = GenerateSimpleTypeXMLText(GenerateSimpleTypeFunction)
-
+
facets = GenerateDictFacets(["pattern", "enumeration"])
-
+
simpleType["facets"] = facets
simpleType["extract"] = ExtractSimpleTypeValue
simpleType["initial"] = SimpleTypeInitialValue
@@ -488,10 +488,10 @@
def ReduceSimpleType(factory, attributes, elements):
# Reduce all the simple type children
annotations, children = factory.ReduceElements(elements)
-
+
simpleType = CreateSimpleType(factory, attributes, children[0])
simpleType["doc"] = annotations
-
+
return simpleType
# Complex type
@@ -503,7 +503,7 @@
basetypeinfos = factory.FindSchemaElement(base)
if not isinstance(basetypeinfos, (UnicodeType, StringType)) and basetypeinfos["type"] == COMPLEXTYPE:
attrnames = dict(map(lambda x:(x["name"], True), basetypeinfos["attributes"]))
-
+
for element in elements:
if element["type"] == ATTRIBUTE:
if attrnames.get(element["name"], False):
@@ -534,7 +534,7 @@
raise ValueError("Only one base type can be defined for restriction!")
if restriction["base"] is None:
raise ValueError("No base type has been defined for restriction!")
-
+
while len(children) > 0 and children[0]["type"] in ALL_FACETS:
restriction["facets"].append(children.pop(0))
restriction["attributes"] = ExtractAttributes(factory, children, restriction["base"])
@@ -571,9 +571,9 @@
def ReduceSimpleContent(factory, attributes, elements):
annotations, children = factory.ReduceElements(elements)
-
+
simpleContent = children[0].copy()
-
+
basetypeinfos = factory.FindSchemaElement(simpleContent["base"])
if basetypeinfos["type"] == SIMPLETYPE:
contenttypeinfos = simpleContent.copy()
@@ -588,7 +588,7 @@
else:
raise ValueError("No compatible base type defined for simpleContent!")
contenttypeinfos = CreateSimpleType(factory, attributes, contenttypeinfos)
-
+
simpleContent["elements"] = [{"name": "content", "type": ELEMENT,
"elmt_type": contenttypeinfos, "doc": annotations,
"minOccurs": 1, "maxOccurs": 1}]
@@ -605,7 +605,7 @@
def ReduceComplexType(factory, attributes, elements):
annotations, children = factory.ReduceElements(elements)
-
+
if len(children) > 0:
if children[0]["type"] in ["simpleContent", "complexContent"]:
complexType = children[0].copy()
@@ -666,20 +666,20 @@
def ReduceAttribute(factory, attributes, elements):
annotations, children = factory.ReduceElements(elements)
-
+
if attributes.has_key("default"):
if attributes.has_key("fixed"):
raise ValueError("\"default\" and \"fixed\" can't be defined at the same time!")
elif attributes.get("use", "optional") != "optional":
raise ValueError("if \"default\" present, \"use\" can only have the value \"optional\"!")
-
+
attribute = {"type": ATTRIBUTE, "attr_type": attributes.get("type", None), "doc": annotations}
if len(children) > 0:
if attribute["attr_type"] is None:
attribute["attr_type"] = children[0]
else:
raise ValueError("Only one type can be defined for attribute!")
-
+
if attributes.has_key("ref"):
if attributes.has_key("name"):
raise ValueError("\"ref\" and \"name\" can't be defined at the same time!")
@@ -689,7 +689,7 @@
raise ValueError("if \"ref\" is present, no type can be defined!")
elif attribute["attr_type"] is None:
raise ValueError("No type has been defined for attribute \"%s\"!" % attributes["name"])
-
+
if attributes.has_key("type"):
tmp_attrs = attributes.copy()
tmp_attrs.pop("type")
@@ -711,14 +711,14 @@
def ReduceAny(factory, attributes, elements):
annotations, children = factory.ReduceElements(elements)
-
+
any = {"type": ANY, "doc": annotations}
any.update(attributes)
return any
def ReduceElement(factory, attributes, elements):
annotations, children = factory.ReduceElements(elements)
-
+
types = []
constraints = []
for child in children:
@@ -726,10 +726,10 @@
constraints.append(child)
else:
types.append(child)
-
+
if attributes.has_key("default") and attributes.has_key("fixed"):
raise ValueError("\"default\" and \"fixed\" can't be defined at the same time!")
-
+
if attributes.has_key("ref"):
for attr in ["name", "default", "fixed", "form", "block", "type"]:
if attributes.has_key(attr):
@@ -738,7 +738,7 @@
raise ValueError("\"ref\" and \"nillable\" can't be defined at the same time!")
if len(types) > 0:
raise ValueError("No type and no constraints can be defined where \"ref\" is defined!")
-
+
infos = factory.FindSchemaElement(attributes["ref"], ELEMENT)
if infos is not None:
element = infos.copy()
@@ -748,7 +748,7 @@
return element
else:
raise ValueError("\"%s\" base type isn't defined or circular referenced!" % name)
-
+
elif attributes.has_key("name"):
element = {"type": ELEMENT, "elmt_type": attributes.get("type", None), "constraints": constraints, "doc": annotations}
if len(types) > 0:
@@ -759,7 +759,7 @@
elif element["elmt_type"] is None:
element["elmt_type"] = "tag"
element["type"] = TAG
-
+
if attributes.has_key("type"):
tmp_attrs = attributes.copy()
tmp_attrs.pop("type")
@@ -772,18 +772,18 @@
def ReduceAll(factory, attributes, elements):
annotations, children = factory.ReduceElements(elements)
-
+
for child in children:
if children["maxOccurs"] == "unbounded" or children["maxOccurs"] > 1:
raise ValueError("\"all\" item can't have \"maxOccurs\" attribute greater than 1!")
-
+
return {"type": "all", "elements": children, "minOccurs": attributes["minOccurs"],
"maxOccurs": attributes["maxOccurs"], "order": False, "doc": annotations}
def ReduceChoice(factory, attributes, elements):
annotations, children = factory.ReduceElements(elements)
-
+
choices = []
for child in children:
if child["type"] in [ELEMENT, ANY, TAG]:
@@ -795,7 +795,7 @@
elif child["type"] == CHOICE:
choices.extend(child["choices"])
elif child["type"] == "group":
- elmtgroup = factory.FindSchemaElement(child["ref"], ELEMENTSGROUP)
+ elmtgroup = factory.FindSchemaElement(child["ref"], ELEMENTSGROUP)
if not elmtgroup.has_key("choices"):
raise ValueError("Only group composed of \"choice\" can be referenced in \"choice\" element!")
choices_tmp = []
@@ -810,18 +810,18 @@
else:
choices_tmp.append(choice)
choices.extend(choices_tmp)
-
+
for choice in choices:
attributes["minOccurs"] = min(attributes["minOccurs"], choice["minOccurs"])
choice["minOccurs"] = 1
-
+
return {"type": CHOICE, "choices": choices, "minOccurs": attributes["minOccurs"],
"maxOccurs": attributes["maxOccurs"], "doc": annotations}
def ReduceSequence(factory, attributes, elements):
annotations, children = factory.ReduceElements(elements)
-
+
sequence = []
for child in children:
if child["type"] in [ELEMENT, ANY, TAG, CHOICE]:
@@ -844,14 +844,14 @@
else:
elements_tmp.append(element)
sequence.extend(elements_tmp)
-
+
return {"type": "sequence", "elements": sequence, "minOccurs": attributes["minOccurs"],
"maxOccurs": attributes["maxOccurs"], "order": True, "doc": annotations}
-
-
+
+
def ReduceGroup(factory, attributes, elements):
annotations, children = factory.ReduceElements(elements)
-
+
if attributes.has_key("ref"):
return {"type": "group", "ref": attributes["ref"], "doc": annotations}
else:
@@ -868,39 +868,39 @@
def ReduceUnique(factory, attributes, elements):
annotations, children = factory.ReduceElements(elements)
-
+
unique = {"type": CONSTRAINT, "const_type": "unique", "selector": children[0], "fields": children[1:]}
unique.update(attributes)
return unique
-
+
def ReduceKey(factory, attributes, elements):
annotations, children = factory.ReduceElements(elements)
-
+
key = {"type": CONSTRAINT, "const_type": "key", "selector": children[0], "fields": children[1:]}
key.update(attributes)
return key
def ReduceKeyRef(factory, attributes, elements):
annotations, children = factory.ReduceElements(elements)
-
+
keyref = {"type": CONSTRAINT, "const_type": "keyref", "selector": children[0], "fields": children[1:]}
keyref.update(attributes)
return keyref
-
+
def ReduceSelector(factory, attributes, elements):
annotations, children = factory.ReduceElements(elements)
-
+
selector = {"type": CONSTRAINT, "const_type": "selector"}
selector.update(attributes)
return selector
def ReduceField(factory, attributes, elements):
annotations, children = factory.ReduceElements(elements)
-
+
field = {"type": CONSTRAINT, "const_type": "field"}
field.update(attributes)
return field
-
+
# Inclusion elements
@@ -910,7 +910,7 @@
def ReduceInclude(factory, attributes, elements):
annotations, children = factory.ReduceElements(elements)
-
+
if factory.FileName is None:
raise ValueError("Include in XSD string not yet supported")
filepath = attributes["schemaLocation"]
@@ -922,7 +922,7 @@
include_factory = XSDClassFactory(minidom.parse(xsdfile), filepath)
xsdfile.close()
include_factory.CreateClasses()
-
+
if factory.TargetNamespace == include_factory.TargetNamespace:
factory.Namespaces[factory.TargetNamespace].update(include_factory.Namespaces[include_factory.TargetNamespace])
else:
@@ -931,7 +931,7 @@
factory.ComputedClassesLookUp.update(include_factory.ComputedClassesLookUp)
factory.EquivalentClassesParent.update(include_factory.EquivalentClassesParent)
return None
-
+
def ReduceRedefine(factory, attributes, elements):
annotations, children = factory.ReduceElements(elements)
raise ValueError("\"redefine\" element isn't supported yet!")
@@ -944,15 +944,15 @@
factory.ElementFormDefault = attributes["elementFormDefault"]
factory.BlockDefault = attributes["blockDefault"]
factory.FinalDefault = attributes["finalDefault"]
-
+
targetNamespace = attributes.get("targetNamespace", None)
factory.TargetNamespace = factory.DefinedNamespaces.get(targetNamespace, None)
if factory.TargetNamespace is not None:
factory.etreeNamespaceFormat = "{%s}%%s" % targetNamespace
factory.Namespaces[factory.TargetNamespace] = {}
-
+
annotations, children = factory.ReduceElements(elements, True)
-
+
for child in children:
if child.has_key("name"):
infos = factory.GetQualifiedNameInfos(child["name"], factory.TargetNamespace, True)
@@ -987,7 +987,7 @@
else:
return True
return schema == reference
-
+
#-------------------------------------------------------------------------------
# Base class for XSD schema extraction
#-------------------------------------------------------------------------------
@@ -999,7 +999,7 @@
ClassFactory.__init__(self, document, filepath, debug)
self.Namespaces["xml"] = {
"lang": {
- "type": SYNTAXATTRIBUTE,
+ "type": SYNTAXATTRIBUTE,
"extract": {
"default": GenerateModelNameExtraction("lang", LANGUAGE_model)
}
@@ -1007,31 +1007,31 @@
}
self.Namespaces["xsi"] = {
"noNamespaceSchemaLocation": {
- "type": SYNTAXATTRIBUTE,
+ "type": SYNTAXATTRIBUTE,
"extract": {
"default": NotSupportedYet("noNamespaceSchemaLocation")
}
},
"nil": {
- "type": SYNTAXATTRIBUTE,
+ "type": SYNTAXATTRIBUTE,
"extract": {
"default": NotSupportedYet("nil")
}
},
"schemaLocation": {
- "type": SYNTAXATTRIBUTE,
+ "type": SYNTAXATTRIBUTE,
"extract": {
"default": NotSupportedYet("schemaLocation")
}
},
"type": {
- "type": SYNTAXATTRIBUTE,
+ "type": SYNTAXATTRIBUTE,
"extract": {
"default": NotSupportedYet("type")
}
}
}
-
+
def ParseSchema(self):
for child in self.Document.childNodes:
if child.nodeType == self.Document.ELEMENT_NODE:
@@ -1067,7 +1067,7 @@
if element_type is not None and element["type"] != element_type:
raise ValueError("\"%s\" isn't of the expected type!" % element_name)
return element
-
+
def CreateSchemaElement(self, element_name, element_type):
for type, attributes, elements in self.Schema[2]:
namespace, name = DecomposeQualifiedName(type)
@@ -1091,7 +1091,7 @@
return None
"""
-This function opens the xsd file and generate a xml parser with class lookup from
+This function opens the xsd file and generate a xml parser with class lookup from
the xml tree
"""
def GenerateParserFromXSD(filepath):
@@ -1129,9 +1129,9 @@
{any attributes with non-schema namespace . . .}>
Content: (annotation?, element*)
</all>""",
- "type": SYNTAXELEMENT,
- "extract": {
- "default": GenerateElement("all", ["id", "maxOccurs", "minOccurs"],
+ "type": SYNTAXELEMENT,
+ "extract": {
+ "default": GenerateElement("all", ["id", "maxOccurs", "minOccurs"],
re.compile("((?:annotation )?(?:element )*)"))
},
"reduce": ReduceAll
@@ -1143,9 +1143,9 @@
{any attributes with non-schema namespace . . .}>
Content: (appinfo | documentation)*
</annotation>""",
- "type": SYNTAXELEMENT,
- "extract": {
- "default": GenerateElement("annotation", ["id"],
+ "type": SYNTAXELEMENT,
+ "extract": {
+ "default": GenerateElement("annotation", ["id"],
re.compile("((?:app_info |documentation )*)"))
},
"reduce": ReduceAnnotation
@@ -1161,10 +1161,10 @@
{any attributes with non-schema namespace . . .}>
Content: (annotation?)
</any>""",
- "type": SYNTAXELEMENT,
- "extract": {
- "default": GenerateElement("any",
- ["id", "maxOccurs", "minOccurs", "namespace", "processContents"],
+ "type": SYNTAXELEMENT,
+ "extract": {
+ "default": GenerateElement("any",
+ ["id", "maxOccurs", "minOccurs", "namespace", "processContents"],
re.compile("((?:annotation )?(?:simpleType )*)"))
},
"reduce": ReduceAny
@@ -1178,7 +1178,7 @@
{any attributes with non-schema namespace . . .}>
Content: (annotation?)
</anyAttribute>""",
- "type": SYNTAXELEMENT,
+ "type": SYNTAXELEMENT,
"extract": {
"default": GenerateElement("anyAttribute",
["id", "namespace", "processContents"], ONLY_ANNOTATION)
@@ -1192,7 +1192,7 @@
{any attributes with non-schema namespace . . .}>
Content: ({any})*
</appinfo>""",
- "type": SYNTAXELEMENT,
+ "type": SYNTAXELEMENT,
"extract": {
"default": GenerateElement("appinfo", ["source"], re.compile("(.*)"), True)
},
@@ -1212,13 +1212,13 @@
{any attributes with non-schema namespace . . .}>
Content: (annotation?, simpleType?)
</attribute>""",
- "type": SYNTAXELEMENT,
- "extract": {
- "default": GenerateElement("attribute",
- ["default", "fixed", "form", "id", "name", "ref", "type", "use"],
+ "type": SYNTAXELEMENT,
+ "extract": {
+ "default": GenerateElement("attribute",
+ ["default", "fixed", "form", "id", "name", "ref", "type", "use"],
re.compile("((?:annotation )?(?:simpleType )?)")),
- "schema": GenerateElement("attribute",
- ["default", "fixed", "form", "id", "name", "type"],
+ "schema": GenerateElement("attribute",
+ ["default", "fixed", "form", "id", "name", "type"],
re.compile("((?:annotation )?(?:simpleType )?)"))
},
"reduce": ReduceAttribute
@@ -1232,12 +1232,12 @@
{any attributes with non-schema namespace . . .}>
Content: (annotation?, ((attribute | attributeGroup)*, anyAttribute?))
</attributeGroup>""",
- "type": SYNTAXELEMENT,
- "extract": {
- "default": GenerateElement("attributeGroup",
+ "type": SYNTAXELEMENT,
+ "extract": {
+ "default": GenerateElement("attributeGroup",
["id", "ref"], ONLY_ANNOTATION),
"schema": GenerateElement("attributeGroup",
- ["id", "name"],
+ ["id", "name"],
re.compile("((?:annotation )?(?:(?:attribute |attributeGroup )*(?:anyAttribute )?))"))
},
"reduce": ReduceAttributeGroup
@@ -1251,9 +1251,9 @@
{any attributes with non-schema namespace . . .}>
Content: (annotation?, (element | group | choice | sequence | any)*)
</choice>""",
- "type": SYNTAXELEMENT,
- "extract": {
- "default": GenerateElement("choice", ["id", "maxOccurs", "minOccurs"],
+ "type": SYNTAXELEMENT,
+ "extract": {
+ "default": GenerateElement("choice", ["id", "maxOccurs", "minOccurs"],
re.compile("((?:annotation )?(?:element |group |choice |sequence |any )*)"))
},
"reduce": ReduceChoice
@@ -1266,9 +1266,9 @@
{any attributes with non-schema namespace . . .}>
Content: (annotation?, (restriction | extension))
</complexContent>""",
- "type": SYNTAXELEMENT,
- "extract": {
- "default": GenerateElement("complexContent", ["id", "mixed"],
+ "type": SYNTAXELEMENT,
+ "extract": {
+ "default": GenerateElement("complexContent", ["id", "mixed"],
re.compile("((?:annotation )?(?:restriction |extension ))"))
},
"reduce": ReduceComplexContent
@@ -1285,10 +1285,10 @@
{any attributes with non-schema namespace . . .}>
Content: (annotation?, (simpleContent | complexContent | ((group | all | choice | sequence)?, ((attribute | attributeGroup)*, anyAttribute?))))
</complexType>""",
- "type": SYNTAXELEMENT,
- "extract": {
- "default": GenerateElement("complexType",
- ["abstract", "block", "final", "id", "mixed", "name"],
+ "type": SYNTAXELEMENT,
+ "extract": {
+ "default": GenerateElement("complexType",
+ ["abstract", "block", "final", "id", "mixed", "name"],
re.compile("((?:annotation )?(?:simpleContent |complexContent |(?:(?:group |all |choice |sequence )?(?:(?:attribute |attributeGroup )*(?:anyAttribute )?))))"))
},
"reduce": ReduceComplexType
@@ -1301,9 +1301,9 @@
{any attributes with non-schema namespace . . .}>
Content: ({any})*
</documentation>""",
- "type": SYNTAXELEMENT,
- "extract": {
- "default": GenerateElement("documentation",
+ "type": SYNTAXELEMENT,
+ "extract": {
+ "default": GenerateElement("documentation",
["source", "lang"], re.compile("(.*)"), True)
},
"reduce": ReduceDocumentation
@@ -1328,13 +1328,13 @@
{any attributes with non-schema namespace . . .}>
Content: (annotation?, ((simpleType | complexType)?, (unique | key | keyref)*))
</element>""",
- "type": SYNTAXELEMENT,
- "extract": {
- "default": GenerateElement("element",
- ["abstract", "block", "default", "final", "fixed", "form", "id", "maxOccurs", "minOccurs", "name", "nillable", "ref", "substitutionGroup", "type"],
+ "type": SYNTAXELEMENT,
+ "extract": {
+ "default": GenerateElement("element",
+ ["abstract", "block", "default", "final", "fixed", "form", "id", "maxOccurs", "minOccurs", "name", "nillable", "ref", "substitutionGroup", "type"],
re.compile("((?:annotation )?(?:simpleType |complexType )?(?:unique |key |keyref )*)")),
- "schema": GenerateElement("element",
- ["abstract", "block", "default", "final", "fixed", "form", "id", "name", "nillable", "substitutionGroup", "type"],
+ "schema": GenerateElement("element",
+ ["abstract", "block", "default", "final", "fixed", "form", "id", "name", "nillable", "substitutionGroup", "type"],
re.compile("((?:annotation )?(?:simpleType |complexType )?(?:unique |key |keyref )*)"))
},
"reduce": ReduceElement
@@ -1347,7 +1347,7 @@
{any attributes with non-schema namespace . . .}>
Content: (annotation?)
</enumeration>""",
- "type": SYNTAXELEMENT,
+ "type": SYNTAXELEMENT,
"extract": {
"default": GenerateElement("enumeration", ["id", "value"], ONLY_ANNOTATION)
},
@@ -1361,11 +1361,11 @@
{any attributes with non-schema namespace . . .}>
Content: (annotation?, ((group | all | choice | sequence)?, ((attribute | attributeGroup)*, anyAttribute?)))
</extension>""",
- "type": SYNTAXELEMENT,
- "extract": {
- "default": GenerateElement("extension", ["base", "id"],
+ "type": SYNTAXELEMENT,
+ "extract": {
+ "default": GenerateElement("extension", ["base", "id"],
re.compile("((?:annotation )?(?:(?:attribute |attributeGroup )*(?:anyAttribute )?))")),
- "complexContent": GenerateElement("extension", ["base", "id"],
+ "complexContent": GenerateElement("extension", ["base", "id"],
re.compile("((?:annotation )?(?:group |all |choice |sequence )?(?:(?:attribute |attributeGroup )*(?:anyAttribute )?))"))
},
"reduce": ReduceExtension
@@ -1378,7 +1378,7 @@
{any attributes with non-schema namespace . . .}>
Content: (annotation?)
</field>""",
- "type": SYNTAXELEMENT,
+ "type": SYNTAXELEMENT,
"extract": {
"default": GenerateElement("field", ["id", "xpath"], ONLY_ANNOTATION)
},
@@ -1393,9 +1393,9 @@
{any attributes with non-schema namespace . . .}>
Content: (annotation?)
</fractionDigits>""",
- "type": SYNTAXELEMENT,
- "extract": {
- "default": GenerateElement("fractionDigits",
+ "type": SYNTAXELEMENT,
+ "extract": {
+ "default": GenerateElement("fractionDigits",
["fixed", "id", "value"], ONLY_ANNOTATION)
},
"reduce": GenerateFacetReducing("fractionDigits", True)
@@ -1411,13 +1411,13 @@
{any attributes with non-schema namespace . . .}>
Content: (annotation?, (all | choice | sequence)?)
</group>""",
- "type": SYNTAXELEMENT,
+ "type": SYNTAXELEMENT,
"extract": {
"default": GenerateElement("group",
- ["id", "maxOccurs", "minOccurs", "ref"],
+ ["id", "maxOccurs", "minOccurs", "ref"],
re.compile("((?:annotation )?(?:all |choice |sequence )?)")),
"schema": GenerateElement("group",
- ["id", "name"],
+ ["id", "name"],
re.compile("((?:annotation )?(?:all |choice |sequence )?)"))
},
"reduce": ReduceGroup
@@ -1431,7 +1431,7 @@
{any attributes with non-schema namespace . . .}>
Content: (annotation?)
</import>""",
- "type": SYNTAXELEMENT,
+ "type": SYNTAXELEMENT,
"extract": {
"default": GenerateElement("import",
["id", "namespace", "schemaLocation"], ONLY_ANNOTATION)
@@ -1446,7 +1446,7 @@
{any attributes with non-schema namespace . . .}>
Content: (annotation?)
</include>""",
- "type": SYNTAXELEMENT,
+ "type": SYNTAXELEMENT,
"extract": {
"default": GenerateElement("include",
["id", "schemaLocation"], ONLY_ANNOTATION)
@@ -1461,9 +1461,9 @@
{any attributes with non-schema namespace . . .}>
Content: (annotation?, (selector, field+))
</key>""",
- "type": SYNTAXELEMENT,
- "extract": {
- "default": GenerateElement("key", ["id", "name"],
+ "type": SYNTAXELEMENT,
+ "extract": {
+ "default": GenerateElement("key", ["id", "name"],
re.compile("((?:annotation )?(?:selector (?:field )+))"))
},
"reduce": ReduceKey
@@ -1477,9 +1477,9 @@
{any attributes with non-schema namespace . . .}>
Content: (annotation?, (selector, field+))
</keyref>""",
- "type": SYNTAXELEMENT,
- "extract": {
- "default": GenerateElement("keyref", ["id", "name", "refer"],
+ "type": SYNTAXELEMENT,
+ "extract": {
+ "default": GenerateElement("keyref", ["id", "name", "refer"],
re.compile("((?:annotation )?(?:selector (?:field )+))"))
},
"reduce": ReduceKeyRef
@@ -1493,9 +1493,9 @@
{any attributes with non-schema namespace . . .}>
Content: (annotation?)
</length>""",
- "type": SYNTAXELEMENT,
- "extract": {
- "default": GenerateElement("length",
+ "type": SYNTAXELEMENT,
+ "extract": {
+ "default": GenerateElement("length",
["fixed", "id", "value"], ONLY_ANNOTATION)
},
"reduce": GenerateFacetReducing("length", True)
@@ -1508,9 +1508,9 @@
{any attributes with non-schema namespace . . .}>
Content: (annotation?, simpleType?)
</list>""",
- "type": SYNTAXELEMENT,
- "extract": {
- "default": GenerateElement("list", ["id", "itemType"],
+ "type": SYNTAXELEMENT,
+ "extract": {
+ "default": GenerateElement("list", ["id", "itemType"],
re.compile("((?:annotation )?(?:simpleType )?)$"))
},
"reduce": ReduceList
@@ -1524,7 +1524,7 @@
{any attributes with non-schema namespace . . .}>
Content: (annotation?)
</maxInclusive>""",
- "type": SYNTAXELEMENT,
+ "type": SYNTAXELEMENT,
"extract": {
"default": GenerateElement("maxExclusive",
["fixed", "id", "value"], ONLY_ANNOTATION)
@@ -1540,9 +1540,9 @@
{any attributes with non-schema namespace . . .}>
Content: (annotation?)
</maxExclusive>""",
- "type": SYNTAXELEMENT,
- "extract": {
- "default": GenerateElement("maxInclusive",
+ "type": SYNTAXELEMENT,
+ "extract": {
+ "default": GenerateElement("maxInclusive",
["fixed", "id", "value"], ONLY_ANNOTATION)
},
"reduce": GenerateFacetReducing("maxInclusive", True)
@@ -1556,9 +1556,9 @@
{any attributes with non-schema namespace . . .}>
Content: (annotation?)
</maxLength>""",
- "type": SYNTAXELEMENT,
- "extract": {
- "default": GenerateElement("maxLength",
+ "type": SYNTAXELEMENT,
+ "extract": {
+ "default": GenerateElement("maxLength",
["fixed", "id", "value"], ONLY_ANNOTATION)
},
"reduce": GenerateFacetReducing("maxLength", True)
@@ -1572,9 +1572,9 @@
{any attributes with non-schema namespace . . .}>
Content: (annotation?)
</minExclusive>""",
- "type": SYNTAXELEMENT,
- "extract": {
- "default": GenerateElement("minExclusive",
+ "type": SYNTAXELEMENT,
+ "extract": {
+ "default": GenerateElement("minExclusive",
["fixed", "id", "value"], ONLY_ANNOTATION)
},
"reduce": GenerateFacetReducing("minExclusive", True)
@@ -1588,9 +1588,9 @@
{any attributes with non-schema namespace . . .}>
Content: (annotation?)
</minInclusive>""",
- "type": SYNTAXELEMENT,
- "extract": {
- "default": GenerateElement("minInclusive",
+ "type": SYNTAXELEMENT,
+ "extract": {
+ "default": GenerateElement("minInclusive",
["fixed", "id", "value"], ONLY_ANNOTATION)
},
"reduce": GenerateFacetReducing("minInclusive", True)
@@ -1604,7 +1604,7 @@
{any attributes with non-schema namespace . . .}>
Content: (annotation?)
</minLength>""",
- "type": SYNTAXELEMENT,
+ "type": SYNTAXELEMENT,
"extract": {
"default": GenerateElement("minLength",
["fixed", "id", "value"], ONLY_ANNOTATION)
@@ -1619,7 +1619,7 @@
{any attributes with non-schema namespace . . .}>
Content: (annotation?)
</pattern>""",
- "type": SYNTAXELEMENT,
+ "type": SYNTAXELEMENT,
"extract": {
"default": GenerateElement("pattern", ["id", "value"], ONLY_ANNOTATION)
},
@@ -1633,9 +1633,9 @@
{any attributes with non-schema namespace . . .}>
Content: (annotation | (simpleType | complexType | group | attributeGroup))*
</redefine>""",
- "type": SYNTAXELEMENT,
- "extract": {
- "default": GenerateElement("refine", ["id", "schemaLocation"],
+ "type": SYNTAXELEMENT,
+ "extract": {
+ "default": GenerateElement("refine", ["id", "schemaLocation"],
re.compile("((?:annotation |(?:simpleType |complexType |group |attributeGroup ))*)"))
},
"reduce": ReduceRedefine
@@ -1648,13 +1648,13 @@
{any attributes with non-schema namespace . . .}>
Content: (annotation?, (group | all | choice | sequence)?, ((attribute | attributeGroup)*, anyAttribute?))
</restriction>""",
- "type": SYNTAXELEMENT,
- "extract": {
- "default": GenerateElement("restriction", ["base", "id"],
+ "type": SYNTAXELEMENT,
+ "extract": {
+ "default": GenerateElement("restriction", ["base", "id"],
re.compile("((?:annotation )?(?:(?:simpleType )?(?:(?:minExclusive |minInclusive |maxExclusive |maxInclusive |totalDigits |fractionDigits |length |minLength |maxLength |enumeration |whiteSpace |pattern )*)))")),
- "simpleContent": GenerateElement("restriction", ["base", "id"],
+ "simpleContent": GenerateElement("restriction", ["base", "id"],
re.compile("((?:annotation )?(?:(?:simpleType )?(?:(?:minExclusive |minInclusive |maxExclusive |maxInclusive |totalDigits |fractionDigits |length |minLength |maxLength |enumeration |whiteSpace |pattern )*)?(?:(?:attribute |attributeGroup )*(?:anyAttribute )?)))")),
- "complexContent": GenerateElement("restriction", ["base", "id"],
+ "complexContent": GenerateElement("restriction", ["base", "id"],
re.compile("((?:annotation )?(?:(?:simpleType )?(?:group |all |choice |sequence )?(?:(?:attribute |attributeGroup )*(?:anyAttribute )?)))")),
},
"reduce": ReduceRestriction
@@ -1673,10 +1673,10 @@
{any attributes with non-schema namespace . . .}>
Content: ((include | import | redefine | annotation)*, (((simpleType | complexType | group | attributeGroup) | element | attribute | notation), annotation*)*)
</schema>""",
- "type": SYNTAXELEMENT,
+ "type": SYNTAXELEMENT,
"extract": {
"default": GenerateElement("schema",
- ["attributeFormDefault", "blockDefault", "elementFormDefault", "finalDefault", "id", "targetNamespace", "version", "lang"],
+ ["attributeFormDefault", "blockDefault", "elementFormDefault", "finalDefault", "id", "targetNamespace", "version", "lang"],
re.compile("((?:include |import |redefine |annotation )*(?:(?:(?:simpleType |complexType |group |attributeGroup )|element |attribute |annotation )(?:annotation )*)*)"))
}
},
@@ -1688,7 +1688,7 @@
{any attributes with non-schema namespace . . .}>
Content: (annotation?)
</selector>""",
- "type": SYNTAXELEMENT,
+ "type": SYNTAXELEMENT,
"extract": {
"default": GenerateElement("selector", ["id", "xpath"], ONLY_ANNOTATION)
},
@@ -1703,9 +1703,9 @@
{any attributes with non-schema namespace . . .}>
Content: (annotation?, (element | group | choice | sequence | any)*)
</sequence>""",
- "type": SYNTAXELEMENT,
- "extract": {
- "default": GenerateElement("sequence", ["id", "maxOccurs", "minOccurs"],
+ "type": SYNTAXELEMENT,
+ "extract": {
+ "default": GenerateElement("sequence", ["id", "maxOccurs", "minOccurs"],
re.compile("((?:annotation )?(?:element |group |choice |sequence |any )*)"))
},
"reduce": ReduceSequence
@@ -1717,9 +1717,9 @@
{any attributes with non-schema namespace . . .}>
Content: (annotation?, (restriction | extension))
</simpleContent>""",
- "type": SYNTAXELEMENT,
- "extract": {
- "default": GenerateElement("simpleContent", ["id"],
+ "type": SYNTAXELEMENT,
+ "extract": {
+ "default": GenerateElement("simpleContent", ["id"],
re.compile("((?:annotation )?(?:restriction |extension ))"))
},
"reduce": ReduceSimpleContent
@@ -1733,9 +1733,9 @@
{any attributes with non-schema namespace . . .}>
Content: (annotation?, (restriction | list | union))
</simpleType>""",
- "type": SYNTAXELEMENT,
- "extract": {
- "default": GenerateElement("simpleType", ["final", "id", "name"],
+ "type": SYNTAXELEMENT,
+ "extract": {
+ "default": GenerateElement("simpleType", ["final", "id", "name"],
re.compile("((?:annotation )?(?:restriction |list |union ))"))
},
"reduce": ReduceSimpleType
@@ -1749,9 +1749,9 @@
{any attributes with non-schema namespace . . .}>
Content: (annotation?)
</totalDigits>""",
- "type": SYNTAXELEMENT,
- "extract": {
- "default": GenerateElement("totalDigits",
+ "type": SYNTAXELEMENT,
+ "extract": {
+ "default": GenerateElement("totalDigits",
["fixed", "id", "value"], ONLY_ANNOTATION),
},
"reduce": GenerateFacetReducing("totalDigits", True)
@@ -1764,9 +1764,9 @@
{any attributes with non-schema namespace . . .}>
Content: (annotation?, simpleType*)
</union>""",
- "type": SYNTAXELEMENT,
- "extract": {
- "default": GenerateElement("union", ["id", "memberTypes"],
+ "type": SYNTAXELEMENT,
+ "extract": {
+ "default": GenerateElement("union", ["id", "memberTypes"],
re.compile("((?:annotation )?(?:simpleType )*)"))
},
"reduce": ReduceUnion
@@ -1779,14 +1779,14 @@
{any attributes with non-schema namespace . . .}>
Content: (annotation?, (selector, field+))
</unique>""",
- "type": SYNTAXELEMENT,
- "extract": {
- "default": GenerateElement("unique", ["id", "name"],
+ "type": SYNTAXELEMENT,
+ "extract": {
+ "default": GenerateElement("unique", ["id", "name"],
re.compile("((?:annotation )?(?:selector |(?:field )+))"))
},
"reduce": ReduceUnique
},
-
+
"whiteSpace": {"struct" : """
<whiteSpace
fixed = boolean : false
@@ -1795,9 +1795,9 @@
{any attributes with non-schema namespace . . .}>
Content: (annotation?)
</whiteSpace>""",
- "type": SYNTAXELEMENT,
- "extract": {
- "default": GenerateElement("whiteSpace",
+ "type": SYNTAXELEMENT,
+ "extract": {
+ "default": GenerateElement("whiteSpace",
["fixed", "id", "value"], ONLY_ANNOTATION)
},
"reduce": GenerateFacetReducing("whiteSpace", True)
@@ -1808,7 +1808,7 @@
#-------------------------------------------------------------------------------
"abstract": {
- "type": SYNTAXATTRIBUTE,
+ "type": SYNTAXATTRIBUTE,
"extract": {
"default": GetBoolean
},
@@ -1818,7 +1818,7 @@
},
"attributeFormDefault": {
- "type": SYNTAXATTRIBUTE,
+ "type": SYNTAXATTRIBUTE,
"extract": {
"default": GenerateEnumeratedExtraction("member attributeFormDefault", ["qualified", "unqualified"])
},
@@ -1826,23 +1826,23 @@
"default": "unqualified"
}
},
-
+
"base": {
- "type": SYNTAXATTRIBUTE,
+ "type": SYNTAXATTRIBUTE,
"extract": {
"default": GenerateModelNameExtraction("member base", QName_model)
}
},
-
+
"block": {
- "type": SYNTAXATTRIBUTE,
+ "type": SYNTAXATTRIBUTE,
"extract": {
"default": GenerateGetList("block", ["restriction", "extension", "substitution"])
}
},
-
+
"blockDefault": {
- "type": SYNTAXATTRIBUTE,
+ "type": SYNTAXATTRIBUTE,
"extract": {
"default": GenerateGetList("block", ["restriction", "extension", "substitution"])
},
@@ -1850,16 +1850,16 @@
"default": ""
}
},
-
+
"default": {
- "type": SYNTAXATTRIBUTE,
+ "type": SYNTAXATTRIBUTE,
"extract": {
"default": GetAttributeValue
}
},
"elementFormDefault": {
- "type": SYNTAXATTRIBUTE,
+ "type": SYNTAXATTRIBUTE,
"extract": {
"default": GenerateEnumeratedExtraction("member elementFormDefault", ["qualified", "unqualified"])
},
@@ -1867,9 +1867,9 @@
"default": "unqualified"
}
},
-
+
"final": {
- "type": SYNTAXATTRIBUTE,
+ "type": SYNTAXATTRIBUTE,
"extract": {
"default": GenerateGetList("final", ["restriction", "extension", "substitution"]),
"simpleType": GenerateGetList("final", ["list", "union", "restriction"])
@@ -1877,7 +1877,7 @@
},
"finalDefault": {
- "type": SYNTAXATTRIBUTE,
+ "type": SYNTAXATTRIBUTE,
"extract": {
"default": GenerateGetList("finalDefault", ["restriction", "extension", "list", "union"])
},
@@ -1885,9 +1885,9 @@
"default": ""
}
},
-
+
"fixed": {
- "type": SYNTAXATTRIBUTE,
+ "type": SYNTAXATTRIBUTE,
"extract": {
"default": GetBoolean,
"attribute": GetAttributeValue,
@@ -1901,35 +1901,35 @@
},
"form": {
- "type": SYNTAXATTRIBUTE,
+ "type": SYNTAXATTRIBUTE,
"extract": {
"default": GenerateEnumeratedExtraction("member form", ["qualified", "unqualified"])
}
},
"id": {
- "type": SYNTAXATTRIBUTE,
+ "type": SYNTAXATTRIBUTE,
"extract": {
"default": GenerateModelNameExtraction("member id", NCName_model)
}
},
-
+
"itemType": {
- "type": SYNTAXATTRIBUTE,
+ "type": SYNTAXATTRIBUTE,
"extract": {
"default": GenerateModelNameExtraction("member itemType", QName_model)
}
},
"memberTypes": {
- "type": SYNTAXATTRIBUTE,
+ "type": SYNTAXATTRIBUTE,
"extract": {
"default": GenerateModelNameListExtraction("member memberTypes", QNames_model)
},
},
-
+
"maxOccurs": {
- "type": SYNTAXATTRIBUTE,
+ "type": SYNTAXATTRIBUTE,
"extract": {
"default": GenerateLimitExtraction(),
"all": GenerateLimitExtraction(1, 1, False)
@@ -1940,7 +1940,7 @@
},
"minOccurs": {
- "type": SYNTAXATTRIBUTE,
+ "type": SYNTAXATTRIBUTE,
"extract": {
"default": GenerateLimitExtraction(unbounded = False),
"all": GenerateLimitExtraction(0, 1, False)
@@ -1951,7 +1951,7 @@
},
"mixed": {
- "type": SYNTAXATTRIBUTE,
+ "type": SYNTAXATTRIBUTE,
"extract": {
"default": GetBoolean
},
@@ -1960,16 +1960,16 @@
"complexType": False
}
},
-
+
"name": {
- "type": SYNTAXATTRIBUTE,
+ "type": SYNTAXATTRIBUTE,
"extract": {
"default": GenerateModelNameExtraction("member name", NCName_model)
}
},
-
+
"namespace": {
- "type": SYNTAXATTRIBUTE,
+ "type": SYNTAXATTRIBUTE,
"extract": {
"default": GenerateModelNameExtraction("member namespace", URI_model),
"any": GetNamespaces
@@ -1981,14 +1981,14 @@
},
"nillable": {
- "type": SYNTAXATTRIBUTE,
+ "type": SYNTAXATTRIBUTE,
"extract": {
"default": GetBoolean
},
},
-
+
"processContents": {
- "type": SYNTAXATTRIBUTE,
+ "type": SYNTAXATTRIBUTE,
"extract": {
"default": GenerateEnumeratedExtraction("member processContents", ["lax", "skip", "strict"])
},
@@ -1996,9 +1996,9 @@
"default": "strict"
}
},
-
+
"ref": {
- "type": SYNTAXATTRIBUTE,
+ "type": SYNTAXATTRIBUTE,
"extract": {
"default": GenerateModelNameExtraction("member ref", QName_model)
}
@@ -2010,44 +2010,44 @@
"default": GenerateModelNameExtraction("member refer", QName_model)
}
},
-
+
"schemaLocation": {
- "type": SYNTAXATTRIBUTE,
+ "type": SYNTAXATTRIBUTE,
"extract": {
"default": GenerateModelNameExtraction("member schemaLocation", URI_model)
}
},
-
+
"source": {
"type": SYNTAXATTRIBUTE,
"extract": {
"default": GenerateModelNameExtraction("member source", URI_model)
}
},
-
+
"substitutionGroup": {
- "type": SYNTAXATTRIBUTE,
+ "type": SYNTAXATTRIBUTE,
"extract": {
"default": GenerateModelNameExtraction("member substitutionGroup", QName_model)
}
},
"targetNamespace": {
- "type": SYNTAXATTRIBUTE,
+ "type": SYNTAXATTRIBUTE,
"extract": {
"default": GenerateModelNameExtraction("member targetNamespace", URI_model)
}
},
-
+
"type": {
- "type": SYNTAXATTRIBUTE,
+ "type": SYNTAXATTRIBUTE,
"extract": {
"default": GenerateModelNameExtraction("member type", QName_model)
}
},
"use": {
- "type": SYNTAXATTRIBUTE,
+ "type": SYNTAXATTRIBUTE,
"extract": {
"default": GenerateEnumeratedExtraction("member usage", ["required", "optional", "prohibited"])
},
@@ -2057,7 +2057,7 @@
},
"value": {
- "type": SYNTAXATTRIBUTE,
+ "type": SYNTAXATTRIBUTE,
"extract": {
"default": GetAttributeValue,
"fractionDigits": GenerateIntegerExtraction(minInclusive=0),
@@ -2077,13 +2077,13 @@
},
"xpath": {
- "type": SYNTAXATTRIBUTE,
+ "type": SYNTAXATTRIBUTE,
"extract": {
# "default": NotSupportedYet("xpath")
"default": GetAttributeValue
}
},
-
+
#-------------------------------------------------------------------------------
# Simple types definition
#-------------------------------------------------------------------------------
@@ -2110,27 +2110,27 @@
"token": {
"type": SIMPLETYPE,
- "basename": "token",
+ "basename": "token",
"extract": GetToken,
"facets": STRING_FACETS,
"generate": GenerateSimpleTypeXMLText(lambda x : x),
"initial": lambda: "",
"check": lambda x: isinstance(x, (StringType, UnicodeType))
},
-
+
"base64Binary": {
- "type": SIMPLETYPE,
- "basename": "base64Binary",
+ "type": SIMPLETYPE,
+ "basename": "base64Binary",
"extract": NotSupportedYet("base64Binary"),
"facets": STRING_FACETS,
"generate": GenerateSimpleTypeXMLText(str),
"initial": lambda: 0,
"check": lambda x: isinstance(x, (IntType, LongType))
},
-
+
"hexBinary": {
"type": SIMPLETYPE,
- "basename": "hexBinary",
+ "basename": "hexBinary",
"extract": GetHexInteger,
"facets": STRING_FACETS,
"generate": GenerateSimpleTypeXMLText(lambda x: ("%."+str(int(round(len("%X"%x)/2.)*2))+"X")%x),
@@ -2140,24 +2140,24 @@
"integer": {
"type": SIMPLETYPE,
- "basename": "integer",
+ "basename": "integer",
"extract": GenerateIntegerExtraction(),
"facets": DECIMAL_FACETS,
"generate": GenerateSimpleTypeXMLText(str),
"initial": lambda: 0,
"check": lambda x: isinstance(x, IntType)
},
-
+
"positiveInteger": {
"type": SIMPLETYPE,
- "basename": "positiveInteger",
+ "basename": "positiveInteger",
"extract": GenerateIntegerExtraction(minExclusive=0),
"facets": DECIMAL_FACETS,
"generate": GenerateSimpleTypeXMLText(str),
"initial": lambda: 1,
"check": lambda x: isinstance(x, IntType)
},
-
+
"negativeInteger": {
"type": SIMPLETYPE,
"basename": "negativeInteger",
@@ -2167,27 +2167,27 @@
"initial": lambda: -1,
"check": lambda x: isinstance(x, IntType)
},
-
+
"nonNegativeInteger": {
- "type": SIMPLETYPE,
- "basename": "nonNegativeInteger",
+ "type": SIMPLETYPE,
+ "basename": "nonNegativeInteger",
"extract": GenerateIntegerExtraction(minInclusive=0),
"facets": DECIMAL_FACETS,
"generate": GenerateSimpleTypeXMLText(str),
"initial": lambda: 0,
"check": lambda x: isinstance(x, IntType)
},
-
+
"nonPositiveInteger": {
"type": SIMPLETYPE,
- "basename": "nonPositiveInteger",
+ "basename": "nonPositiveInteger",
"extract": GenerateIntegerExtraction(maxInclusive=0),
"facets": DECIMAL_FACETS,
"generate": GenerateSimpleTypeXMLText(str),
"initial": lambda: 0,
"check": lambda x: isinstance(x, IntType)
},
-
+
"long": {
"type": SIMPLETYPE,
"basename": "long",
@@ -2197,7 +2197,7 @@
"initial": lambda: 0,
"check": lambda x: isinstance(x, IntType)
},
-
+
"unsignedLong": {
"type": SIMPLETYPE,
"basename": "unsignedLong",
@@ -2240,7 +2240,7 @@
"unsignedShort": {
"type": SIMPLETYPE,
- "basename": "unsignedShort",
+ "basename": "unsignedShort",
"extract": GenerateIntegerExtraction(minInclusive=0,maxExclusive=2**16),
"facets": DECIMAL_FACETS,
"generate": GenerateSimpleTypeXMLText(str),
@@ -2306,7 +2306,7 @@
"generate": GenerateSimpleTypeXMLText(lambda x:{True : "true", False : "false"}[x]),
"initial": lambda: False,
"check": lambda x: isinstance(x, BooleanType)
- },
+ },
"duration": {
"type": SIMPLETYPE,
@@ -2337,7 +2337,7 @@
"initial": lambda: datetime.date(1,1,1),
"check": lambda x: isinstance(x, datetime.date)
},
-
+
"time": {
"type": SIMPLETYPE,
"basename": "time",
@@ -2407,7 +2407,7 @@
"initial": lambda: "",
"check": lambda x: isinstance(x, (StringType, UnicodeType))
},
-
+
"QName": {
"type": SIMPLETYPE,
"basename": "QName",
@@ -2531,4 +2531,3 @@
# Complex Types
"anyType": {"type": COMPLEXTYPE, "extract": lambda x:None},
}
-