lpcmanager

Adding back new LPCManager.py.

2016-07-19, dporopat
1c870ee5ecc3
Parents 7cd611858634
Children 706ede36d534
Adding back new LPCManager.py.
  • +588 -517
    LPCManager.py
  • --- a/LPCManager.py Mon Jul 18 15:01:36 2016 +0200
    +++ b/LPCManager.py Tue Jul 19 10:16:57 2016 +0200
    @@ -15,29 +15,33 @@
    sys.path.append(_beremiz_folder)
    import wxversion
    +
    wxversion.select('2.8')
    import wx
    +
    def Bpath(*args):
    - return os.path.join(CWD,*args)
    + return os.path.join(CWD, *args)
    +
    if __name__ == '__main__':
    def usage():
    print "\nUsage of LPCManager.py :"
    - print "\n %s Projectpath Buildpath port [arch]\n"%sys.argv[0]
    -
    + print "\n %s Projectpath Buildpath port [arch]\n" % sys.argv[0]
    +
    +
    try:
    opts, args = getopt.getopt(sys.argv[1:], "h", ["help"])
    except getopt.GetoptError:
    # print help information and exit:
    usage()
    sys.exit(2)
    -
    +
    for o, a in opts:
    if o in ("-h", "--help"):
    usage()
    sys.exit()
    -
    +
    if len(args) < 3 or len(args) > 4:
    usage()
    sys.exit()
    @@ -53,8 +57,8 @@
    arch = args[3]
    else:
    arch = "MC9"
    - # XXX arch = "MC8"
    + PLC_module = {'MC9', 'GOT'}
    __builtin__.__dict__["BMZ_DBG"] = os.path.exists("LPC_DEBUG")
    app = wx.PySimpleApp(redirect=BMZ_DBG)
    @@ -62,87 +66,101 @@
    wx.InitAllImageHandlers()
    from util.misc import InstallLocalRessources
    +
    InstallLocalRessources(_beremiz_folder)
    _lpcmanager_path = os.path.split(__file__)[0]
    import features
    from POULibrary import POULibrary
    -class PLCLibrary(POULibrary):
    +
    +class PLCLibraryLPC(POULibrary):
    def GetLibraryPath(self):
    - return os.path.join(_lpcmanager_path, "pous.xml")
    + return os.path.join(_lpcmanager_path + '/Pous/', "pousLPC.xml")
    +
    +class PLCLibraryGOT(POULibrary):
    + def GetLibraryPath(self):
    + return os.path.join(_lpcmanager_path + '/Pous/', "pousGOT.xml")
    +
    -features.libraries=[
    - ('Native', 'NativeLib.NativeLibrary'),
    - ('LPC', lambda: PLCLibrary),
    - ('Python', 'py_ext.PythonLibrary')]
    +features.libraries=[('Native', 'NativeLib.NativeLibrary')]
    -features.catalog.pop([i for i,x in enumerate(features.catalog) if x[0].startswith('svg')][0])
    -
    +if arch == "MC9":
    + features.libraries += [('Python', 'py_ext.PythonLibrary')]
    +elif arch == "GOT":
    + features.libraries += [('GOT', lambda: PLCLibraryGOT),('Python', 'py_ext.PythonLibrary')]
    +else:
    + features.libraries += [('LPC', lambda: PLCLibraryLPC)]
    +
    +features.catalog.pop([i for i, x in enumerate(features.catalog) if x[0].startswith('svg')][0])
    +
    import connectors
    from LPCconnector import LPC_connector_factory
    -connectors.connectors["LPC"]=lambda:LPC_connector_factory
    +
    +connectors.connectors["LPC"] = lambda: LPC_connector_factory
    import targets
    -from LPCtarget import LPC_target
    +from LPCtarget import LPC_target
    +
    targets.targets["LPC"] = {"xsd": os.path.join(_lpcmanager_path, "LPCtarget", "XSD"),
    "class": lambda: LPC_target,
    - "code": {os.path.join(_lpcmanager_path,"LPCtarget","plc_LPC_main.c")}}
    + "code": {os.path.join(_lpcmanager_path, "LPCtarget", "plc_LPC_main.c")}}
    targets.toolchains["makefile"] = os.path.join(_lpcmanager_path, "LPCtarget", "XSD_toolchain_makefile")
    targets.targets["MC9"] = {"xsd": os.path.join(_lpcmanager_path, "MC9target", "XSD"),
    "class": targets.targets["Xenomai"]["class"],
    - "code": {"plc_MC9_main.c":targets.targets["Xenomai"]["code"]["plc_Xenomai_main.c"],
    - "plc_MC9_main_retain.c":os.path.join(_lpcmanager_path,
    - "MC9target", "plc_MC9_main_retain.c")}}
    + "code": {"plc_MC9_main.c": targets.targets["Xenomai"]["code"]["plc_Xenomai_main.c"],
    + "plc_MC9_main_retain.c": os.path.join(_lpcmanager_path,
    + "MC9target", "plc_MC9_main_retain.c")}}
    from Beremiz import *
    from ProjectController import ProjectController
    from ConfigTreeNode import ConfigTreeNode
    from editors.ProjectNodeEditor import ProjectNodeEditor
    -from PLCControler import PLCControler, LOCATION_MODULE, LOCATION_GROUP,\
    - LOCATION_VAR_INPUT, LOCATION_VAR_OUTPUT, LOCATION_VAR_MEMORY
    +from PLCControler import PLCControler, LOCATION_MODULE, LOCATION_GROUP, \
    + LOCATION_VAR_INPUT, LOCATION_VAR_OUTPUT, LOCATION_VAR_MEMORY
    from IDEFrame import IDEFrame
    from dialogs import ProjectDialog
    from controls import TextCtrlAutoComplete
    havecanfestival = False
    -#try:
    +# try:
    from canfestival import RootClass as CanOpenRootClass
    from canfestival.canfestival import _SlaveCTN, _NodeListCTN, NodeManager
    from canfestival.NetworkEditor import NetworkEditor
    from canfestival.SlaveEditor import SlaveEditor
    +
    havecanfestival = True
    -#except:
    +# except:
    # havecanfestival = False
    -
    +
    SCROLLBAR_UNIT = 10
    -WINDOW_COLOUR = wx.Colour(240,240,240)
    -TITLE_COLOUR = wx.Colour(200,200,220)
    -CHANGED_TITLE_COLOUR = wx.Colour(220,200,220)
    -CHANGED_WINDOW_COLOUR = wx.Colour(255,240,240)
    +WINDOW_COLOUR = wx.Colour(240, 240, 240)
    +TITLE_COLOUR = wx.Colour(200, 200, 220)
    +CHANGED_TITLE_COLOUR = wx.Colour(220, 200, 220)
    +CHANGED_WINDOW_COLOUR = wx.Colour(255, 240, 240)
    if wx.Platform == '__WXMSW__':
    - faces = { 'times': 'Times New Roman',
    - 'mono' : 'Courier New',
    - 'helv' : 'Arial',
    - 'other': 'Comic Sans MS',
    - 'size' : 16,
    + faces = {'times': 'Times New Roman',
    + 'mono': 'Courier New',
    + 'helv': 'Arial',
    + 'other': 'Comic Sans MS',
    + 'size': 16,
    }
    else:
    - faces = { 'times': 'Times',
    - 'mono' : 'Courier',
    - 'helv' : 'Helvetica',
    - 'other': 'new century schoolbook',
    - 'size' : 18,
    + faces = {'times': 'Times',
    + 'mono': 'Courier',
    + 'helv': 'Helvetica',
    + 'other': 'new century schoolbook',
    + 'size': 18,
    }
    from editors.ConfTreeNodeEditor import GenBitmapTextButton
    from editors.ConfTreeNodeEditor import ConfTreeNodeEditor
    -#ConfTreeNodeEditor.SHOW_BASE_PARAMS = False
    +# ConfTreeNodeEditor.SHOW_BASE_PARAMS = False
    -#-------------------------------------------------------------------------------
    +# -------------------------------------------------------------------------------
    # CANFESTIVAL CONFNODE HACK
    -#-------------------------------------------------------------------------------
    +# -------------------------------------------------------------------------------
    # from canfestival import canfestival
    # class LPC_canfestival_config:
    # def getCFLAGS(self, *args):
    @@ -154,27 +172,33 @@
    # canfestival.local_canfestival_config = LPC_canfestival_config()
    import LPCBus as LPCBus_mod
    -LPCBus_mod.LPCarch = arch
    +
    +if arch in PLC_module:
    + LPCBus_mod.LPCarch = "MC9"
    +else:
    + LPCBus_mod.LPCarch = arch
    +
    from LPCBus import *
    -#-------------------------------------------------------------------------------
    +# -------------------------------------------------------------------------------
    # LPC CanFestival ConfNode Class
    -#-------------------------------------------------------------------------------
    +# -------------------------------------------------------------------------------
    if havecanfestival:
    -
    DEFAULT_SETTINGS = {
    "CAN_Baudrate": "125K",
    "Slave_NodeId": 2,
    "Master_NodeId": 1,
    }
    -
    - class LPCSlaveEditor(SlaveEditor):
    - #SHOW_BASE_PARAMS = False
    - pass
    -
    - class LPCCanOpenSlave(_SlaveCTN):
    - XSD = """<?xml version="1.0" encoding="ISO-8859-1" ?>
    +
    +
    +class LPCSlaveEditor(SlaveEditor):
    + # SHOW_BASE_PARAMS = False
    + pass
    +
    +
    +class LPCCanOpenSlave(_SlaveCTN):
    + XSD = """<?xml version="1.0" encoding="ISO-8859-1" ?>
    <xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema">
    <xsd:element name="CanFestivalSlaveNode">
    <xsd:complexType>
    @@ -193,42 +217,44 @@
    </xsd:element>
    </xsd:schema>
    """ % DEFAULT_SETTINGS
    -
    - EditorType = LPCSlaveEditor
    -
    - def __init__(self):
    - # TODO change netname when name change
    - NodeManager.__init__(self)
    - odfilepath = self.GetSlaveODPath()
    - if(os.path.isfile(odfilepath)):
    - self.OpenFileInCurrent(odfilepath)
    - else:
    - self.CreateNewNode("SlaveNode", # Name - will be changed at build time
    - 0x00, # NodeID - will be changed at build time
    - "slave", # Type
    - "", # description
    - "None", # profile
    - "", # prfile filepath
    - "heartbeat", # NMT
    - []) # options
    - self.OnCTNSave()
    -
    - def GetCanDevice(self):
    - return str(self.BaseParams.getIEC_Channel())
    -
    - ConfNodeMethods = [
    - {"bitmap" : "NetworkEdit",
    - "name" : _("Edit slave"),
    - "tooltip" : _("Edit CanOpen slave with ObjdictEdit"),
    - "method" : "_OpenView"},
    - ] + _SlaveCTN.ConfNodeMethods
    -
    - class LPCNetworkEditor(NetworkEditor):
    - #SHOW_BASE_PARAMS = False
    - pass
    -
    - class LPCCanOpenMaster(_NodeListCTN):
    - XSD = """<?xml version="1.0" encoding="ISO-8859-1" ?>
    +
    + EditorType = LPCSlaveEditor
    +
    + def __init__(self):
    + # TODO change netname when name change
    + NodeManager.__init__(self)
    + odfilepath = self.GetSlaveODPath()
    + if (os.path.isfile(odfilepath)):
    + self.OpenFileInCurrent(odfilepath)
    + else:
    + self.CreateNewNode("SlaveNode", # Name - will be changed at build time
    + 0x00, # NodeID - will be changed at build time
    + "slave", # Type
    + "", # description
    + "None", # profile
    + "", # prfile filepath
    + "heartbeat", # NMT
    + []) # options
    + self.OnCTNSave()
    +
    + def GetCanDevice(self):
    + return str(self.BaseParams.getIEC_Channel())
    +
    + ConfNodeMethods = [
    + {"bitmap": "NetworkEdit",
    + "name": _("Edit slave"),
    + "tooltip": _("Edit CanOpen slave with ObjdictEdit"),
    + "method": "_OpenView"},
    + ] + _SlaveCTN.ConfNodeMethods
    +
    +
    +class LPCNetworkEditor(NetworkEditor):
    + # SHOW_BASE_PARAMS = False
    + pass
    +
    +
    +class LPCCanOpenMaster(_NodeListCTN):
    + XSD = """<?xml version="1.0" encoding="ISO-8859-1" ?>
    <xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema">
    <xsd:element name="CanFestivalNode">
    <xsd:complexType>
    @@ -239,43 +265,45 @@
    </xsd:element>
    </xsd:schema>
    """ % DEFAULT_SETTINGS
    -
    - EditorType = LPCNetworkEditor
    -
    - def GetCanDevice(self):
    - return str(self.BaseParams.getIEC_Channel())
    -
    - ConfNodeMethods = [
    - {"bitmap" : "NetworkEdit",
    - "name" : _("Edit network"),
    - "tooltip" : _("Edit CanOpen Network with NetworkEdit"),
    - "method" : "_OpenView"},
    - ] + _NodeListCTN.ConfNodeMethods
    -
    - class LPCCanOpen(CanOpenRootClass):
    - XSD = None
    - CTNChildrenTypes = [("CanOpenNode", LPCCanOpenMaster, "CanOpen Master"),
    - ("CanOpenSlave", LPCCanOpenSlave, "CanOpen Slave")]
    -
    - def GetCanDriver(self):
    - return None
    -
    - def LoadChildren(self):
    - ConfigTreeNode.LoadChildren(self)
    -
    - if self.GetChildByName("Master") is None:
    - master = self.CTNAddChild("Master", "CanOpenNode", 0)
    - #master.BaseParams.setEnabled(False)
    - master.CTNRequestSave()
    -
    - if self.GetChildByName("Slave") is None:
    - slave = self.CTNAddChild("Slave", "CanOpenSlave", 1)
    - #slave.BaseParams.setEnabled(False)
    - slave.CTNRequestSave()
    +
    + EditorType = LPCNetworkEditor
    +
    + def GetCanDevice(self):
    + return str(self.BaseParams.getIEC_Channel())
    +
    + ConfNodeMethods = [
    + {"bitmap": "NetworkEdit",
    + "name": _("Edit network"),
    + "tooltip": _("Edit CanOpen Network with NetworkEdit"),
    + "method": "_OpenView"},
    + ] + _NodeListCTN.ConfNodeMethods
    +
    +
    +class LPCCanOpen(CanOpenRootClass):
    + XSD = None
    + CTNChildrenTypes = [("CanOpenNode", LPCCanOpenMaster, "CanOpen Master"),
    + ("CanOpenSlave", LPCCanOpenSlave, "CanOpen Slave")]
    -#-------------------------------------------------------------------------------
    + def GetCanDriver(self):
    + return None
    +
    + def LoadChildren(self):
    + ConfigTreeNode.LoadChildren(self)
    +
    + if self.GetChildByName("Master") is None:
    + master = self.CTNAddChild("Master", "CanOpenNode", 0)
    + # master.BaseParams.setEnabled(False)
    + master.CTNRequestSave()
    +
    + if self.GetChildByName("Slave") is None:
    + slave = self.CTNAddChild("Slave", "CanOpenSlave", 1)
    + # slave.BaseParams.setEnabled(False)
    + slave.CTNRequestSave()
    +
    +
    +# -------------------------------------------------------------------------------
    # LPCProjectController Class
    -#-------------------------------------------------------------------------------
    +# -------------------------------------------------------------------------------
    def mycopytree(src, dst):
    """
    @@ -285,8 +313,8 @@
    """
    for i in os.listdir(src):
    if not i.startswith('.'):
    - srcpath = os.path.join(src,i)
    - dstpath = os.path.join(dst,i)
    + srcpath = os.path.join(src, i)
    + dstpath = os.path.join(dst, i)
    if os.path.isdir(srcpath):
    if os.path.exists(dstpath):
    shutil.rmtree(dstpath)
    @@ -295,9 +323,10 @@
    elif os.path.isfile(srcpath):
    shutil.copy2(srcpath, dstpath)
    +
    [SIMULATION_MODE, TRANSFER_MODE] = range(2)
    -if arch == "MC9" :
    +if arch in PLC_module:
    class LPCProjectNodeEditor(ProjectNodeEditor):
    pass
    else:
    @@ -305,77 +334,76 @@
    SHOW_PARAMS = False
    ENABLE_REQUIRED = False
    -
    _StatusMethods = [
    - {"bitmap" : "Debug",
    - "name" : _("Simulate"),
    - "tooltip" : _("Simulate PLC"),
    - "method" : "_Simulate"},
    - {"bitmap" : "Run",
    - "name" : _("Run"),
    - "shown" : False,
    - "tooltip" : _("Start PLC"),
    - "method" : "_Run"},
    - {"bitmap" : "Stop",
    - "name" : _("Stop"),
    - "shown" : False,
    - "tooltip" : _("Stop Running PLC"),
    - "method" : "_Stop"},
    - {"bitmap" : "Build",
    - "name" : _("Build"),
    - "tooltip" : _("Build project into build folder"),
    - "method" : "_Build"},
    - {"bitmap" : "Clean",
    - "name" : _("Clean"),
    - "enabled" : False,
    - "tooltip" : _("Clean project build folder"),
    - "method" : "_Clean"},
    - {"bitmap" : "Transfer",
    - "name" : _("Transfer"),
    - "shown" : False,
    - "tooltip" : _("Transfer PLC"),
    - "method" : "_Transfer"},
    + {"bitmap": "Debug",
    + "name": _("Simulate"),
    + "tooltip": _("Simulate PLC"),
    + "method": "_Simulate"},
    + {"bitmap": "Run",
    + "name": _("Run"),
    + "shown": False,
    + "tooltip": _("Start PLC"),
    + "method": "_Run"},
    + {"bitmap": "Stop",
    + "name": _("Stop"),
    + "shown": False,
    + "tooltip": _("Stop Running PLC"),
    + "method": "_Stop"},
    + {"bitmap": "Build",
    + "name": _("Build"),
    + "tooltip": _("Build project into build folder"),
    + "method": "_Build"},
    + {"bitmap": "Clean",
    + "name": _("Clean"),
    + "enabled": False,
    + "tooltip": _("Clean project build folder"),
    + "method": "_Clean"},
    + {"bitmap": "Transfer",
    + "name": _("Transfer"),
    + "shown": False,
    + "tooltip": _("Transfer PLC"),
    + "method": "_Transfer"},
    ]
    _MethodFromPLCState = {
    - "Started" : [("_Simulate", False),
    - ("_Run", False),
    - ("_Stop", True),
    - ("_Build", True),
    - ("_Transfer", True)],
    - "Stopped" : [("_Simulate", False),
    - ("_Run", True),
    - ("_Stop", False),
    - ("_Build", True),
    - ("_Transfer", True)],
    - "Connected" : [("_Simulate", "not simulating"),
    - ("_Run", True),
    - ("_Stop", True if arch=="MC9" else "simulating"),
    - ("_Build", True),
    - ("_Transfer", True)],
    - "Disconnected" :[("_Simulate", "not simulating"),
    - ("_Run", False),
    - ("_Stop", True if arch=="MC9" else "simulating"),
    - ("_Build", True),
    - ("_Transfer", False)],
    + "Started": [("_Simulate", False),
    + ("_Run", False),
    + ("_Stop", True),
    + ("_Build", True),
    + ("_Transfer", True)],
    + "Stopped": [("_Simulate", False),
    + ("_Run", True),
    + ("_Stop", False),
    + ("_Build", True),
    + ("_Transfer", True)],
    + "Connected": [("_Simulate", "not simulating"),
    + ("_Run", True),
    + ("_Stop", True if arch in PLC_module else "simulating"),
    + ("_Build", True),
    + ("_Transfer", True)],
    + "Disconnected": [("_Simulate", "not simulating"),
    + ("_Run", False),
    + ("_Stop", True if arch in PLC_module else "simulating"),
    + ("_Build", True),
    + ("_Transfer", False)],
    }
    -if arch == "MC9" :
    +if arch in PLC_module:
    _StatusMethods += [
    - {"bitmap" : "Connect",
    - "name" : _("Connect"),
    - "shown" : True,
    - "tooltip" : _("Connect to the target PLC"),
    - "method" : "_Connect"},
    - {"bitmap" : "Disconnect",
    - "name" : _("Disconnect"),
    - "shown" : False,
    - "tooltip" : _("Disconnect from PLC"),
    - "method" : "_Disconnect"},
    - {"bitmap" : "UpdateFw",
    - "name" : _("UpdateFw"),
    - "shown" : True,
    - "tooltip" : _("Update the PLC firmware"),
    - "method" : "_UpdateFw"},
    + {"bitmap": "Connect",
    + "name": _("Connect"),
    + "shown": True,
    + "tooltip": _("Connect to the target PLC"),
    + "method": "_Connect"},
    + {"bitmap": "Disconnect",
    + "name": _("Disconnect"),
    + "shown": False,
    + "tooltip": _("Disconnect from PLC"),
    + "method": "_Disconnect"},
    + {"bitmap": "UpdateFw",
    + "name": _("UpdateFw"),
    + "shown": True,
    + "tooltip": _("Update the PLC firmware"),
    + "method": "_UpdateFw"},
    ]
    _MethodFromPLCState["Disconnected"] += [("_Connect", True),
    ("_Disconnect", False)]
    @@ -383,37 +411,38 @@
    _MethodFromPLCState["Connected"] += [("_Connect", False),
    ("_Disconnect", True)]
    +
    class LPCProjectController(ProjectController):
    StatusMethods = _StatusMethods
    - #ConfNodeMethods = []
    -
    + # ConfNodeMethods = []
    +
    EditorType = LPCProjectNodeEditor
    -
    +
    def __init__(self, frame, logger, buildpath):
    self.OrigBuildPath = buildpath
    -
    +
    ProjectController.__init__(self, frame, logger)
    -
    +
    if havecanfestival:
    self.CTNChildrenTypes += [("LPCBus", LPCBus, "LPC bus"), ("CanOpen", LPCCanOpen, "CanOpen bus")]
    else:
    self.CTNChildrenTypes += [("LPCBus", LPCBus, "LPC bus")]
    self.CTNType = "LPC"
    -
    - self.OnlineMode = "NORMAL" if arch=="MC9" else "OFF"
    +
    + self.OnlineMode = "NORMAL" if arch in PLC_module else "OFF"
    self.LPCConnector = None
    self.ConnectorPath = None
    -
    +
    self.CurrentMode = None
    self.previous_mode = None
    -
    +
    self.SimulationBuildPath = None
    -
    +
    self.AbortTransferTimer = None
    # Firmware update running status
    self.firmawreUpadateIsRunning = False
    -
    +
    def GetProjectName(self):
    return self.Project.getname()
    @@ -425,10 +454,10 @@
    def GetTarget(self):
    target = ProjectController.GetTarget(self)
    - if self.CurrentMode != SIMULATION_MODE and arch != "MC9":
    + if self.CurrentMode != SIMULATION_MODE and arch not in PLC_module:
    target.getcontent().setBuildPath(self.BuildPath)
    return target
    -
    +
    def _getBuildPath(self):
    if self.CurrentMode == SIMULATION_MODE:
    if self.SimulationBuildPath is None:
    @@ -447,7 +476,7 @@
    ProjectController._Build(self)
    if save:
    wx.CallAfter(self.AppFrame.RefreshAll)
    -
    +
    def SetProjectName(self, name):
    return self.Project.setname(name)
    @@ -457,77 +486,77 @@
    if mode not in ["OFF", ""]:
    self.OnlineMode = mode
    self.ConnectorPath = path
    - uri = "LPC://%s/%s" % (self.OnlineMode,path)
    + uri = "LPC://%s/%s" % (self.OnlineMode, path)
    try:
    self.LPCConnector = connectors.ConnectorFactory(uri, self)
    except Exception, msg:
    - self.logger.write_error(_("Exception while connecting %s!\n")%uri)
    + self.logger.write_error(_("Exception while connecting %s!\n") % uri)
    self.logger.write_error(traceback.format_exc())
    # Did connection success ?
    if self.LPCConnector is None:
    # Oups.
    - self.logger.write_error(_("Connection failed to %s!\n")%uri)
    -
    + self.logger.write_error(_("Connection failed to %s!\n") % uri)
    +
    else:
    self.OnlineMode = "OFF"
    self.LPCConnector = None
    self.ConnectorPath = None
    -
    +
    self.ApplyOnlineMode()
    - SetOnlineMode = lambda *x:None if arch=="MC9" else _SetOnlineMode
    + SetOnlineMode = lambda *x: None if arch in PLC_module else _SetOnlineMode
    def ApplyOnlineMode(self):
    if self.CurrentMode != SIMULATION_MODE:
    self.KillDebugThread()
    -
    +
    self._SetConnector(self.LPCConnector)
    -
    +
    # Init with actual PLC status and print it
    self.UpdateMethodsFromPLCStatus()
    -
    +
    if self.LPCConnector is not None and self.OnlineMode == "APPLICATION":
    -
    +
    self.CompareLocalAndRemotePLC()
    -
    +
    if self.previous_plcstate is not None:
    status = _(self.previous_plcstate)
    else:
    status = ""
    - self.logger.write(_("PLC is %s\n")%status)
    -
    - #if self.StatusTimer and not self.StatusTimer.IsRunning():
    + self.logger.write(_("PLC is %s\n") % status)
    +
    + # if self.StatusTimer and not self.StatusTimer.IsRunning():
    # # Start the status Timer
    # self.StatusTimer.Start(milliseconds=2000, oneShot=False)
    -
    - if self.previous_plcstate=="Started":
    +
    + if self.previous_plcstate == "Started":
    if self.DebugAvailable() and self.GetIECProgramsAndVariables():
    self.logger.write(_("Debug connect matching running PLC\n"))
    self._connect_debug()
    else:
    self.logger.write_warning(_("Debug do not match PLC - stop/transfert/start to re-enable\n"))
    -
    +
    elif self.StatusTimer and self.StatusTimer.IsRunning():
    self.StatusTimer.Stop()
    -
    +
    if self.CurrentMode == TRANSFER_MODE:
    -
    +
    if self.OnlineMode == "BOOTLOADER":
    self.BeginTransfer()
    -
    +
    elif self.OnlineMode == "APPLICATION":
    self.CurrentMode = None
    self.AbortTransferTimer.Stop()
    self.AbortTransferTimer = None
    -
    +
    self.logger.write(_("PLC transferred successfully\n"))
    -
    +
    # Update a PLCOpenEditor Pou variable location
    def UpdateProjectVariableLocation(self, old_leading, new_leading):
    self.Project.updateElementAddress(old_leading, new_leading)
    self.BufferProject()
    -
    +
    # Update a PLCOpenEditor Pou variable name
    def UpdateProjectVariableName(self, old_name, new_name):
    self.Project.updateElementName(old_name, new_name)
    @@ -543,15 +572,15 @@
    def AddProjectDefaultConfiguration(self, config_name="config", res_name="resource1"):
    ProjectController.AddProjectDefaultConfiguration(self, config_name, res_name)
    -
    +
    self.SetEditedResourceInfos(
    - self.ComputeConfigurationResourceName(config_name, res_name),
    - [{"Name": "main_task",
    - "Triggering": "Cyclic",
    - "Interval": "T#50ms",
    - "Priority": 0}],
    - [])
    -
    + self.ComputeConfigurationResourceName(config_name, res_name),
    + [{"Name": "main_task",
    + "Triggering": "Cyclic",
    + "Interval": "T#50ms",
    + "Priority": 0}],
    + [])
    +
    def LoadProject(self, ProjectPath, BuildPath=None):
    """
    Load a project contained in a folder
    @@ -559,7 +588,7 @@
    """
    if os.path.basename(ProjectPath) == "":
    ProjectPath = os.path.dirname(ProjectPath)
    -
    +
    # Verify that project contains a PLCOpen program
    plc_file = os.path.join(ProjectPath, "plc.xml")
    if os.path.isfile(plc_file):
    @@ -576,60 +605,63 @@
    "scaling": {}})
    if len(self.GetProjectConfigNames()) == 0:
    self.AddProjectDefaultConfiguration()
    -
    +
    # Change XSD into class members
    self._AddParamsMembers()
    self.Children = {}
    -
    +
    # Keep track of the root confnode (i.e. project path)
    self.ProjectPath = ProjectPath
    -
    +
    self.BuildPath = self._getBuildPath()
    if self.OrigBuildPath is not None:
    mycopytree(self.OrigBuildPath, self.BuildPath)
    -
    +
    # If dir have already be made, and file exist
    if os.path.isdir(self.CTNPath()) and os.path.isfile(self.ConfNodeXmlFilePath()):
    - #Load the confnode.xml file into parameters members
    + # Load the confnode.xml file into parameters members
    result = self.LoadXMLParams()
    if result:
    return result
    - #Load and init all the children
    + # Load and init all the children
    self.LoadChildren()
    -
    +
    canopen_child = self.GetChildByName("CanOpen")
    if havecanfestival and canopen_child is None:
    canopen = self.CTNAddChild("CanOpen", "CanOpen", 0)
    canopen.LoadChildren()
    canopen.CTNRequestSave()
    -
    +
    elif not havecanfestival and canopen_child is not None:
    canopen_child.CTNRemove()
    -
    +
    if self.CTNTestModified():
    self.SaveProject()
    -
    +
    if wx.GetApp() is None:
    self.RefreshConfNodesBlockLists()
    else:
    wx.CallAfter(self.RefreshConfNodesBlockLists)
    + if arch in PLC_module:
    + self.SetParamsAttribute('BeremizRoot.TargetType', 'MC9')
    +
    return None
    -
    +
    def IsPLCStarted(self):
    return self.previous_plcstate == "Started" or self.previous_mode == SIMULATION_MODE
    -
    +
    def ShowMethod(self, name, val):
    simulating = self.CurrentMode == SIMULATION_MODE
    - if type(val) == str :
    + if type(val) == str:
    if val.endswith("simulating"):
    if val.startswith("not"):
    - val = not simulating
    - else :
    - val = simulating
    + val = not simulating
    + else:
    + val = simulating
    ProjectController.ShowMethod(self, name, val)
    -
    +
    def UpdateMethodsFromPLCStatus(self):
    simulating = self.CurrentMode == SIMULATION_MODE
    if self.OnlineMode == "OFF":
    @@ -649,7 +681,7 @@
    else:
    status = "Disconnected"
    if self.previous_plcstate != status or self.previous_mode != self.CurrentMode:
    - for args in _MethodFromPLCState.get(status,[]):
    + for args in _MethodFromPLCState.get(status, []):
    self.ShowMethod(*args)
    self.previous_plcstate = status
    self.previous_mode = self.CurrentMode
    @@ -777,28 +809,28 @@
    try:
    self._SetConnector(connectors.ConnectorFactory(uri, self))
    except Exception, msg:
    - self.logger.write_error(_("Exception while connecting %s!\n")%uri)
    + self.logger.write_error(_("Exception while connecting %s!\n") % uri)
    self.logger.write_error(traceback.format_exc())
    # Did connection success ?
    if self._connector is None:
    # Oups.
    - self.logger.write_error(_("Connection failed to %s!\n")%uri)
    + self.logger.write_error(_("Connection failed to %s!\n") % uri)
    self.StopSimulation()
    return False
    -
    +
    self.CurrentMode = SIMULATION_MODE
    -
    +
    buildpath = self._getBuildPath()
    -
    +
    # Eventually create build dir
    if not os.path.exists(buildpath):
    os.makedirs(buildpath)
    -
    +
    # Generate SoftPLC IEC code
    IECGenRes = self._Generate_SoftPLC()
    -
    - # If IEC code gen fail, bail out.
    +
    + # If IEC code gen fail, bail out.
    if not IECGenRes:
    self.logger.write_error(_("IEC-61131-3 code generation failed !\n"))
    self.StopSimulation()
    @@ -807,7 +839,7 @@
    # Reset variable and program list that are parsed from
    # CSV file generated by IEC2C compiler.
    self.ResetIECProgramsAndVariables()
    -
    +
    gen_result = self.CTNGenerate_C(buildpath, self.PLCGeneratedLocatedVars)
    CTNCFilesAndCFLAGS, CTNLDFLAGS, DoCalls = gen_result[:3]
    # if some files have been generated put them in the list with their location
    @@ -819,43 +851,43 @@
    # confnode asks for some LDFLAGS
    if CTNLDFLAGS:
    # LDFLAGS can be either string
    - if type(CTNLDFLAGS)==type(str()):
    - self.LDFLAGS=[CTNLDFLAGS]
    - #or list of strings
    - elif type(CTNLDFLAGS)==type(list()):
    - self.LDFLAGS=CTNLDFLAGS[:]
    + if type(CTNLDFLAGS) == type(str()):
    + self.LDFLAGS = [CTNLDFLAGS]
    + # or list of strings
    + elif type(CTNLDFLAGS) == type(list()):
    + self.LDFLAGS = CTNLDFLAGS[:]
    else:
    - self.LDFLAGS=[]
    -
    + self.LDFLAGS = []
    +
    # Header file for extensions
    - open(os.path.join(buildpath,"beremiz.h"), "w").write(targets.GetHeader())
    -
    + open(os.path.join(buildpath, "beremiz.h"), "w").write(targets.GetHeader())
    +
    # Template based part of C code generation
    # files are stacked at the beginning, as files of confnode tree root
    for generator, filename, name in [
    - # debugger code
    - (self.Generate_plc_debugger, "plc_debugger.c", "Debugger"),
    - # init/cleanup/retrieve/publish, run and align code
    - (self.Generate_plc_main,"plc_main.c","Common runtime"),
    - # declare located variables for simulate in a black box
    - (self.Generate_plc_declare_locations,"plc_declare_locations.c","Declare Locations"),
    - # declare located variables for simulate in a black box
    - (self.Generate_lpc_retain_array_sim,"lpc_retain_array_sim.c","Retain Array for Simulation")]:
    + # debugger code
    + (self.Generate_plc_debugger, "plc_debugger.c", "Debugger"),
    + # init/cleanup/retrieve/publish, run and align code
    + (self.Generate_plc_main, "plc_main.c", "Common runtime"),
    + # declare located variables for simulate in a black box
    + (self.Generate_plc_declare_locations, "plc_declare_locations.c", "Declare Locations"),
    + # declare located variables for simulate in a black box
    + (self.Generate_lpc_retain_array_sim, "lpc_retain_array_sim.c", "Retain Array for Simulation")]:
    try:
    # Do generate
    code = generator()
    if code is None:
    - raise
    - code_path = os.path.join(buildpath,filename)
    + raise
    + code_path = os.path.join(buildpath, filename)
    open(code_path, "w").write(code)
    # Insert this file as first file to be compiled at root confnode
    - self.LocationCFilesAndCFLAGS[0][1].insert(0,(code_path, self.plcCFLAGS))
    + self.LocationCFilesAndCFLAGS[0][1].insert(0, (code_path, self.plcCFLAGS))
    except Exception, exc:
    - self.logger.write_error(name+_(" generation failed !\n"))
    + self.logger.write_error(name + _(" generation failed !\n"))
    self.logger.write_error(traceback.format_exc())
    self.StopSimulation()
    return False
    -
    +
    # Get simulation builder
    builder = self.GetBuilder()
    if builder is None:
    @@ -865,7 +897,7 @@
    # Build
    try:
    - if not builder.build() :
    + if not builder.build():
    self.logger.write_error(_("C Build failed.\n"))
    self.StopSimulation()
    return False
    @@ -876,7 +908,7 @@
    return False
    data = builder.GetBinaryCode()
    - if data is not None :
    + if data is not None:
    if self._connector.NewPLC(builder.GetBinaryCodeMD5(), data, []):
    self.UnsubscribeAllDebugIECVariable()
    self.ProgramTransferred()
    @@ -888,21 +920,21 @@
    self.logger.write_error(_("Transfer failed\n"))
    self.StopSimulation()
    return False
    -
    +
    self._Run()
    -
    +
    if not self.StatusTimer.IsRunning():
    # Start the status Timer
    self.StatusTimer.Start(milliseconds=500, oneShot=False)
    -
    +
    def StopSimulation(self):
    self.CurrentMode = None
    self._SetConnector(None, False)
    self.ApplyOnlineMode()
    -
    +
    def _Stop(self):
    ProjectController._Stop(self)
    -
    +
    if self.CurrentMode == SIMULATION_MODE:
    self.StopSimulation()
    @@ -917,22 +949,24 @@
    self.ProgramTransferred()
    def ResetBuildMD5(self):
    - builder=self.GetBuilder()
    + builder = self.GetBuilder()
    if builder is not None:
    - builder.ResetBinaryCodeMD5(*([] if arch=="MC9" else [self.OnlineMode]))
    -
    + builder.ResetBinaryCodeMD5(*([] if arch in PLC_module else [self.OnlineMode]))
    +
    def GetLastBuildMD5(self):
    - builder=self.GetBuilder()
    + builder = self.GetBuilder()
    if builder is not None:
    - return builder.GetBinaryCodeMD5(*([] if arch=="MC9" else [self.OnlineMode]))
    + return builder.GetBinaryCodeMD5(*([] if arch in PLC_module else [self.OnlineMode]))
    else:
    return None
    def _Clean(self):
    self._CloseView(self._IECCodeView)
    - if os.path.isdir(os.path.join(self._getBuildPath())) and os.path.isfile(os.path.join(self._getBuildPath(), "hmi.py")) and os.path.isfile(os.path.join(self._getBuildPath(), "runtime_2.py")):
    + if os.path.isdir(os.path.join(self._getBuildPath())) and os.path.isfile(
    + os.path.join(self._getBuildPath(), "hmi.py")) and os.path.isfile(
    + os.path.join(self._getBuildPath(), "runtime_2.py")):
    self.logger.write(_("Cleaning the build directory\n"))
    - #self.logger.write(_(str(os.path.join(self._getBuildPath(), "hmi.py"))))
    + # self.logger.write(_(str(os.path.join(self._getBuildPath(), "hmi.py"))))
    os.remove(os.path.join(self._getBuildPath(), "hmi.py"))
    os.remove(os.path.join(self._getBuildPath(), "runtime_2.py"))
    else:
    @@ -946,38 +980,38 @@
    def _Transfer(self):
    if self.OnlineMode == "NORMAL":
    ProjectController._Transfer(self)
    - return
    + return
    if self.CurrentMode is None and self.OnlineMode != "OFF":
    self.CurrentMode = TRANSFER_MODE
    -
    +
    if ProjectController._Build(self):
    -
    +
    ID_ABORTTRANSFERTIMER = wx.NewId()
    self.AbortTransferTimer = wx.Timer(self.AppFrame, ID_ABORTTRANSFERTIMER)
    - self.AppFrame.Bind(wx.EVT_TIMER, self.AbortTransfer, self.AbortTransferTimer)
    -
    + self.AppFrame.Bind(wx.EVT_TIMER, self.AbortTransfer, self.AbortTransferTimer)
    +
    if self.OnlineMode == "BOOTLOADER":
    self.BeginTransfer()
    -
    +
    else:
    self.logger.write(_("Resetting PLC\n"))
    - #self.StatusTimer.Stop()
    + # self.StatusTimer.Stop()
    self.LPCConnector.ResetPLC()
    self.AbortTransferTimer.Start(milliseconds=5000, oneShot=True)
    -
    +
    else:
    self.CurrentMode = None
    -
    +
    def BeginTransfer(self):
    self.logger.write(_("Start PLC transfer\n"))
    -
    +
    self.AbortTransferTimer.Stop()
    ProjectController._Transfer(self)
    self.AbortTransferTimer.Start(milliseconds=5000, oneShot=True)
    -
    +
    def AbortTransfer(self, event):
    self.logger.write_warning(_("Timeout waiting PLC to recover\n"))
    -
    +
    self.CurrentMode = None
    self.AbortTransferTimer.Stop()
    self.AbortTransferTimer = None
    @@ -1030,7 +1064,7 @@
    self.firmawreUpadateIsRunning = False
    return
    else:
    - self.logger.write(_("Firmware image file: %s\n")%imageFilePath)
    + self.logger.write(_("Firmware image file: %s\n") % imageFilePath)
    if updateType == 1:
    self.logger.write(_("Firmware update type: Linux kernel image\n"))
    @@ -1044,20 +1078,20 @@
    self.firmawreUpadateIsRunning = False
    return
    - if chunksSize < 1024 or chunksSize > 1024*1024:
    - self.logger.write_error(_("Bad chunks size : %d KiB!\n")%chunksSize)
    + if chunksSize < 1024 or chunksSize > 1024 * 1024:
    + self.logger.write_error(_("Bad chunks size : %d KiB!\n") % chunksSize)
    self.logger.write_error(_("Firmware update canceled!\n"))
    self.firmawreUpadateIsRunning = False
    return
    else:
    - self.logger.write(_("Chunks size : %d KiB\n")%chunksSize)
    + self.logger.write(_("Chunks size : %d KiB\n") % chunksSize)
    - self.logger.write(_("Reboot after update : %s\n")%("Yes" if reboot else "No"))
    + self.logger.write(_("Reboot after update : %s\n") % ("Yes" if reboot else "No"))
    # Get the target PLC URI
    # Check if an uri is already configured in the Beremiz project
    uri = self.BeremizRoot.getURI_location()
    if uri is not None and uri != "":
    - self.logger.write(_("PLC URI configured in the Beremiz project will be used: %s\n")%uri)
    + self.logger.write(_("PLC URI configured in the Beremiz project will be used: %s\n") % uri)
    else:
    # PLC URI is not configured in the Beremiz project
    # Launch Service Discovery dialog
    @@ -1079,7 +1113,7 @@
    try:
    self._SetConnector(connectors.ConnectorFactory(uri, self))
    except Exception:
    - self.logger.write_error(_("Exception while connecting %s!\n")%uri)
    + self.logger.write_error(_("Exception while connecting %s!\n") % uri)
    self.logger.write_error(traceback.format_exc())
    self.logger.write_error(_("Firmware update canceled!\n"))
    self.firmawreUpadateIsRunning = False
    @@ -1088,7 +1122,7 @@
    # Did connection success ?
    if self._connector is None:
    # Oups.
    - self.logger.write_error(_("Connection failed to %s!\n")%uri)
    + self.logger.write_error(_("Connection failed to %s!\n") % uri)
    self.logger.write_error(_("Firmware update canceled!\n"))
    self.firmawreUpadateIsRunning = False
    return
    @@ -1096,9 +1130,9 @@
    self.logger.write(_("Connected.\n"))
    # Last confirmation before firmware update
    - answer = wx.MessageBox(_('Are you sure to launch the firmware update for the selected PLC?'),
    - _('Firmware Update'), wx.YES_NO | wx.CENTRE |wx.NO_DEFAULT,
    - self.AppFrame)
    + answer = wx.MessageBox(_('Are you sure to launch the firmware update for the selected PLC?'),
    + _('Firmware Update'), wx.YES_NO | wx.CENTRE | wx.NO_DEFAULT,
    + self.AppFrame)
    if answer != wx.YES:
    self.logger.write_error(_("Firmware update canceled!\n"))
    self.firmawreUpadateIsRunning = False
    @@ -1121,91 +1155,92 @@
    self.firmawreUpadateIsRunning = False
    return True
    -#-------------------------------------------------------------------------------
    +
    +# -------------------------------------------------------------------------------
    # LPCBeremiz Class
    -#-------------------------------------------------------------------------------
    -lpcberemiz_cmd=None
    +# -------------------------------------------------------------------------------
    +lpcberemiz_cmd = None
    +
    class LPCBeremiz(Beremiz):
    -
    def _init_coll_FileMenu_Items(self, parent):
    AppendMenu(parent, help='', id=wx.ID_SAVE,
    - kind=wx.ITEM_NORMAL, text=_(u'Save\tCTRL+S'))
    + kind=wx.ITEM_NORMAL, text=_(u'Save\tCTRL+S'))
    AppendMenu(parent, help='', id=wx.ID_CLOSE,
    - kind=wx.ITEM_NORMAL, text=_(u'Close Tab\tCTRL+W'))
    + kind=wx.ITEM_NORMAL, text=_(u'Close Tab\tCTRL+W'))
    parent.AppendSeparator()
    AppendMenu(parent, help='', id=wx.ID_PAGE_SETUP,
    - kind=wx.ITEM_NORMAL, text=_(u'Page Setup'))
    + kind=wx.ITEM_NORMAL, text=_(u'Page Setup'))
    AppendMenu(parent, help='', id=wx.ID_PREVIEW,
    - kind=wx.ITEM_NORMAL, text=_(u'Preview'))
    + kind=wx.ITEM_NORMAL, text=_(u'Preview'))
    AppendMenu(parent, help='', id=wx.ID_PRINT,
    - kind=wx.ITEM_NORMAL, text=_(u'Print'))
    + kind=wx.ITEM_NORMAL, text=_(u'Print'))
    parent.AppendSeparator()
    AppendMenu(parent, help='', id=wx.ID_EXIT,
    - kind=wx.ITEM_NORMAL, text=_(u'Quit\tCTRL+Q'))
    -
    + kind=wx.ITEM_NORMAL, text=_(u'Quit\tCTRL+Q'))
    +
    self.Bind(wx.EVT_MENU, self.OnSaveProjectMenu, id=wx.ID_SAVE)
    self.Bind(wx.EVT_MENU, self.OnCloseTabMenu, id=wx.ID_CLOSE)
    self.Bind(wx.EVT_MENU, self.OnPageSetupMenu, id=wx.ID_PAGE_SETUP)
    self.Bind(wx.EVT_MENU, self.OnPreviewMenu, id=wx.ID_PREVIEW)
    self.Bind(wx.EVT_MENU, self.OnPrintMenu, id=wx.ID_PRINT)
    self.Bind(wx.EVT_MENU, self.OnQuitMenu, id=wx.ID_EXIT)
    -
    +
    self.AddToMenuToolBar([(wx.ID_SAVE, "save", _(u'Save'), None),
    (wx.ID_PRINT, "print", _(u'Print'), None)])
    -
    +
    def _init_ctrls(self, prnt):
    Beremiz._init_ctrls(self, prnt)
    -
    +
    self.PLCConfig = wx.ScrolledWindow(
    - name='PLCConfig', parent=self.LeftNoteBook, pos=wx.Point(0, 0),
    - size=wx.Size(-1, -1), style=wx.TAB_TRAVERSAL|wx.SUNKEN_BORDER|wx.HSCROLL|wx.VSCROLL)
    + name='PLCConfig', parent=self.LeftNoteBook, pos=wx.Point(0, 0),
    + size=wx.Size(-1, -1), style=wx.TAB_TRAVERSAL | wx.SUNKEN_BORDER | wx.HSCROLL | wx.VSCROLL)
    self.PLCConfig.SetBackgroundColour(wx.WHITE)
    self.PLCConfig.Bind(wx.EVT_LEFT_DOWN, self.OnPanelLeftDown)
    self.PLCConfig.Bind(wx.EVT_SIZE, self.OnMoveWindow)
    self.MainTabs["PLCConfig"] = (self.PLCConfig, _("Topology"))
    self.LeftNoteBook.InsertPage(0, self.PLCConfig, _("Topology"), True)
    -
    +
    self.PLCConfigMainSizer = wx.FlexGridSizer(cols=1, hgap=2, rows=2, vgap=2)
    self.PLCParamsSizer = wx.BoxSizer(wx.VERTICAL)
    self.ConfNodeTreeSizer = wx.FlexGridSizer(cols=1, hgap=0, rows=0, vgap=2)
    self.ConfNodeTreeSizer.AddGrowableCol(0)
    -
    - self.PLCConfigMainSizer.AddSizer(self.PLCParamsSizer, 0, border=10, flag=wx.GROW|wx.TOP|wx.LEFT|wx.RIGHT)
    - self.PLCConfigMainSizer.AddSizer(self.ConfNodeTreeSizer, 0, border=10, flag=wx.BOTTOM|wx.LEFT|wx.RIGHT)
    +
    + self.PLCConfigMainSizer.AddSizer(self.PLCParamsSizer, 0, border=10, flag=wx.GROW | wx.TOP | wx.LEFT | wx.RIGHT)
    + self.PLCConfigMainSizer.AddSizer(self.ConfNodeTreeSizer, 0, border=10, flag=wx.BOTTOM | wx.LEFT | wx.RIGHT)
    self.PLCConfigMainSizer.AddGrowableCol(0)
    self.PLCConfigMainSizer.AddGrowableRow(1)
    -
    +
    self.PLCConfig.SetSizer(self.PLCConfigMainSizer)
    -
    +
    self.AUIManager.Update()
    def __init__(self, parent, projectOpen=None, buildpath=None, ctr=None, debug=True):
    self.ConfNodeInfos = {}
    -
    +
    Beremiz.__init__(self, parent, projectOpen, buildpath, ctr, debug)
    -
    +
    def Show(self):
    wx.Frame.Show(self)
    -
    +
    def OnCloseFrame(self, event):
    global frame
    -
    +
    if self.CheckSaveBeforeClosing(_("Close Application")):
    -
    +
    frame.Hide()
    -
    +
    self.CTR.ResetAppFrame(lpcberemiz_cmd.Log)
    if self.CTR.OnlineMode == 0:
    self.CTR._SetConnector(None, False)
    -
    +
    self.CTR.KillDebugThread()
    self.KillLocalRuntime()
    -
    +
    self.SaveLastState()
    -
    +
    lpcberemiz_cmd.Log.write("Closed\n")
    -
    +
    event.Veto()
    def OnMoveWindow(self, event):
    @@ -1254,7 +1289,7 @@
    MenuToolBar.EnableTool(wx.ID_PRINT, False)
    self.FileMenu.Enable(wx.ID_SAVE, False)
    MenuToolBar.EnableTool(wx.ID_SAVE, False)
    -
    +
    def RefreshScrollBars(self):
    xstart, ystart = self.PLCConfig.GetViewStart()
    window_size = self.PLCConfig.GetClientSize()
    @@ -1264,70 +1299,76 @@
    posx = max(0, min(xstart, (maxx - window_size[0]) / SCROLLBAR_UNIT))
    posy = max(0, min(ystart, (maxy - window_size[1]) / SCROLLBAR_UNIT))
    self.PLCConfig.Scroll(posx, posy)
    - self.PLCConfig.SetScrollbars(SCROLLBAR_UNIT, SCROLLBAR_UNIT,
    - maxx / SCROLLBAR_UNIT, maxy / SCROLLBAR_UNIT, posx, posy)
    + self.PLCConfig.SetScrollbars(SCROLLBAR_UNIT, SCROLLBAR_UNIT,
    + maxx / SCROLLBAR_UNIT, maxy / SCROLLBAR_UNIT, posx, posy)
    def RefreshPLCParams(self):
    self.Freeze()
    self.ClearSizer(self.PLCParamsSizer)
    -
    - if self.CTR is not None:
    +
    + if self.CTR is not None:
    plcwindow = wx.Panel(self.PLCConfig, -1, size=wx.Size(-1, -1))
    if self.CTR.CTNTestModified():
    bkgdclr = CHANGED_TITLE_COLOUR
    else:
    bkgdclr = TITLE_COLOUR
    -
    +
    plcwindow.SetBackgroundColour(TITLE_COLOUR)
    plcwindow.Bind(wx.EVT_LEFT_DOWN, self.OnPanelLeftDown)
    self.PLCParamsSizer.AddWindow(plcwindow, 0, border=0, flag=wx.GROW)
    -
    +
    plcwindowsizer = wx.BoxSizer(wx.HORIZONTAL)
    plcwindow.SetSizer(plcwindowsizer)
    -
    +
    st = wx.StaticText(plcwindow, -1)
    - st.SetFont(wx.Font(faces["size"], wx.DEFAULT, wx.NORMAL, wx.BOLD, faceName = faces["helv"]))
    + st.SetFont(wx.Font(faces["size"], wx.DEFAULT, wx.NORMAL, wx.BOLD, faceName=faces["helv"]))
    st.SetLabel(self.CTR.GetProjectName())
    - plcwindowsizer.AddWindow(st, 0, border=5, flag=wx.ALL|wx.ALIGN_CENTER)
    -
    + plcwindowsizer.AddWindow(st, 0, border=5, flag=wx.ALL | wx.ALIGN_CENTER)
    +
    plcwindowmainsizer = wx.BoxSizer(wx.VERTICAL)
    plcwindowsizer.AddSizer(plcwindowmainsizer, 0, border=5, flag=wx.ALL)
    -
    +
    plcwindowbuttonsizer = wx.BoxSizer(wx.HORIZONTAL)
    plcwindowmainsizer.AddSizer(plcwindowbuttonsizer, 0, border=0, flag=wx.ALIGN_CENTER)
    -
    +
    msizer = self.GenerateMethodButtonSizer(self.CTR, plcwindow)
    plcwindowbuttonsizer.AddSizer(msizer, 0, border=0, flag=wx.GROW)
    -
    +
    self.PLCConfigMainSizer.Layout()
    self.RefreshScrollBars()
    self.Thaw()
    def GenerateMethodButtonSizer(self, confnode, parent):
    - normal_bt_font=wx.Font(faces["size"] / 3, wx.DEFAULT, wx.NORMAL, wx.NORMAL, faceName = faces["helv"])
    - mouseover_bt_font=wx.Font(faces["size"] / 3, wx.DEFAULT, wx.NORMAL, wx.NORMAL, underline=True, faceName = faces["helv"])
    + normal_bt_font = wx.Font(faces["size"] / 3, wx.DEFAULT, wx.NORMAL, wx.NORMAL, faceName=faces["helv"])
    + mouseover_bt_font = wx.Font(faces["size"] / 3, wx.DEFAULT, wx.NORMAL, wx.NORMAL, underline=True,
    + faceName=faces["helv"])
    msizer = wx.FlexGridSizer(cols=len(confnode.ConfNodeMethods))
    for confnode_method in confnode.ConfNodeMethods:
    - if "method" in confnode_method and confnode_method.get("shown",True):
    + if "method" in confnode_method and confnode_method.get("shown", True):
    id = wx.NewId()
    label = confnode_method["name"]
    button = GenBitmapTextButton(id=id, parent=parent,
    - bitmap=wx.Bitmap(Bpath("images", "%s.png"%confnode_method.get("bitmap", "Unknown"))), label=label,
    - name=label, pos=wx.DefaultPosition, style=wx.NO_BORDER)
    + bitmap=wx.Bitmap(
    + Bpath("images", "%s.png" % confnode_method.get("bitmap", "Unknown"))),
    + label=label,
    + name=label, pos=wx.DefaultPosition, style=wx.NO_BORDER)
    button.SetFont(normal_bt_font)
    button.SetToolTipString(confnode_method["tooltip"])
    button.Bind(wx.EVT_BUTTON, self.GetButtonCallBackFunction(confnode, confnode_method["method"]), id=id)
    +
    # a fancy underline on mouseover
    def setFontStyle(b, s):
    def fn(event):
    b.SetFont(s)
    b.Refresh()
    event.Skip()
    +
    return fn
    +
    button.Bind(wx.EVT_ENTER_WINDOW, setFontStyle(button, mouseover_bt_font))
    button.Bind(wx.EVT_LEAVE_WINDOW, setFontStyle(button, normal_bt_font))
    - #hack to force size to mini
    - if not confnode_method.get("enabled",True):
    + # hack to force size to mini
    + if not confnode_method.get("enabled", True):
    button.Disable()
    msizer.AddWindow(button, 0, border=0, flag=wx.ALIGN_CENTER)
    return msizer
    @@ -1336,18 +1377,23 @@
    enabled = confnode.CTNEnabled()
    if enabled is not None:
    enablebutton_id = wx.NewId()
    - enablebutton = wx.lib.buttons.GenBitmapToggleButton(id=enablebutton_id, bitmap=wx.Bitmap(Bpath( 'images', 'Disabled.png')),
    - name='EnableButton', parent=parent, size=wx.Size(16, 16), pos=wx.Point(0, 0), style=0)#wx.NO_BORDER)
    + enablebutton = wx.lib.buttons.GenBitmapToggleButton(id=enablebutton_id,
    + bitmap=wx.Bitmap(Bpath('images', 'Disabled.png')),
    + name='EnableButton', parent=parent,
    + size=wx.Size(16, 16), pos=wx.Point(0, 0),
    + style=0) # wx.NO_BORDER)
    enablebutton.SetToolTipString(_("Enable/Disable this confnode"))
    make_genbitmaptogglebutton_flat(enablebutton)
    - enablebutton.SetBitmapSelected(wx.Bitmap(Bpath( 'images', 'Enabled.png')))
    + enablebutton.SetBitmapSelected(wx.Bitmap(Bpath('images', 'Enabled.png')))
    enablebutton.SetToggle(enabled)
    +
    def toggleenablebutton(event):
    res = self.SetConfNodeParamsAttribute(confnode, "BaseParams.Enabled", enablebutton.GetToggle())
    enablebutton.SetToggle(res)
    event.Skip()
    +
    enablebutton.Bind(wx.EVT_BUTTON, toggleenablebutton, id=enablebutton_id)
    - sizer.AddWindow(enablebutton, 0, border=0, flag=wx.RIGHT|wx.ALIGN_CENTER_VERTICAL)
    + sizer.AddWindow(enablebutton, 0, border=0, flag=wx.RIGHT | wx.ALIGN_CENTER_VERTICAL)
    else:
    sizer.AddSpacer(wx.Size(16, 16))
    @@ -1366,52 +1412,54 @@
    def GenerateTreeBranch(self, confnode):
    nodewindow = wx.Panel(self.PLCConfig, -1, size=wx.Size(-1, -1))
    if confnode.CTNTestModified():
    - bkgdclr=CHANGED_WINDOW_COLOUR
    + bkgdclr = CHANGED_WINDOW_COLOUR
    else:
    - bkgdclr=WINDOW_COLOUR
    + bkgdclr = WINDOW_COLOUR
    nodewindow.SetBackgroundColour(bkgdclr)
    -
    +
    if confnode not in self.ConfNodeInfos:
    - self.ConfNodeInfos[confnode] = {"expanded" : False, "visible" : False}
    -
    + self.ConfNodeInfos[confnode] = {"expanded": False, "visible": False}
    +
    self.ConfNodeInfos[confnode]["children"] = confnode.IECSortedChildren()
    confnode_infos = confnode.GetVariableLocationTree()
    confnode_locations = []
    if len(self.ConfNodeInfos[confnode]["children"]) == 0:
    confnode_locations = confnode_infos["children"]
    if not self.ConfNodeInfos[confnode].has_key("locations_infos"):
    - self.ConfNodeInfos[confnode]["locations_infos"] = {"root": {"expanded" : False}}
    -
    + self.ConfNodeInfos[confnode]["locations_infos"] = {"root": {"expanded": False}}
    +
    self.ConfNodeInfos[confnode]["locations_infos"]["root"]["window"] = None
    self.ConfNodeInfos[confnode]["locations_infos"]["root"]["children"] = []
    -
    +
    self.ConfNodeTreeSizer.AddWindow(nodewindow, 0, border=0, flag=wx.GROW)
    -
    +
    nodewindowvsizer = wx.BoxSizer(wx.VERTICAL)
    nodewindow.SetSizer(nodewindowvsizer)
    -
    +
    nodewindowsizer = wx.BoxSizer(wx.HORIZONTAL)
    nodewindowvsizer.AddSizer(nodewindowsizer, 0, border=0, flag=0)
    -
    - #self.GenerateEnableButton(nodewindow, nodewindowsizer, confnode)
    -
    +
    + # self.GenerateEnableButton(nodewindow, nodewindowsizer, confnode)
    +
    st = wx.StaticText(nodewindow, -1)
    - st.SetFont(wx.Font(faces["size"], wx.DEFAULT, wx.NORMAL, wx.BOLD, faceName = faces["helv"]))
    + st.SetFont(wx.Font(faces["size"], wx.DEFAULT, wx.NORMAL, wx.BOLD, faceName=faces["helv"]))
    st.SetLabel(confnode.GetFullIEC_Channel())
    - nodewindowsizer.AddWindow(st, 0, border=5, flag=wx.LEFT|wx.RIGHT|wx.ALIGN_CENTER_VERTICAL)
    -
    + nodewindowsizer.AddWindow(st, 0, border=5, flag=wx.LEFT | wx.RIGHT | wx.ALIGN_CENTER_VERTICAL)
    +
    expandbutton_id = wx.NewId()
    - expandbutton = wx.lib.buttons.GenBitmapToggleButton(id=expandbutton_id, bitmap=wx.Bitmap(Bpath( 'images', 'plus.png')),
    - name='ExpandButton', parent=nodewindow, pos=wx.Point(0, 0),
    - size=wx.Size(13, 13), style=wx.NO_BORDER)
    + expandbutton = wx.lib.buttons.GenBitmapToggleButton(id=expandbutton_id,
    + bitmap=wx.Bitmap(Bpath('images', 'plus.png')),
    + name='ExpandButton', parent=nodewindow, pos=wx.Point(0, 0),
    + size=wx.Size(13, 13), style=wx.NO_BORDER)
    expandbutton.labelDelta = 0
    expandbutton.SetBezelWidth(0)
    expandbutton.SetUseFocusIndicator(False)
    - expandbutton.SetBitmapSelected(wx.Bitmap(Bpath( 'images', 'minus.png')))
    -
    + expandbutton.SetBitmapSelected(wx.Bitmap(Bpath('images', 'minus.png')))
    +
    if len(self.ConfNodeInfos[confnode]["children"]) > 0:
    expandbutton.SetToggle(self.ConfNodeInfos[confnode]["expanded"])
    +
    def togglebutton(event):
    if expandbutton.GetToggle():
    self.ExpandConfNode(confnode)
    @@ -1421,10 +1469,12 @@
    self.PLCConfigMainSizer.Layout()
    self.RefreshScrollBars()
    event.Skip()
    +
    expandbutton.Bind(wx.EVT_BUTTON, togglebutton, id=expandbutton_id)
    elif len(confnode_locations) > 0:
    locations_infos = self.ConfNodeInfos[confnode]["locations_infos"]
    expandbutton.SetToggle(locations_infos["root"]["expanded"])
    +
    def togglebutton(event):
    if expandbutton.GetToggle():
    self.ExpandLocation(locations_infos, "root")
    @@ -1435,47 +1485,49 @@
    self.PLCConfigMainSizer.Layout()
    self.RefreshScrollBars()
    event.Skip()
    +
    expandbutton.Bind(wx.EVT_BUTTON, togglebutton, id=expandbutton_id)
    else:
    expandbutton.Enable(False)
    - nodewindowsizer.AddWindow(expandbutton, 0, border=5, flag=wx.RIGHT|wx.ALIGN_CENTER_VERTICAL)
    -
    + nodewindowsizer.AddWindow(expandbutton, 0, border=5, flag=wx.RIGHT | wx.ALIGN_CENTER_VERTICAL)
    +
    sb = wx.StaticBitmap(nodewindow, -1)
    icon = confnode_infos.get("icon", None)
    if icon is None:
    icon_bitmap = self.LocationImageList.GetBitmap(self.LocationImageDict[confnode_infos["type"]])
    - else:
    + else:
    icon_bitmap = wx.Bitmap(icon)
    sb.SetBitmap(icon_bitmap)
    - nodewindowsizer.AddWindow(sb, 0, border=5, flag=wx.RIGHT|wx.ALIGN_CENTER_VERTICAL)
    -
    + nodewindowsizer.AddWindow(sb, 0, border=5, flag=wx.RIGHT | wx.ALIGN_CENTER_VERTICAL)
    +
    st_id = wx.NewId()
    st = wx.StaticText(nodewindow, st_id, size=wx.DefaultSize, style=wx.NO_BORDER)
    - st.SetFont(wx.Font(faces["size"] * 0.75, wx.DEFAULT, wx.NORMAL, wx.BOLD, faceName = faces["helv"]))
    + st.SetFont(wx.Font(faces["size"] * 0.75, wx.DEFAULT, wx.NORMAL, wx.BOLD, faceName=faces["helv"]))
    st.SetLabel(confnode.MandatoryParams[1].getName())
    - nodewindowsizer.AddWindow(st, 0, border=5, flag=wx.RIGHT|wx.ALIGN_CENTER_VERTICAL)
    -
    + nodewindowsizer.AddWindow(st, 0, border=5, flag=wx.RIGHT | wx.ALIGN_CENTER_VERTICAL)
    +
    buttons_sizer = self.GenerateMethodButtonSizer(confnode, nodewindow)
    nodewindowsizer.AddSizer(buttons_sizer, flag=wx.ALIGN_CENTER_VERTICAL)
    -
    +
    self.ConfNodeInfos[confnode]["window"] = nodewindow
    for child in self.ConfNodeInfos[confnode]["children"]:
    self.GenerateTreeBranch(child)
    if not self.ConfNodeInfos[child]["expanded"]:
    self.CollapseConfNode(child)
    -
    +
    if len(confnode_locations) > 0:
    locations_infos = self.ConfNodeInfos[confnode]["locations_infos"]
    - treectrl = wx.TreeCtrl(self.PLCConfig, -1, size=wx.DefaultSize,
    - style=wx.TR_HAS_BUTTONS|wx.TR_SINGLE|wx.NO_BORDER|wx.TR_HIDE_ROOT|wx.TR_NO_LINES|wx.TR_LINES_AT_ROOT)
    + treectrl = wx.TreeCtrl(self.PLCConfig, -1, size=wx.DefaultSize,
    + style=wx.TR_HAS_BUTTONS | wx.TR_SINGLE | wx.NO_BORDER | wx.TR_HIDE_ROOT | wx.TR_NO_LINES | wx.TR_LINES_AT_ROOT)
    treectrl.SetImageList(self.LocationImageList)
    treectrl.Bind(wx.EVT_TREE_BEGIN_DRAG, self.GenerateLocationBeginDragFunction(locations_infos))
    treectrl.Bind(wx.EVT_TREE_ITEM_EXPANDED, self.GenerateLocationExpandCollapseFunction(locations_infos, True))
    - treectrl.Bind(wx.EVT_TREE_ITEM_COLLAPSED, self.GenerateLocationExpandCollapseFunction(locations_infos, False))
    -
    + treectrl.Bind(wx.EVT_TREE_ITEM_COLLAPSED,
    + self.GenerateLocationExpandCollapseFunction(locations_infos, False))
    +
    treectrl.AddRoot("")
    self.ConfNodeTreeSizer.AddWindow(treectrl, 0, border=0, flag=0)
    -
    +
    locations_infos["root"]["window"] = treectrl
    for location in confnode_locations:
    locations_infos["root"]["children"].append("root.%s" % location["name"])
    @@ -1483,7 +1535,7 @@
    if locations_infos["root"]["expanded"]:
    self.ExpandLocation(locations_infos, "root")
    - def ExpandConfNode(self, confnode, force = False):
    + def ExpandConfNode(self, confnode, force=False):
    for child in self.ConfNodeInfos[confnode]["children"]:
    self.ConfNodeInfos[child]["window"].Show()
    if force or self.ConfNodeInfos[child]["expanded"]:
    @@ -1496,8 +1548,8 @@
    self.ExpandLocation(locations_infos, "root", force)
    if force:
    locations_infos["root"]["expanded"] = True
    -
    - def CollapseConfNode(self, confnode, force = False):
    +
    + def CollapseConfNode(self, confnode, force=False):
    for child in self.ConfNodeInfos[confnode]["children"]:
    self.ConfNodeInfos[child]["window"].Hide()
    self.CollapseConfNode(child, force)
    @@ -1509,7 +1561,7 @@
    if force:
    locations_infos["root"]["expanded"] = False
    - def ExpandLocation(self, locations_infos, group, force = False, refresh_size=True):
    + def ExpandLocation(self, locations_infos, group, force=False, refresh_size=True):
    locations_infos[group]["expanded"] = True
    if group == "root":
    if locations_infos[group]["window"] is not None:
    @@ -1521,8 +1573,8 @@
    self.ExpandLocation(locations_infos, child, force, False)
    if locations_infos["root"]["window"] is not None and refresh_size:
    self.RefreshTreeCtrlSize(locations_infos["root"]["window"])
    -
    - def CollapseLocation(self, locations_infos, group, force = False, refresh_size=True):
    +
    + def CollapseLocation(self, locations_infos, group, force=False, refresh_size=True):
    locations_infos[group]["expanded"] = False
    if group == "root":
    if locations_infos[group]["window"] is not None:
    @@ -1538,8 +1590,8 @@
    def GenerateLocationTreeBranch(self, treectrl, root, locations_infos, parent, location):
    location_name = "%s.%s" % (parent, location["name"])
    if not locations_infos.has_key(location_name):
    - locations_infos[location_name] = {"expanded" : False}
    -
    + locations_infos[location_name] = {"expanded": False}
    +
    if location["type"] in [LOCATION_VAR_INPUT, LOCATION_VAR_OUTPUT, LOCATION_VAR_MEMORY]:
    label = "%(name)s (%(location)s)" % location
    elif location["location"] != "":
    @@ -1549,7 +1601,7 @@
    item = treectrl.AppendItem(root, label)
    treectrl.SetPyData(item, location_name)
    treectrl.SetItemImage(item, self.LocationImageDict[location["type"]])
    -
    +
    locations_infos[location_name]["item"] = item
    locations_infos[location_name]["children"] = []
    infos = location.copy()
    @@ -1561,7 +1613,7 @@
    self.GenerateLocationTreeBranch(treectrl, item, locations_infos, location_name, child)
    if locations_infos[location_name]["expanded"]:
    self.ExpandLocation(locations_infos, location_name)
    -
    +
    def GenerateLocationBeginDragFunction(self, locations_infos):
    def OnLocationBeginDragFunction(event):
    item = event.GetItem()
    @@ -1569,12 +1621,14 @@
    if location_name is not None:
    infos = locations_infos[location_name]["infos"]
    if infos["type"] in [LOCATION_VAR_INPUT, LOCATION_VAR_OUTPUT, LOCATION_VAR_MEMORY]:
    - data = wx.TextDataObject(str((infos["location"], "location", infos["IEC_type"], infos["var_name"], infos["description"])))
    + data = wx.TextDataObject(str((infos["location"], "location", infos["IEC_type"], infos["var_name"],
    + infos["description"])))
    dragSource = wx.DropSource(self)
    dragSource.SetData(data)
    dragSource.DoDragDrop()
    +
    return OnLocationBeginDragFunction
    -
    +
    def RefreshTreeCtrlSize(self, treectrl):
    rect = self.GetTreeCtrlItemRect(treectrl, treectrl.GetRootItem())
    treectrl.SetMinSize(wx.Size(max(rect.width, rect.x + rect.width) + 20, max(rect.height, rect.y + rect.height)))
    @@ -1589,7 +1643,7 @@
    maxx, maxy = item_rect.x + item_rect.width, item_rect.y + item_rect.height
    else:
    minx = miny = maxx = maxy = 0
    -
    +
    if treectrl.ItemHasChildren(item) and (item == treectrl.GetRootItem() or treectrl.IsExpanded(item)):
    if wx.VERSION >= (2, 6, 0):
    child, item_cookie = treectrl.GetFirstChild(item)
    @@ -1602,9 +1656,9 @@
    maxx = max(maxx, child_rect.x + child_rect.width)
    maxy = max(maxy, child_rect.y + child_rect.height)
    child, item_cookie = treectrl.GetNextChild(item, item_cookie)
    -
    +
    return wx.Rect(minx, miny, maxx - minx, maxy - miny)
    -
    +
    def GenerateLocationExpandCollapseFunction(self, locations_infos, expand):
    def OnLocationExpandedFunction(event):
    item = event.GetItem()
    @@ -1613,22 +1667,25 @@
    locations_infos[location_name]["expanded"] = expand
    self.RefreshTreeCtrlSize(locations_infos["root"]["window"])
    event.Skip()
    +
    return OnLocationExpandedFunction
    -
    +
    def GetButtonCallBackFunction(self, confnode, method):
    """ Generate the callbackfunc for a given confnode method"""
    +
    def OnButtonClick(event):
    # Disable button to prevent re-entrant call
    event.GetEventObject().Disable()
    # Call
    - getattr(confnode,method)()
    + getattr(confnode, method)()
    # Re-enable button
    event.GetEventObject().Enable()
    # Trigger refresh on Idle
    wx.CallAfter(self.RefreshAll)
    event.Skip()
    +
    return OnButtonClick
    -
    +
    def ClearSizer(self, sizer):
    staticboxes = []
    for item in sizer.GetChildren():
    @@ -1640,26 +1697,26 @@
    sizer.Clear(True)
    for staticbox in staticboxes:
    staticbox.Destroy()
    -
    +
    def RefreshAll(self):
    Beremiz.RefreshAll(self)
    self.RefreshPLCParams()
    self.RefreshConfNodeTree()
    -
    +
    # Remove taskbar icon when simulating
    - def StartLocalRuntime(self, taskbaricon = True):
    - return Beremiz.StartLocalRuntime(self, taskbaricon = False)
    + def StartLocalRuntime(self, taskbaricon=True):
    + return Beremiz.StartLocalRuntime(self, taskbaricon=False)
    +
    class StdoutPseudoFile:
    -
    def __init__(self, port):
    self.socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
    self.socket.connect(('localhost', port))
    self.Buffer = ""
    -
    +
    def __del__(self):
    self.socket.close()
    -
    +
    def readline(self):
    idx = self.Buffer.find("\n")
    while idx == -1:
    @@ -1669,18 +1726,19 @@
    self.Buffer += text
    idx = self.Buffer.find("\n")
    if idx != -1:
    - line = self.Buffer[:idx+1]
    - self.Buffer = self.Buffer[idx+1:]
    + line = self.Buffer[:idx + 1]
    + self.Buffer = self.Buffer[idx + 1:]
    if BMZ_DBG:
    - print "command >"+line
    + print "command >" + line
    return line
    return ""
    -
    +
    """ Base class for file like objects to facilitate StdOut for the Shell."""
    - def write(self, s, style = None):
    +
    + def write(self, s, style=None):
    if s != '':
    self.socket.send(s.encode('utf8'))
    -
    +
    def writeyield(self, s):
    self.write(s)
    @@ -1692,62 +1750,68 @@
    def flush(self):
    pass
    -
    +
    def isatty(self):
    return False
    +
    if __name__ == '__main__':
    -
    +
    from threading import Thread, Timer, Semaphore
    import cmd
    wx_eval_lock = Semaphore(0)
    eval_res = None
    +
    +
    def wx_evaluator(callable, *args, **kwargs):
    global eval_res
    eval_res = None
    try:
    - eval_res=callable(*args,**kwargs)
    + eval_res = callable(*args, **kwargs)
    finally:
    wx_eval_lock.release()
    +
    def evaluator(callable, *args, **kwargs):
    global eval_res
    - wx.CallAfter(wx_evaluator,callable,*args,**kwargs)
    + wx.CallAfter(wx_evaluator, callable, *args, **kwargs)
    wx_eval_lock.acquire()
    return eval_res
    +
    # Command log for debug, for viewing from wxInspector
    if BMZ_DBG:
    __builtins__.cmdlog = []
    +
    class LPCBeremiz_Cmd(cmd.Cmd):
    -
    +
    prompt = ""
    RefreshTimer = None
    -
    +
    def __init__(self, CTR, Log):
    cmd.Cmd.__init__(self, stdin=Log, stdout=Log)
    self.use_rawinput = False
    self.restore_last_state = False
    self.Log = Log
    self.CTR = CTR
    -
    +
    def RestartTimer(self):
    if self.RefreshTimer is not None:
    self.RefreshTimer.cancel()
    - self.RefreshTimer = Timer(0.1, wx.CallAfter, args = [self.Refresh])
    + self.RefreshTimer = Timer(0.1, wx.CallAfter, args=[self.Refresh])
    self.RefreshTimer.start()
    -
    +
    def Exit(self):
    global frame, app
    self.Close()
    app.ExitMainLoop()
    return True
    -
    +
    def do_EOF(self, line):
    return self.Exit()
    -
    +
    def Show(self):
    global frame
    if frame is not None:
    @@ -1757,7 +1821,7 @@
    frame.Raise()
    self.restore_last_state = True
    self.RestartTimer()
    -
    +
    def Refresh(self):
    global frame
    if frame is not None:
    @@ -1768,17 +1832,17 @@
    frame.RefreshEditor()
    frame._Refresh(TITLE, PROJECTTREE, POUINSTANCEVARIABLESPANEL, FILEMENU, EDITMENU)
    frame.RefreshAll()
    -
    +
    def Close(self):
    global frame
    -
    +
    self.CTR.ResetAppFrame(self.Log)
    if frame is not None:
    frame.Hide()
    -
    +
    def Compile(self):
    self.CTR._Build()
    -
    +
    def SetProjectProperties(self, projectname, productname, productversion, companyname):
    new_properties = {
    "projectName": projectname,
    @@ -1787,11 +1851,11 @@
    "companyName": companyname}
    self.CTR.SetProjectProperties(properties=new_properties, buffer=False)
    self.RestartTimer()
    -
    +
    def SetOnlineMode(self, mode, path=None):
    self.CTR.SetOnlineMode(mode, path)
    self.RestartTimer()
    -
    +
    def AddBus(self, iec_channel, name, icon=None):
    for child in self.CTR.IterChildren():
    if child.BaseParams.getName() == name:
    @@ -1803,7 +1867,7 @@
    return "Error: Unable to create bus\n"
    bus.SetIcon(icon)
    self.RestartTimer()
    -
    +
    def RenameBus(self, iec_channel, name):
    bus = self.CTR.GetChildByIECLocation((iec_channel,))
    if bus is None:
    @@ -1813,7 +1877,7 @@
    return "Error: A bus named %s already exists\n" % name
    bus.BaseParams.setName(name)
    self.RestartTimer()
    -
    +
    def ChangeBusIECChannel(self, old_iec_channel, new_iec_channel):
    bus = self.CTR.GetChildByIECLocation((old_iec_channel,))
    if bus is None:
    @@ -1822,15 +1886,15 @@
    if child != bus and child.BaseParams.getIEC_Channel() == new_iec_channel:
    return "Error: A bus with IEC_channel %d already exists\n" % new_iec_channel
    if wx.GetApp() is None:
    - self.CTR.UpdateProjectVariableLocation(str(old_iec_channel),
    - str(new_iec_channel))
    + self.CTR.UpdateProjectVariableLocation(str(old_iec_channel),
    + str(new_iec_channel))
    else:
    self.CTR.UpdateProjectVariableLocation(
    - str(old_iec_channel),
    - str(new_iec_channel))
    + str(old_iec_channel),
    + str(new_iec_channel))
    bus.BaseParams.setIEC_Channel(new_iec_channel)
    self.RestartTimer()
    -
    +
    def RemoveBus(self, iec_channel):
    bus = self.CTR.GetChildByIECLocation((iec_channel,))
    if bus is None:
    @@ -1838,7 +1902,7 @@
    self.CTR.RemoveProjectVariableByFilter(str(iec_channel))
    self.CTR.Children["LPCBus"].remove(bus)
    self.RestartTimer()
    -
    +
    def AddModule(self, parent, iec_channel, name, icode, icon=None):
    module = self.CTR.GetChildByIECLocation(parent)
    if module is None:
    @@ -1847,15 +1911,15 @@
    if child["name"] == name:
    return "Error: A module named %s already exists\n" % name
    elif child["IEC_Channel"] == iec_channel:
    - return "Error: A module with IEC_channel %d already exists\n" % iec_channel
    - GetLastModuleGroup(module).append({"name": name,
    - "type": LOCATION_MODULE,
    - "IEC_Channel": iec_channel,
    - "icon": icon,
    - "init": icode,
    - "children": []})
    + return "Error: A module with IEC_channel %d already exists\n" % iec_channel
    + GetLastModuleGroup(module).append({"name": name,
    + "type": LOCATION_MODULE,
    + "IEC_Channel": iec_channel,
    + "icon": icon,
    + "init": icode,
    + "children": []})
    self.RestartTimer()
    -
    +
    def RenameModule(self, iec_location, name):
    module = self.CTR.GetChildByIECLocation(iec_location)
    if module is None:
    @@ -1869,7 +1933,7 @@
    return "Error: A module named %s already exists\n" % name
    module["name"] = name
    self.RestartTimer()
    -
    +
    def ChangeModuleIECChannel(self, old_iec_location, new_iec_channel):
    module = self.CTR.GetChildByIECLocation(old_iec_location)
    if module is None:
    @@ -1881,16 +1945,17 @@
    for child in GetModuleChildren(parent):
    if child["IEC_Channel"] == new_iec_channel:
    return "Error: A module with IEC_channel %d already exists\n" % new_iec_channel
    - self.CTR.UpdateProjectVariableLocation(".".join(map(str, old_iec_location)), ".".join(map(str, old_iec_location[:1] + (new_iec_channel,))))
    + self.CTR.UpdateProjectVariableLocation(".".join(map(str, old_iec_location)),
    + ".".join(map(str, old_iec_location[:1] + (new_iec_channel,))))
    module["IEC_Channel"] = new_iec_channel
    self.RestartTimer()
    -
    +
    def ChangeModuleInitCode(self, iec_location, icode):
    module = self.CTR.GetChildByIECLocation(iec_location)
    if module is None:
    return "Error: No module found\n"
    module["init"] = icode
    -
    +
    def RemoveModule(self, parent, iec_channel):
    module = self.CTR.GetChildByIECLocation(parent)
    if module is None:
    @@ -1901,7 +1966,7 @@
    self.CTR.RemoveProjectVariableByFilter(".".join(map(str, parent + (iec_channel,))))
    RemoveModuleChild(module, child)
    self.RestartTimer()
    -
    +
    def StartGroup(self, parent, name, icon=None):
    module = self.CTR.GetChildByIECLocation(parent)
    if module is None:
    @@ -1909,12 +1974,12 @@
    for child in module["children"]:
    if child["type"] == LOCATION_GROUP and child["name"] == name:
    return "Error: A group named %s already exists\n" % name
    - module["children"].append({"name": name,
    - "type": LOCATION_GROUP,
    - "icon": icon,
    - "children": []})
    + module["children"].append({"name": name,
    + "type": LOCATION_GROUP,
    + "icon": icon,
    + "children": []})
    self.RestartTimer()
    -
    +
    def AddVariable(self, parent, location, name, direction, type, rcode, pcode, description=""):
    module = self.CTR.GetChildByIECLocation(parent)
    if module is None:
    @@ -1924,16 +1989,17 @@
    return "Error: A variable named %s already exists\n" % name
    if child["location"] == location and child["type"] == LOCATION_TYPES[direction]:
    return "Error: A variable with location %s already exists\n" % ".".join(map(str, location))
    - GetLastModuleGroup(module).append({"name": name,
    - "location": location,
    - "type": LOCATION_TYPES[direction],
    - "IEC_type": type,
    - "description": description,
    - "retrieve": rcode,
    - "publish": pcode})
    + GetLastModuleGroup(module).append({"name": name,
    + "location": location,
    + "type": LOCATION_TYPES[direction],
    + "IEC_type": type,
    + "description": description,
    + "retrieve": rcode,
    + "publish": pcode})
    self.RestartTimer()
    - def ChangeVariableParams(self, parent, location, new_name, new_direction, new_type, new_rcode, new_pcode, new_description=None):
    + def ChangeVariableParams(self, parent, location, new_name, new_direction, new_type, new_rcode, new_pcode,
    + new_description=None):
    module = self.CTR.GetChildByIECLocation(parent)
    if module is None:
    return "Error: No parent found\n"
    @@ -1955,7 +2021,7 @@
    if new_description is not None:
    variable["description"] = new_description
    self.RestartTimer()
    -
    +
    def RemoveVariable(self, parent, location, direction):
    module = self.CTR.GetChildByIECLocation(parent)
    if module is None:
    @@ -1968,12 +2034,15 @@
    self.CTR.RemoveProjectVariableByAddress(address)
    RemoveModuleChild(module, child)
    self.RestartTimer()
    -
    +
    +
    def location(loc):
    return tuple(map(int, loc.split(".")))
    -
    +
    +
    def GetCmdFunction(function, arg_types, opt=0):
    arg_number = len(arg_types)
    +
    def CmdFunction(self, line):
    args_toks = line.split('"')
    if len(args_toks) % 2 == 0:
    @@ -2016,20 +2085,22 @@
    return
    func = getattr(self, function)
    - res = evaluator(func,*args)
    + res = evaluator(func, *args)
    if BMZ_DBG:
    - cmdlog.append((function,line,res))
    - if len(cmdlog) > 100: #prevent debug log to grow too much
    - cmdlog.pop(0)
    + cmdlog.append((function, line, res))
    + if len(cmdlog) > 100: # prevent debug log to grow too much
    + cmdlog.pop(0)
    if isinstance(res, (StringType, UnicodeType)):
    self.Log.write(res)
    return False
    else:
    return res
    +
    return CmdFunction
    +
    def CmdThreadProc(CTR, Log):
    global lpcberemiz_cmd
    for function, (arg_types, opt) in {"Exit": ([], 0),
    @@ -2043,25 +2114,26 @@
    "RenameBus": ([int, str], 0),
    "ChangeBusIECChannel": ([int, int], 0),
    "RemoveBus": ([int], 0),
    - "AddModule": ([location, int, str, str, str], 1),
    + "AddModule": ([location, int, str, str, str], 1),
    "RenameModule": ([location, str], 0),
    "ChangeModuleIECChannel": ([location, int], 0),
    "ChangeModuleInitCode": ([location, str], 0),
    "RemoveModule": ([location, int], 0),
    "StartGroup": ([location, str, str], 1),
    "AddVariable": ([location, location, str, str, str, str, str, str], 1),
    - "ChangeVariableParams": ([location, location, str, str, str, str, str, str], 1),
    + "ChangeVariableParams": (
    + [location, location, str, str, str, str, str, str], 1),
    "RemoveVariable": ([location, location], 0)}.iteritems():
    -
    setattr(LPCBeremiz_Cmd, "do_%s" % function, GetCmdFunction(function, arg_types, opt))
    lpcberemiz_cmd = LPCBeremiz_Cmd(CTR, Log)
    lpcberemiz_cmd.cmdloop()
    +
    Log = StdoutPseudoFile(port)
    if projectOpen is not None:
    projectOpen = DecodeFileSystemPath(projectOpen, False)
    -
    +
    CTR = LPCProjectController(None, Log, buildpath)
    if projectOpen is not None and os.path.isdir(projectOpen):
    result = CTR.LoadProject(projectOpen)
    @@ -2069,14 +2141,13 @@
    Log.write("Error: Invalid project directory", result)
    else:
    Log.write("Error: No such file or directory")
    -
    - cmd_thread=Thread(target=CmdThreadProc, args=[CTR, Log])
    +
    + cmd_thread = Thread(target=CmdThreadProc, args=[CTR, Log])
    cmd_thread.start()
    # Install a exception handle for bug reports
    - AddExceptHook(os.getcwd(),__version__)
    -
    + AddExceptHook(os.getcwd(), __version__)
    +
    frame = LPCBeremiz(None, ctr=CTR, debug=True)
    -
    +
    app.MainLoop()
    -