# HG changeset patch # User etisserant # Date 1188921509 -7200 # Node ID d3cb5020997bf2596edc22ec530bc5a9434b8937 # Parent 73257cea38bdff538ef46b60d9c036f5a49f0e68 Beremiz plugins definitions. diff -r 73257cea38bd -r d3cb5020997b Beremiz.py --- a/Beremiz.py Tue Sep 04 17:16:42 2007 +0200 +++ b/Beremiz.py Tue Sep 04 17:58:29 2007 +0200 @@ -26,22 +26,10 @@ import wx -from time import localtime -from datetime import datetime import types import os, re, platform, sys, time, traceback, getopt, commands -base_folder = os.path.split(sys.path[0])[0] -sys.path.append(os.path.join(base_folder, "plcopeneditor")) -sys.path.append(os.path.join(base_folder, "CanFestival-3", "objdictgen")) -sys.path.append(os.path.join(base_folder, "wxsvg", "svgui", "defeditor")) - -iec2cc_path = os.path.join(base_folder, "matiec", "iec2cc") -ieclib_path = os.path.join(base_folder, "matiec", "lib") - -from PLCOpenEditor import PLCOpenEditor, ProjectDialog -from TextViewer import TextViewer -from plcopen.structures import IEC_KEYWORDS#, AddPlugin + from plugger import PluginsRoot class LogPseudoFile: @@ -80,6 +68,41 @@ def isatty(self): return false + def LogCommand(self, Command, sz_limit = 100): + + import os, popen2, fcntl, select, signal + + child = popen2.Popen3(Command, 1) # capture stdout and stderr from command + child.tochild.close() # don't need to talk to child + outfile = child.fromchild + outfd = outfile.fileno() + errfile = child.childerr + errfd = errfile.fileno() + outdata = errdata = '' + outeof = erreof = 0 + outlen = errlen = 0 + while 1: + ready = select.select([outfd,errfd],[],[]) # wait for input + if outfd in ready[0]: + outchunk = outfile.readline() + if outchunk == '': outeof = 1 + else : outlen += 1 + outdata += outchunk + self.write(outchunk) + if errfd in ready[0]: + errchunk = errfile.readline() + if errchunk == '': erreof = 1 + else : errlen += 1 + errdata += errchunk + self.write_warning(errchunk) + if outeof and erreof : break + if errlen > sz_limit or outlen > sz_limit : + os.kill(child.pid, signal.SIGTERM) + self.write_error("Output size reached limit -- killed\n") + break + err = child.wait() + return (err, outdata, errdata) + [ID_BEREMIZ, ID_BEREMIZMAINSPLITTER, ID_BEREMIZSECONDSPLITTER, ID_BEREMIZLEFTPANEL, ID_BEREMIZPARAMSPANEL, ID_BEREMIZLOGCONSOLE, @@ -299,14 +322,12 @@ self.Log = LogPseudoFile(self.LogConsole) - self.PluginRoot = PluginsRoot() + self.PluginRoot = PluginsRoot(self) if projectOpen: self.PluginRoot.LoadProject(projectOpen) self.RefreshPluginTree() - self.PLCEditor = None - self.RefreshPluginParams() self.RefreshButtons() self.RefreshMainMenu() @@ -588,123 +609,6 @@ textctrl.SetValue(str(element_infos["value"])) first = False - def UpdateAttributesTreeParts(self, tree, new_tree): - tree_leafs = [(element_infos["name"], element_infos["type"]) for element_infos in tree["children"]] - new_tree_leafs = [(element_infos["name"], element_infos["type"]) for element_infos in new_tree["children"]] - if tree_leafs != new_tree_leafs: - tree["children"] = new_tree["children"] - for child in tree["children"]: - self.PrepareAttributesTree(child) - else: - for idx, new_element_infos in enumerate(new_tree["children"]): - tree["children"][idx]["value"] = new_element_infos["value"] - if len(new_element_infos["children"]) > 0: - self.UpdateAttributesTreeParts(tree["children"][idx], new_element_infos) - - def PrepareAttributesTree(self, tree): - if len(tree["children"]) > 0: - tree["open"] = False - for child in tree["children"]: - self.PrepareAttributesTree(child) - - def GenerateTable(self, data, tree, path, indent): - if path: - tree_path = "%s.%s"%(path, tree["name"]) - infos = {"Attribute" : " " * indent + tree["name"], "Value" : tree["value"], "Type" : tree["type"], "Open" : "", "Path" : tree_path} - data.append(infos) - indent += 1 - else: - tree_path = tree["name"] - if len(tree["children"]) > 0: - if tree["open"] or not path: - if path: - infos["Open"] = "v" - for child in tree["children"]: - self.GenerateTable(data, child, tree_path, indent) - elif path: - infos["Open"] = ">" - - def RefreshAttributesGrid(self): - plugin = self.GetSelectedPlugin() - if not plugin: - self.AttributesTree = [] - self.Table.Empty() - else: - new_params = plugin.GetParamsAttributes() - for idx, child in enumerate(new_params): - if len(self.AttributesTree) > idx: - if self.AttributesTree[idx]["name"] == child["name"]: - self.UpdateAttributesTreeParts(self.AttributesTree[idx], child) - else: - self.AttributesTree[idx] = child - self.PrepareAttributesTree(child) - else: - self.AttributesTree.append(child) - self.PrepareAttributesTree(child) - while len(self.AttributesTree) > len(new_params): - self.AttributesTree.pop(-1) - data = [] - for child in self.AttributesTree: - self.GenerateTable(data, child, None, 0) - self.Table.SetData(data) - self.Table.ResetView(self.AttributesGrid) - - def OpenClose(self, tree, path): - parts = path.split(".", 1) - for child in tree["children"]: - if child["name"] == parts[0]: - if len(parts) > 1: - return self.OpenClose(child, parts[1]) - elif len(child["children"]) > 0: - child["open"] = not child["open"] - return True - return False - - def OpenCloseAttribute(self): - if self.AttributesGrid.GetGridCursorCol() == 0: - row = self.AttributesGrid.GetGridCursorRow() - path = self.Table.GetValueByName(row, "Path") - parts = path.split(".", 1) - for child in self.AttributesTree: - if child["name"] == parts[0] and len(parts) > 1: - result = self.OpenClose(child, parts[1]) - if result: - self.RefreshAttributesGrid() - - def OnParamsEnableChanged(self, event): - plugin = self.GetSelectedPlugin() - if plugin and plugin != self.PluginRoot: - plugin.BaseParams.setEnabled(event.Checked()) - event.Skip() - - def OnParamsIECChannelChanged(self, event): - plugin = self.GetSelectedPlugin() - if plugin and plugin != self.PluginRoot: - plugin.BaseParams.setIEC_Channel(self.ParamsIECChannel.GetValue()) - event.Skip() - - def OnParamsTargetTypeChanged(self, event): - plugin = self.GetSelectedPlugin() - if plugin and plugin == self.PluginRoot: - self.PluginRoot.ChangeTargetType(self.ParamsTargetType.GetStringSelection()) - self.RefreshAttributesGrid() - event.Skip() - - def OnAttributesGridCellChange(self, event): - row = event.GetRow() - plugin = self.GetSelectedPlugin() - if plugin: - path = self.Table.GetValueByName(row, "Path") - value = self.Table.GetValueByName(row, "Value") - plugin.SetParamsAttribute(path, value) - print plugin.GetParamsAttributes(path) - self.RefreshAttributesGrid() - event.Skip() - - def OnAttributesGridCellLeftClick(self, event): - wx.CallAfter(self.OpenCloseAttribute) - event.Skip() - def OnNewProjectMenu(self, event): defaultpath = self.PluginRoot.GetProjectPath() if defaultpath == "": @@ -713,25 +617,20 @@ if dialog.ShowModal() == wx.ID_OK: projectpath = dialog.GetPath() dialog.Destroy() - if os.path.isdir(projectpath) and len(os.listdir(projectpath)) == 0: - dialog = ProjectDialog(self) - if dialog.ShowModal() == wx.ID_OK: - values = dialog.GetValues() - values["creationDateTime"] = datetime(*localtime()[:6]) - self.PluginRoot.NewProject(projectpath, values) - self.RefreshPluginTree() - self.RefreshButtons() - self.RefreshMainMenu() - dialog.Destroy() + res = self.PluginRoot.NewProject(projectpath) + if not res : + self.RefreshPluginTree() + self.RefreshButtons() + self.RefreshMainMenu() else: - message = wx.MessageDialog(self, "Folder choosen isn't empty. You can't use it for a new project!", "ERROR", wx.OK|wx.ICON_ERROR) + message = wx.MessageDialog(self, res, "ERROR", wx.OK|wx.ICON_ERROR) message.ShowModal() message.Destroy() event.Skip() def OnOpenProjectMenu(self, event): defaultpath = self.PluginRoot.GetProjectPath() - if defaultpath == "": + if not defaultpath: defaultpath = os.getcwd() dialog = wx.DirDialog(self , "Choose a project", defaultpath, wx.DD_NEW_DIR_BUTTON) if dialog.ShowModal() == wx.ID_OK: @@ -785,7 +684,7 @@ event.Skip() def OnBuildMenu(self, event): - self.BuildAutom() + #self.BuildAutom() event.Skip() def OnSimulateMenu(self, event): @@ -828,50 +727,6 @@ def DeletePlugin(self): pass - - def EditPLC(self): - if not self.PLCEditor: - self.PLCEditor = PLCOpenEditor(self, self.PluginRoot.PLCManager) - self.PLCEditor.RefreshProjectTree() - self.PLCEditor.RefreshFileMenu() - self.PLCEditor.RefreshEditMenu() - self.PLCEditor.RefreshToolBar() - self.PLCEditor.Show() - - def LogCommand(self, Command, sz_limit = 100): - - import os, popen2, fcntl, select, signal - - child = popen2.Popen3(Command, 1) # capture stdout and stderr from command - child.tochild.close() # don't need to talk to child - outfile = child.fromchild - outfd = outfile.fileno() - errfile = child.childerr - errfd = errfile.fileno() - outdata = errdata = '' - outeof = erreof = 0 - outlen = errlen = 0 - while 1: - ready = select.select([outfd,errfd],[],[]) # wait for input - if outfd in ready[0]: - outchunk = outfile.readline() - if outchunk == '': outeof = 1 - else : outlen += 1 - outdata += outchunk - self.Log.write(outchunk) - if errfd in ready[0]: - errchunk = errfile.readline() - if errchunk == '': erreof = 1 - else : errlen += 1 - errdata += errchunk - self.Log.write_warning(errchunk) - if outeof and erreof : break - if errlen > sz_limit or outlen > sz_limit : - os.kill(child.pid, signal.SIGTERM) - self.Log.write_error("Output size reached limit -- killed\n") - break - err = child.wait() - return (err, outdata, errdata) #------------------------------------------------------------------------------- # Add Bus Dialog diff -r 73257cea38bd -r d3cb5020997b plugger.py --- a/plugger.py Tue Sep 04 17:16:42 2007 +0200 +++ b/plugger.py Tue Sep 04 17:58:29 2007 +0200 @@ -2,15 +2,18 @@ Base definitions for beremiz plugins """ -import os +import os,sys import plugins import types import shutil from xml.dom import minidom + +#Quick hack to be able to find Beremiz IEC tools. Should be config params. +base_folder = os.path.split(sys.path[0])[0] +sys.path.append(os.path.join(base_folder, "plcopeneditor")) + from xmlclass import GenerateClassesFromXSDstring -from PLCControler import PLCControler - _BaseParamsClass = GenerateClassesFromXSDstring(""" @@ -66,6 +69,7 @@ return False def OnPlugSave(self): + #Default, do nothing and return success return True def GetParamsAttributes(self, path = None): @@ -98,17 +102,15 @@ os.mkdir(plugpath) # generate XML for base XML parameters controller of the plugin - basexmlfilepath = self.PluginBaseXmlFilePath() - if basexmlfilepath: - BaseXMLFile = open(basexmlfilepath,'w') + if self.MandatoryParams: + BaseXMLFile = open(self.PluginBaseXmlFilePath(),'w') BaseXMLFile.write("\n") BaseXMLFile.write(self.MandatoryParams[1].generateXMLText(self.MandatoryParams[0], 0)) BaseXMLFile.close() # generate XML for XML parameters controller of the plugin - xmlfilepath = self.PluginXmlFilePath() - if xmlfilepath: - XMLFile = open(xmlfilepath,'w') + if self.PlugParams: + XMLFile = open(self.PluginXmlFilePath(),'w') XMLFile.write("\n") XMLFile.write(self.PlugParams[1].generateXMLText(self.PlugParams[0], 0)) XMLFile.close() @@ -292,8 +294,14 @@ if os.path.isdir(_self.PlugPath(PlugName)) and os.path.isfile(_self.PluginXmlFilePath(PlugName)): #Load the plugin.xml file into parameters members _self.LoadXMLParams(PlugName) + # Basic check. Better to fail immediately. + if (_self.BaseParams.getName() != PlugName): + raise Exception, "Project tree layout do not match plugin.xml %s!=%s "%(PlugName, _self.BaseParams.getName()) + + # Now, self.PlugPath() should be OK + # Check that IEC_Channel is not already in use. - self.FindNewIEC_Channel(self.BaseParams.getIEC_Channel()) + _self.FindNewIEC_Channel(_self.BaseParams.getIEC_Channel()) # Call the plugin real __init__ if getattr(PlugClass, "__init__", None): PlugClass.__init__(_self) @@ -319,31 +327,21 @@ return newPluginOpj - def LoadXMLParams(self, PlugName = None, test = True): + def LoadXMLParams(self, PlugName = None): # Get the base xml tree - basexmlfilepath = self.PluginBaseXmlFilePath(PlugName) - if basexmlfilepath: - basexmlfile = open(basexmlfilepath, 'r') + if self.MandatoryParams: + basexmlfile = open(self.PluginBaseXmlFilePath(PlugName), 'r') basetree = minidom.parse(basexmlfile) self.MandatoryParams[1].loadXMLTree(basetree.childNodes[0]) basexmlfile.close() # Get the xml tree - xmlfilepath = self.PluginXmlFilePath(PlugName) - if xmlfilepath: - xmlfile = open(xmlfilepath, 'r') + if self.PlugParams: + xmlfile = open(self.PluginXmlFilePath(PlugName), 'r') tree = minidom.parse(xmlfile) self.PlugParams[1].loadXMLTree(tree.childNodes[0]) xmlfile.close() - if test: - # Basic check. Better to fail immediately. - if not PlugName: - PlugName = os.path.split(self.PlugPath())[1].split(NameTypeSeparator)[0] - if (self.BaseParams.getName() != PlugName): - raise Exception, "Project tree layout do not match plugin.xml %s!=%s "%(PlugName, self.BaseParams.getName()) - # Now, self.PlugPath() should be OK - def LoadChilds(self): # Iterate over all PlugName@PlugType in plugin directory, and try to open them for PlugDir in os.listdir(self.PlugPath()): @@ -359,7 +357,38 @@ return getattr(__import__("plugins." + name), name).RootClass return GetRootClass + +#################################################################################### +#################################################################################### +#################################################################################### +################################### ROOT ###################################### +#################################################################################### +#################################################################################### +#################################################################################### + +iec2cc_path = os.path.join(base_folder, "matiec", "iec2cc") +ieclib_path = os.path.join(base_folder, "matiec", "lib") + +# import for project creation timestamping +from time import localtime +from datetime import datetime +# import necessary stuff from PLCOpenEditor +from PLCControler import PLCControler +from PLCOpenEditor import PLCOpenEditor, ProjectDialog +from TextViewer import TextViewer +from plcopen.structures import IEC_KEYWORDS + class PluginsRoot(PlugTemplate): + """ + This class define Root object of the plugin tree. + It is responsible of : + - Managing project directory + - Building project + - Handling PLCOpenEditor controler and view + - Loading user plugins and instanciante them as childs + - ... + + """ # For root object, available Childs Types are modules of the plugin packages. PlugChildsTypes = [(name, _GetClassFunction(name)) for name in plugins.__all__] @@ -418,26 +447,43 @@ """ - def __init__(self): - PlugTemplate.__init__(self) + def __init__(self, frame): + + self.MandatoryParams = None + self.AppFrame = frame + + """ + This method are not called here... but in NewProject and OpenProject + self._AddParamsMembers() + self.PluggedChilds = {} + """ + # self is the parent self.PlugParent = None # Keep track of the plugin type name self.PlugType = "Beremiz" - self.ProjectPath = "" + # After __init__ root plugin is not valid + self.ProjectPath = None self.PLCManager = None + self.PLCEditor = None def HasProjectOpened(self): """ Return if a project is actually opened """ - return self.ProjectPath != "" + return self.ProjectPath != None def GetProjectPath(self): return self.ProjectPath - def NewProject(self, ProjectPath, PLCParams): + def GetPlugInfos(self): + childs = [] + for child in self.IterChilds(): + childs.append(child.GetPlugInfos()) + return {"name" : os.path.split(self.ProjectPath)[1], "type" : None, "values" : childs} + + def NewProject(self, ProjectPath): """ Create a new project in an empty folder @param ProjectPath: path of the folder where project have to be created @@ -446,6 +492,16 @@ # Verify that choosen folder is empty if not os.path.isdir(ProjectPath) or len(os.listdir(ProjectPath)) > 0: return "Folder choosen isn't empty. You can't use it for a new project!" + + dialog = ProjectDialog(self.AppFrame) + if dialog.ShowModal() == wx.ID_OK: + values = dialog.GetValues() + values["creationDateTime"] = datetime(*localtime()[:6]) + dialog.Destroy() + else: + dialog.Destroy() + return "Project not created" + # Create Controler for PLCOpen program self.PLCManager = PLCControler() self.PLCManager.CreateNewProject(PLCParams.pop("projectName")) @@ -453,11 +509,8 @@ # Change XSD into class members self._AddParamsMembers() self.PluggedChilds = {} - # No IEC channel, name, etc... - self.MandatoryParams = [] # Keep track of the root plugin (i.e. project path) self.ProjectPath = ProjectPath - self.BaseParams.setName(os.path.split(ProjectPath)[1]) return None def LoadProject(self, ProjectPath): @@ -478,19 +531,16 @@ # Change XSD into class members self._AddParamsMembers() self.PluggedChilds = {} - # No IEC channel, name, etc... - self.MandatoryParams = None # Keep track of the root plugin (i.e. project path) self.ProjectPath = ProjectPath # If dir have already be made, and file exist if os.path.isdir(self.PlugPath()) and os.path.isfile(self.PluginXmlFilePath()): #Load the plugin.xml file into parameters members - result = self.LoadXMLParams(test = False) + result = self.LoadXMLParams() if result: return result #Load and init all the childs self.LoadChilds() - self.BaseParams.setName(os.path.split(ProjectPath)[1]) return None def SaveProject(self): @@ -501,9 +551,6 @@ def PlugPath(self, PlugName=None): return self.ProjectPath - def PluginBaseXmlFilePath(self, PlugName=None): - return None - def PluginXmlFilePath(self, PlugName=None): return os.path.join(self.PlugPath(PlugName), "beremiz.xml") @@ -517,61 +564,93 @@ @return: [(C_file_name, CFLAGS),...] , LDFLAGS_TO_APPEND """ return [(C_file_name, "") for C_file_name in self.PLCGeneratedCFiles ] , "" - - def _Generate_SoftPLC(self, buildpath, logger): - + + def _getBuildPath(self): + return os.path.join(self.ProjectPath, "build") + + def _getIECcodepath(self): + # define name for IEC code file + return os.path.join(self._getBuildPath(), "plc.st") + + def _Generate_SoftPLC(self, logger): + """ + Generate SoftPLC ST/IL/SFC code out of PLCOpenEditor controller, and compile it with IEC2CC + @param buildpath: path where files should be created + @param logger: the log pseudo file + """ + + logger.write("Generating SoftPLC IEC-61131 ST/IL/SFC code...\n") + buildpath = self._getBuildPath() + # define name for IEC code file + plc_file = self._getIECcodepath() + # ask PLCOpenEditor controller to write ST/IL/SFC code file + result = self.PLCManager.GenerateProgram(plc_file) + if not result: + # Failed ! + logger.write_error("Error : ST/IL/SFC code generator returned %d"%result) + return False + logger.write("Compiling ST Program in to C Program...\n") + # Now compile IEC code into many C files + # files are listed to stdout, and errors to stderr. + status, result, err_result = logger.LogCommand("%s %s -I %s %s"%(iec2cc_path, plc_file, ieclib_path, self.TargetDir)) + if status: + # Failed ! + logger.write_error("Error : IEC to C compiler returned %d"%status) + return False + # Now extract C files of stdout + C_files = result.splitlines() + # remove those that are not to be compiled because included by others + C_files.remove("POUS.c") + C_files.remove("LOCATED_VARIABLES.h") + # transform those base names to full names with path + C_files = map(lambda filename:os.path.join(self.TargetDir, filename), C_files) + logger.write("Extracting Located Variables...\n") + # IEC2CC compiler generate a list of located variables : LOCATED_VARIABLES.h + location_file = open(os.path.join(buildpath,"LOCATED_VARIABLES.h")) + locations = [] + # each line of LOCATED_VARIABLES.h declares a located variable + lines = [line.strip() for line in location_file.readlines()] + # This regular expression parses the lines genereated by IEC2CC LOCATED_MODEL = re.compile("__LOCATED_VAR\((?P[A-Z]*),(?P[_A-Za-z0-9]*),(?P[QMI])(?:,(?P[XBWD]))?,(?P[,0-9]*)\)") - - if self.PLCManager: - logger.write("Generating SoftPLC IEC-61131 ST/IL/SFC code...\n") - plc_file = os.path.join(self.TargetDir, "plc.st") - result = self.PLCManager.GenerateProgram(plc_file) - if not result: - logger.write_error("Error : ST/IL/SFC code generator returned %d"%result) - return False - logger.write("Compiling ST Program in to C Program...\n") - status, result, err_result = self.LogCommand("%s %s -I %s %s"%(iec2cc_path, plc_file, ieclib_path, self.TargetDir)) - if status: - new_dialog = wx.Frame(None) - ST_viewer = TextViewer(new_dialog, None, None) - #ST_viewer.Enable(False) - ST_viewer.SetKeywords(IEC_KEYWORDS) - ST_viewer.SetText(file(plc_file).read()) - new_dialog.Show() - raise Exception, "Error : IEC to C compiler returned %d"%status - C_files = result.splitlines() - C_files.remove("POUS.c") - C_files = map(lambda filename:os.path.join(self.TargetDir, filename), C_files) - logger.write("Extracting Located Variables...\n") - location_file = open(os.path.join(self.TargetDir,"LOCATED_VARIABLES.h")) - locations = [] - lines = [line.strip() for line in location_file.readlines()] - for line in lines: - result = LOCATED_MODEL.match(line) - if result: - resdict = result.groupdict() - # rewrite location as a tuple of integers - resdict['LOC'] = tuple(map(int,resdict['LOC'].split(','))) - if not resdict['SIZE']: - resdict['SIZE'] = 'X' - locations.append(resdict) + for line in lines: + # If line match RE, + result = LOCATED_MODEL.match(line) + if result: + # Get the resulting dict + resdict = result.groupdict() + # rewrite string for variadic location as a tuple of integers + resdict['LOC'] = tuple(map(int,resdict['LOC'].split(','))) + # set located size to 'X' if not given + if not resdict['SIZE']: + resdict['SIZE'] = 'X' + # finally store into located variable list + locations.append(resdict) + # Keep track of generated C files for later use by self.PlugGenerate_C self.PLCGeneratedCFiles = C_files + # Keep track of generated located variables for later use by self._Generate_C self.PLCGeneratedLocatedVars = locations return True def _build(self, logger): - buildpath = os.path.join(self.ProjectPath, "build") + """ + Method called by user to (re)build SoftPLC and plugin tree + """ + buildpath = self._getBuildPath() + + # Eventually create build dir if not os.path.exists(buildpath): os.mkdir(buildpath) logger.write("Start build in %s" % buildpath) - if not self._Generate_SoftPLC(buildpath, logger): - logger.write("SoftPLC code generation failed !") - return - + # Generate SoftPLC code + if not self._Generate_SoftPLC(logger): + logger.write_error("SoftPLC code generation failed !") + return False + logger.write("SoftPLC code generation successfull") + # Generate C code and compilation params from plugin hierarchy try: CFilesAndCFLAGS, LDFLAGS = self._Generate_C( buildpath, @@ -581,14 +660,39 @@ except Exception, msg: logger.write_error("Plugins code generation Failed !") logger.write_error(str(msg)) - return + return False logger.write_error("Plugins code generation successfull") - + + # Compile the resulting code into object files. for CFile, CFLAG in CFilesAndCFLAGS: print CFile,CFLAG - LDFLAGS - - PluginMethods = [("Build",_build), ("Clean",None), ("Run",None), ("EditPLC",None), ("Simulate",None)] - + # Link object files into something that can be executed on target + print LDFLAGS + + def _showIECcode(self, logger): + plc_file = self._getIECcodepath() + new_dialog = wx.Frame(None) + ST_viewer = TextViewer(new_dialog, None, None) + #ST_viewer.Enable(False) + ST_viewer.SetKeywords(IEC_KEYWORDS) + try: + text = file(plc_file).read() + except: + text = '(* No IEC code have been generated at that time ! *)' + ST_viewer.SetText(text) + + new_dialog.Show() + + def _EditPLC(self, logger): + if not self.PLCEditor: + self.PLCEditor = PLCOpenEditor(self, self.PLCManager) + self.PLCEditor.RefreshProjectTree() + self.PLCEditor.RefreshFileMenu() + self.PLCEditor.RefreshEditMenu() + self.PLCEditor.RefreshToolBar() + self.PLCEditor.Show() + + PluginMethods = [("Build",_build), ("Clean",None), ("Run",None), ("EditPLC",None), ("Show IEC code",_showIECcode)] + diff -r 73257cea38bd -r d3cb5020997b plugins/canfestival/canfestival.py --- a/plugins/canfestival/canfestival.py Tue Sep 04 17:16:42 2007 +0200 +++ b/plugins/canfestival/canfestival.py Tue Sep 04 17:58:29 2007 +0200 @@ -1,4 +1,7 @@ -import os +import os, sys +base_folder = os.path.split(sys.path[0])[0] +sys.path.append(os.path.join(base_folder, "CanFestival-3", "objdictgen")) + from nodelist import NodeList from nodemanager import NodeManager import config_utils, gen_cfile diff -r 73257cea38bd -r d3cb5020997b plugins/svgui/svgui.py --- a/plugins/svgui/svgui.py Tue Sep 04 17:16:42 2007 +0200 +++ b/plugins/svgui/svgui.py Tue Sep 04 17:58:29 2007 +0200 @@ -1,4 +1,7 @@ -import os +import os, sys +base_folder = os.path.split(sys.path[0])[0] +sys.path.append(os.path.join(base_folder, "wxsvg", "defeditor")) + from DEFControler import DEFControler from defeditor import EditorFrame