LPCBeremiz.py
changeset 447 af3399aca7b7
parent 444 8eb1186fc9cf
child 445 1b1dc8ad2498
equal deleted inserted replaced
446:1edde533db19 447:af3399aca7b7
       
     1 #!/usr/bin/env python
       
     2 # -*- coding: utf-8 -*-
       
     3 
       
     4 __version__ = "$Revision$"
       
     5 
       
     6 import os, sys, getopt, wx, tempfile
       
     7 from types import TupleType, StringType, UnicodeType
       
     8 
       
     9 CWD = os.path.split(os.path.realpath(__file__))[0]
       
    10 
       
    11 def Bpath(*args):
       
    12     return os.path.join(CWD,*args)
       
    13 
       
    14 if __name__ == '__main__':
       
    15     def usage():
       
    16         print "\nUsage of LPCBeremiz.py :"
       
    17         print "\n   %s [Projectpath] [Buildpath]\n"%sys.argv[0]
       
    18     
       
    19     try:
       
    20         opts, args = getopt.getopt(sys.argv[1:], "h", ["help"])
       
    21     except getopt.GetoptError:
       
    22         # print help information and exit:
       
    23         usage()
       
    24         sys.exit(2)
       
    25     
       
    26     for o, a in opts:
       
    27         if o in ("-h", "--help"):
       
    28             usage()
       
    29             sys.exit()
       
    30     
       
    31     if len(args) > 2:
       
    32         usage()
       
    33         sys.exit()
       
    34     elif len(args) == 1:
       
    35         projectOpen = args[0]
       
    36         buildpath = None
       
    37     elif len(args) == 2:
       
    38         projectOpen = args[0]
       
    39         buildpath = args[1]
       
    40     else:
       
    41         projectOpen = None
       
    42         buildpath = None
       
    43 
       
    44 class PseudoLocale:
       
    45     LocaleDirs = []
       
    46     Domains = []
       
    47     
       
    48     def AddCatalogLookupPathPrefix(self, localedir):
       
    49         self.LocaleDirs.append(localedir)
       
    50     
       
    51     def AddCatalog(self, domain):
       
    52         self.Domains.append(domain)
       
    53 
       
    54 # Import module for internationalization
       
    55 import gettext
       
    56 import __builtin__
       
    57 
       
    58 # Define locale for wx
       
    59 __builtin__.__dict__['loc'] = PseudoLocale()
       
    60 
       
    61 if __name__ == '__main__':
       
    62     __builtin__.__dict__['_'] = wx.GetTranslation#unicode_translation
       
    63 
       
    64 from Beremiz import *
       
    65 from plugger import PluginsRoot, PlugTemplate, opjimg
       
    66 from plcopen.structures import LOCATIONDATATYPES
       
    67 from PLCControler import LOCATION_PLUGIN, LOCATION_MODULE, LOCATION_GROUP,\
       
    68                          LOCATION_VAR_INPUT, LOCATION_VAR_OUTPUT, LOCATION_VAR_MEMORY
       
    69 from PLCOpenEditor import IDEFrame
       
    70 
       
    71 #-------------------------------------------------------------------------------
       
    72 #                              LPCModule Class
       
    73 #-------------------------------------------------------------------------------
       
    74 
       
    75 def _GetModuleChildren(module):
       
    76     children = []
       
    77     for child in module["children"]:
       
    78         if child["type"] == LOCATION_GROUP:
       
    79             children.extend(child["children"])
       
    80         else:
       
    81             children.append(child)
       
    82     return children
       
    83 
       
    84 def _GetLastModuleGroup(module):
       
    85     group = module
       
    86     for child in module["children"]:
       
    87         if child["type"] == LOCATION_GROUP:
       
    88             group = child
       
    89     return group["children"]
       
    90 
       
    91 def _GetModuleBySomething(module, something, toks):
       
    92     for child in _GetModuleChildren(module):
       
    93         if child.get(something) == toks[0]:
       
    94             if len(toks) > 1:
       
    95                 return _GetModuleBySomething(child, something, toks[1:])
       
    96             return child
       
    97     return None
       
    98 
       
    99 def _GetModuleVariable(module, location):
       
   100     for child in _GetModuleChildren(module):
       
   101         if child["location"] == location:
       
   102             return child
       
   103     return None
       
   104 
       
   105 def _RemoveModuleChild(module, child):
       
   106     if child in module["children"]:
       
   107         module["children"].remove(child)
       
   108     else:
       
   109         for group in module["children"]:
       
   110             if group["type"] == LOCATION_GROUP and child in group["children"]:
       
   111                 group["children"].remove(child)
       
   112 
       
   113 LOCATION_TYPES = {"I": LOCATION_VAR_INPUT,
       
   114                   "Q": LOCATION_VAR_OUTPUT,
       
   115                   "M": LOCATION_VAR_MEMORY}
       
   116 
       
   117 LOCATION_DIRS = dict([(dir, size) for size, dir in LOCATION_TYPES.iteritems()])
       
   118 
       
   119 LOCATION_SIZES = {}
       
   120 for size, types in LOCATIONDATATYPES.iteritems():
       
   121     for type in types:
       
   122         LOCATION_SIZES[type] = size
       
   123 
       
   124 BUS_TEXT = """/* Code generated by LPCBus plugin */
       
   125 
       
   126 /* LPCBus plugin includes */
       
   127 #include "app_glue.h"
       
   128 #ifdef _WINDOWS_H
       
   129   #include "iec_types.h"
       
   130 #else
       
   131   #include "iec_std_lib.h"
       
   132 #endif
       
   133 
       
   134 %(declare_code)s
       
   135 
       
   136 /* LPCBus plugin user variables definition */
       
   137 %(var_decl)s
       
   138 
       
   139 /* LPCBus plugin functions */
       
   140 int __init_%(location_str)s(int argc,char **argv)
       
   141 {
       
   142   return 0;
       
   143 }
       
   144 
       
   145 void __cleanup_%(location_str)s(void)
       
   146 {
       
   147 }
       
   148 
       
   149 void __retrieve_%(location_str)s(void)
       
   150 {
       
   151   %(retrieve_code)s
       
   152 }
       
   153         
       
   154 void __publish_%(location_str)s(void)
       
   155 {
       
   156   %(publish_code)s
       
   157 }
       
   158 """
       
   159 
       
   160 class LPCBus(object):
       
   161     
       
   162     def __init__(self):
       
   163         self.VariableLocationTree = []
       
   164         self.ResetUsedLocations()
       
   165         self.Icon = None
       
   166     
       
   167     def __getitem__(self, key):
       
   168         if key == "children":
       
   169             return self.VariableLocationTree
       
   170         raise KeyError, "Only 'children' key is available"
       
   171     
       
   172     def SetIcon(self, icon):
       
   173         self.Icon = icon
       
   174     
       
   175     def _GetChildBySomething(self, something, toks):
       
   176         return _GetModuleBySomething({"children" : self.VariableLocationTree}, something, toks)
       
   177     
       
   178     def GetBaseTypes(self):
       
   179         return self.GetPlugRoot().GetBaseTypes()
       
   180 
       
   181     def GetSizeOfType(self, type):
       
   182         return LOCATION_SIZES[self.GetPlugRoot().GetBaseType(type)]
       
   183     
       
   184     def _GetVariableLocationTree(self, current_location, infos):
       
   185         if infos["type"] == LOCATION_MODULE:
       
   186             location = current_location + (infos["IEC_Channel"],)
       
   187             return {"name": infos["name"],
       
   188                     "type": infos["type"],
       
   189                     "location": ".".join(map(str, location + ("x",))), 
       
   190                     "icon": infos["icon"], 
       
   191                     "children": [self._GetVariableLocationTree(location, child) for child in infos["children"]]}
       
   192         elif infos["type"] == LOCATION_GROUP:
       
   193             return {"name": infos["name"],
       
   194                     "type": infos["type"],
       
   195                     "location": "", 
       
   196                     "icon": infos["icon"], 
       
   197                     "children": [self._GetVariableLocationTree(current_location, child) for child in infos["children"]]}
       
   198         else:
       
   199             size = self.GetSizeOfType(infos["IEC_type"])
       
   200             location = "%" + LOCATION_DIRS[infos["type"]] + size + ".".join(map(str, current_location + infos["location"]))
       
   201             return {"name": infos["name"],
       
   202                     "type": infos["type"],
       
   203                     "size": size,
       
   204                     "IEC_type": infos["IEC_type"],
       
   205                     "location": location,
       
   206                     "description": infos["description"],
       
   207                     "children": []}
       
   208     
       
   209     def GetVariableLocationTree(self):
       
   210         return {"name": self.BaseParams.getName(),
       
   211                 "type": LOCATION_PLUGIN,
       
   212                 "location": self.GetFullIEC_Channel(),
       
   213                 "icon": self.Icon, 
       
   214                 "children": [self._GetVariableLocationTree(self.GetCurrentLocation(), child) 
       
   215                              for child in self.VariableLocationTree]}
       
   216     
       
   217     def PlugTestModified(self):
       
   218         return False
       
   219 
       
   220     def PlugMakeDir(self):
       
   221         pass
       
   222 
       
   223     def PlugRequestSave(self):
       
   224         return None
       
   225 
       
   226     def ResetUsedLocations(self):
       
   227         self.UsedLocations = {}
       
   228     
       
   229     def _AddUsedLocation(self, parent, location):
       
   230         num = location.pop(0)
       
   231         if not parent.has_key(num):
       
   232             parent[num] = {"used": False, "children": {}}
       
   233         if len(location) > 0:
       
   234             self._AddUsedLocation(parent[num]["children"], location)
       
   235         else:
       
   236             parent[num]["used"] = True
       
   237         
       
   238     def AddUsedLocation(self, location):
       
   239         if len(location) > 0:
       
   240             self._AddUsedLocation(self.UsedLocations, list(location))
       
   241 
       
   242     def _CheckLocationConflicts(self, parent, location):
       
   243         num = location.pop(0)
       
   244         if not parent.has_key(num):
       
   245             return False
       
   246         if len(location) > 0:
       
   247             if parent[num]["used"]:
       
   248                 return True
       
   249             return self._CheckLocationConflicts(parent[num]["children"], location)
       
   250         elif len(parent[num]["children"]) > 0:
       
   251             return True
       
   252         return False
       
   253 
       
   254     def CheckLocationConflicts(self, location):
       
   255         if len(location) > 0:
       
   256             return self._CheckLocationConflicts(self.UsedLocations, list(location))
       
   257         return False
       
   258 
       
   259     def PlugGenerate_C(self, buildpath, locations):
       
   260         """
       
   261         Generate C code
       
   262         @param current_location: Tupple containing plugin IEC location : %I0.0.4.5 => (0,0,4,5)
       
   263         @param locations: List of complete variables locations \
       
   264             [{"IEC_TYPE" : the IEC type (i.e. "INT", "STRING", ...)
       
   265             "NAME" : name of the variable (generally "__IW0_1_2" style)
       
   266             "DIR" : direction "Q","I" or "M"
       
   267             "SIZE" : size "X", "B", "W", "D", "L"
       
   268             "LOC" : tuple of interger for IEC location (0,1,2,...)
       
   269             }, ...]
       
   270         @return: [(C_file_name, CFLAGS),...] , LDFLAGS_TO_APPEND
       
   271         """
       
   272         current_location = self.GetCurrentLocation()
       
   273         # define a unique name for the generated C file
       
   274         location_str = "_".join(map(str, current_location))
       
   275         
       
   276         code_str = {"location_str": location_str,
       
   277                     "var_decl": "",
       
   278                     "declare_code": "",
       
   279                     "retrieve_code": "",
       
   280                     "publish_code": "",
       
   281                    }
       
   282         
       
   283         # Adding variables
       
   284         vars = []
       
   285         self.ResetUsedLocations()
       
   286         for location in locations:
       
   287             loc = location["LOC"][len(current_location):]
       
   288             group = next = self
       
   289             i = 0
       
   290             while next is not None and i < len(loc):
       
   291                 next = self._GetChildBySomething("IEC_Channel", loc[:i + 1])
       
   292                 if next is not None:
       
   293                     i += 1
       
   294                     group = next
       
   295             var_loc = loc[i:]
       
   296             for variable in group["children"]:
       
   297                 if variable["location"] == var_loc:
       
   298                     if location["DIR"] != LOCATION_DIRS[variable["type"]]:
       
   299                         raise Exception, "Direction conflict in variable definition"
       
   300                     if location["IEC_TYPE"] != variable["IEC_type"]:
       
   301                         raise Exception, "Type conflict in variable definition"
       
   302                     if location["DIR"] == "Q":
       
   303                         if self.CheckLocationConflicts(location["LOC"]):
       
   304                             raise Exception, "BYTE and BIT from the same BYTE can't be used together"
       
   305                         self.AddUsedLocation(location["LOC"])
       
   306                     vars.append({"location": location["NAME"],
       
   307                                  "Type": variable["IEC_type"],
       
   308                                  "Declare": variable["declare"],
       
   309                                  "Retrieve": variable["retrieve"],
       
   310                                  "Publish": variable["publish"],
       
   311                                 })
       
   312                     break
       
   313         base_types = self.GetPlugRoot().GetBaseTypes()
       
   314         for var in vars:
       
   315             prefix = ""
       
   316             if var["Type"] in base_types:
       
   317                 prefix = "IEC_"
       
   318             code_str["var_decl"] += "%s%s beremiz%s;\n"%(prefix, var["Type"], var["location"])
       
   319             code_str["var_decl"] += "%s%s *%s = &beremiz%s;\n"%(prefix, var["Type"], var["location"], var["location"])
       
   320             if var["Declare"] != "":
       
   321                 code_str["declare_code"] += var["Declare"] + "\n"
       
   322             if var["Retrieve"] != "":
       
   323                 code_str["retrieve_code"] += var["Retrieve"] % ("*" + var["location"]) + "\n"
       
   324             if var["Publish"] != "":
       
   325                 code_str["publish_code"] += var["Publish"] % ("*" + var["location"]) + "\n"
       
   326         
       
   327         Gen_Module_path = os.path.join(buildpath, "Module_%s.c"%location_str)
       
   328         module = open(Gen_Module_path,'w')
       
   329         module.write(BUS_TEXT % code_str)
       
   330         module.close()
       
   331         
       
   332         matiec_flags = '"-I%s"'%os.path.abspath(self.GetPlugRoot().GetIECLibPath())
       
   333         return [(Gen_Module_path, matiec_flags)],"",True
       
   334 
       
   335 #-------------------------------------------------------------------------------
       
   336 #                              LPCPluginsRoot Class
       
   337 #-------------------------------------------------------------------------------
       
   338 
       
   339 def mycopytree(src, dst):
       
   340     """
       
   341     Copy content of a directory to an other, omit hidden files
       
   342     @param src: source directory
       
   343     @param dst: destination directory
       
   344     """
       
   345     for i in os.listdir(src):
       
   346         if not i.startswith('.'):
       
   347             srcpath = os.path.join(src,i)
       
   348             dstpath = os.path.join(dst,i)
       
   349             if os.path.isdir(srcpath):
       
   350                 os.makedirs(dstpath)
       
   351                 mycopytree(srcpath, dstpath)
       
   352             elif os.path.isfile(srcpath):
       
   353                 shutil.copy2(srcpath, dstpath)
       
   354 
       
   355 class LPCPluginsRoot(PluginsRoot):
       
   356 
       
   357     PlugChildsTypes = [("LPCBus", LPCBus, "LPC bus")]
       
   358 
       
   359     PluginMethods = [
       
   360         {"bitmap" : opjimg("Build"),
       
   361          "name" : _("Build"),
       
   362          "tooltip" : _("Build project into build folder"),
       
   363          "method" : "_build"},
       
   364         {"bitmap" : opjimg("Clean"),
       
   365          "name" : _("Clean"),
       
   366          "enabled" : False,
       
   367          "tooltip" : _("Clean project build folder"),
       
   368          "method" : "_Clean"},
       
   369     ]
       
   370 
       
   371     def GetProjectName(self):
       
   372         return self.Project.getname()
       
   373 
       
   374     def GetDefaultTarget(self):
       
   375         target = self.Classes["BeremizRoot_TargetType"]()
       
   376         target_value = self.Classes["TargetType_Makefile"]()
       
   377         target_value.setBuildPath(self.BuildPath)
       
   378         target.setcontent({"name": "Makefile", "value": target_value})
       
   379         return target
       
   380      
       
   381     def SetProjectName(self, name):
       
   382         return self.Project.setname(name)
       
   383 
       
   384     # Update a PLCOpenEditor Pou variable name
       
   385     def UpdateProjectVariableName(self, old_name, new_name):
       
   386         self.Project.updateElementName(old_name, new_name)
       
   387         self.BufferProject()
       
   388 
       
   389     def RemoveProjectVariableByAddress(self, address):
       
   390         self.Project.removeVariableByAddress(address)
       
   391         self.BufferProject()
       
   392 
       
   393     def RemoveProjectVariableByFilter(self, leading):
       
   394         self.Project.removeVariableByFilter(leading)
       
   395         self.BufferProject()
       
   396 
       
   397     def LoadProject(self, ProjectPath, BuildPath=None):
       
   398         """
       
   399         Load a project XML file
       
   400         @param ProjectPath: path of the project xml file
       
   401         """
       
   402         # Load PLCOpen file
       
   403         result = self.OpenXMLFile(ProjectPath)
       
   404         if result:
       
   405             return result
       
   406         # Change XSD into class members
       
   407         self._AddParamsMembers()
       
   408         self.PluggedChilds = {}
       
   409         # Keep track of the root plugin (i.e. project path)
       
   410         self.ProjectPath = ProjectPath
       
   411 
       
   412         self.BuildPath = tempfile.mkdtemp()
       
   413         if BuildPath is not None:
       
   414             mycopytree(BuildPath, self.BuildPath)
       
   415         
       
   416         self.RefreshPluginsBlockLists()
       
   417         
       
   418         if os.path.exists(self._getBuildPath()):
       
   419             self.EnableMethod("_Clean", True)
       
   420         
       
   421     def SaveProject(self):
       
   422         self.SaveXMLFile(self.ProjectPath)
       
   423 
       
   424 #-------------------------------------------------------------------------------
       
   425 #                              LPCBeremiz Class
       
   426 #-------------------------------------------------------------------------------
       
   427 
       
   428 class LPCBeremiz(Beremiz):
       
   429     
       
   430     def _init_coll_FileMenu_Items(self, parent):
       
   431         AppendMenu(parent, help='', id=wx.ID_SAVE,
       
   432               kind=wx.ITEM_NORMAL, text=_(u'Save\tCTRL+S'))
       
   433         AppendMenu(parent, help='', id=wx.ID_CLOSE,
       
   434               kind=wx.ITEM_NORMAL, text=_(u'Close Tab\tCTRL+W'))
       
   435         parent.AppendSeparator()
       
   436         AppendMenu(parent, help='', id=wx.ID_PAGE_SETUP,
       
   437               kind=wx.ITEM_NORMAL, text=_(u'Page Setup'))
       
   438         AppendMenu(parent, help='', id=wx.ID_PREVIEW,
       
   439               kind=wx.ITEM_NORMAL, text=_(u'Preview'))
       
   440         AppendMenu(parent, help='', id=wx.ID_PRINT,
       
   441               kind=wx.ITEM_NORMAL, text=_(u'Print'))
       
   442         parent.AppendSeparator()
       
   443         AppendMenu(parent, help='', id=wx.ID_PROPERTIES,
       
   444               kind=wx.ITEM_NORMAL, text=_(u'Properties'))
       
   445         parent.AppendSeparator()
       
   446         AppendMenu(parent, help='', id=wx.ID_EXIT,
       
   447               kind=wx.ITEM_NORMAL, text=_(u'Quit\tCTRL+Q'))
       
   448         
       
   449         self.Bind(wx.EVT_MENU, self.OnSaveProjectMenu, id=wx.ID_SAVE)
       
   450         self.Bind(wx.EVT_MENU, self.OnCloseTabMenu, id=wx.ID_CLOSE)
       
   451         self.Bind(wx.EVT_MENU, self.OnPageSetupMenu, id=wx.ID_PAGE_SETUP)
       
   452         self.Bind(wx.EVT_MENU, self.OnPreviewMenu, id=wx.ID_PREVIEW)
       
   453         self.Bind(wx.EVT_MENU, self.OnPrintMenu, id=wx.ID_PRINT)
       
   454         self.Bind(wx.EVT_MENU, self.OnPropertiesMenu, id=wx.ID_PROPERTIES)
       
   455         self.Bind(wx.EVT_MENU, self.OnQuitMenu, id=wx.ID_EXIT)
       
   456     
       
   457     def _init_ctrls(self, prnt):
       
   458         IDEFrame._init_ctrls(self, prnt)
       
   459         
       
   460         self.Bind(wx.EVT_MENU, self.OnOpenWidgetInspector, id=ID_BEREMIZINSPECTOR)
       
   461         accel = wx.AcceleratorTable([wx.AcceleratorEntry(wx.ACCEL_CTRL|wx.ACCEL_ALT, ord('I'), ID_BEREMIZINSPECTOR)])
       
   462         self.SetAcceleratorTable(accel)
       
   463         
       
   464         self.PLCConfig = wx.ScrolledWindow(id=ID_BEREMIZPLCCONFIG,
       
   465               name='PLCConfig', parent=self.LeftNoteBook, pos=wx.Point(0, 0),
       
   466               size=wx.Size(-1, -1), style=wx.TAB_TRAVERSAL|wx.SUNKEN_BORDER|wx.HSCROLL|wx.VSCROLL)
       
   467         self.PLCConfig.SetBackgroundColour(wx.WHITE)
       
   468         self.PLCConfig.Bind(wx.EVT_LEFT_DOWN, self.OnPanelLeftDown)
       
   469         self.PLCConfig.Bind(wx.EVT_SIZE, self.OnMoveWindow)
       
   470         self.LeftNoteBook.InsertPage(0, self.PLCConfig, _("Topology"), True)
       
   471         
       
   472         self.LogConsole = wx.TextCtrl(id=ID_BEREMIZLOGCONSOLE, value='',
       
   473                   name='LogConsole', parent=self.BottomNoteBook, pos=wx.Point(0, 0),
       
   474                   size=wx.Size(0, 0), style=wx.TE_MULTILINE|wx.TE_RICH2)
       
   475         self.LogConsole.Bind(wx.EVT_LEFT_DCLICK, self.OnLogConsoleDClick)
       
   476         self.BottomNoteBook.AddPage(self.LogConsole, _("Log Console"))
       
   477         
       
   478         self._init_beremiz_sizers()
       
   479 
       
   480     def OnCloseFrame(self, event):
       
   481         global frame, lpcberemiz_cmd
       
   482         frame = None
       
   483         self.PluginRoot.ResetAppFrame(lpcberemiz_cmd.Log)
       
   484         
       
   485         self.KillLocalRuntime()
       
   486         
       
   487         event.Skip()
       
   488 
       
   489     def RefreshFileMenu(self):
       
   490         if self.PluginRoot is not None:
       
   491             selected = self.TabsOpened.GetSelection()
       
   492             if selected >= 0:
       
   493                 graphic_viewer = isinstance(self.TabsOpened.GetPage(selected), Viewer)
       
   494             else:
       
   495                 graphic_viewer = False
       
   496             if self.TabsOpened.GetPageCount() > 0:
       
   497                 self.FileMenu.Enable(wx.ID_CLOSE, True)
       
   498                 if graphic_viewer:
       
   499                     self.FileMenu.Enable(wx.ID_PREVIEW, True)
       
   500                     self.FileMenu.Enable(wx.ID_PRINT, True)
       
   501                 else:
       
   502                     self.FileMenu.Enable(wx.ID_PREVIEW, False)
       
   503                     self.FileMenu.Enable(wx.ID_PRINT, False)
       
   504             else:
       
   505                 self.FileMenu.Enable(wx.ID_CLOSE, False)
       
   506                 self.FileMenu.Enable(wx.ID_PREVIEW, False)
       
   507                 self.FileMenu.Enable(wx.ID_PRINT, False)
       
   508             self.FileMenu.Enable(wx.ID_PAGE_SETUP, True)
       
   509             self.FileMenu.Enable(wx.ID_SAVE, True)
       
   510             self.FileMenu.Enable(wx.ID_PROPERTIES, True)
       
   511         else:
       
   512             self.FileMenu.Enable(wx.ID_CLOSE, False)
       
   513             self.FileMenu.Enable(wx.ID_PAGE_SETUP, False)
       
   514             self.FileMenu.Enable(wx.ID_PREVIEW, False)
       
   515             self.FileMenu.Enable(wx.ID_PRINT, False)
       
   516             self.FileMenu.Enable(wx.ID_SAVE, False)
       
   517             self.FileMenu.Enable(wx.ID_PROPERTIES, False)
       
   518         
       
   519     def RefreshPLCParams(self):
       
   520         self.Freeze()
       
   521         self.ClearSizer(self.PLCParamsSizer)
       
   522         
       
   523         if self.PluginRoot is not None:    
       
   524             plcwindow = wx.Panel(self.PLCConfig, -1, size=wx.Size(-1, -1))
       
   525             if self.PluginRoot.PlugTestModified():
       
   526                 bkgdclr = CHANGED_TITLE_COLOUR
       
   527             else:
       
   528                 bkgdclr = TITLE_COLOUR
       
   529                 
       
   530             if self.PluginRoot not in self.PluginInfos:
       
   531                 self.PluginInfos[self.PluginRoot] = {"right_visible" : False}
       
   532             
       
   533             plcwindow.SetBackgroundColour(TITLE_COLOUR)
       
   534             plcwindow.Bind(wx.EVT_LEFT_DOWN, self.OnPanelLeftDown)
       
   535             self.PLCParamsSizer.AddWindow(plcwindow, 0, border=0, flag=wx.GROW)
       
   536             
       
   537             plcwindowsizer = wx.BoxSizer(wx.HORIZONTAL)
       
   538             plcwindow.SetSizer(plcwindowsizer)
       
   539             
       
   540             st = wx.StaticText(plcwindow, -1)
       
   541             st.SetFont(wx.Font(faces["size"], wx.DEFAULT, wx.NORMAL, wx.BOLD, faceName = faces["helv"]))
       
   542             st.SetLabel(self.PluginRoot.GetProjectName())
       
   543             plcwindowsizer.AddWindow(st, 0, border=5, flag=wx.ALL|wx.ALIGN_CENTER)
       
   544             
       
   545             plcwindowmainsizer = wx.BoxSizer(wx.VERTICAL)
       
   546             plcwindowsizer.AddSizer(plcwindowmainsizer, 0, border=5, flag=wx.ALL)
       
   547             
       
   548             plcwindowbuttonsizer = wx.BoxSizer(wx.HORIZONTAL)
       
   549             plcwindowmainsizer.AddSizer(plcwindowbuttonsizer, 0, border=0, flag=wx.ALIGN_CENTER)
       
   550             
       
   551             msizer = self.GenerateMethodButtonSizer(self.PluginRoot, plcwindow, not self.PluginInfos[self.PluginRoot]["right_visible"])
       
   552             plcwindowbuttonsizer.AddSizer(msizer, 0, border=0, flag=wx.GROW)
       
   553             
       
   554         self.PLCConfigMainSizer.Layout()
       
   555         self.RefreshScrollBars()
       
   556         self.Thaw()
       
   557 
       
   558     def GenerateTreeBranch(self, plugin):
       
   559         leftwindow = wx.Panel(self.PLCConfig, -1, size=wx.Size(-1, -1))
       
   560         if plugin.PlugTestModified():
       
   561             bkgdclr=CHANGED_WINDOW_COLOUR
       
   562         else:
       
   563             bkgdclr=WINDOW_COLOUR
       
   564 
       
   565         leftwindow.SetBackgroundColour(bkgdclr)
       
   566         
       
   567         if plugin not in self.PluginInfos:
       
   568             self.PluginInfos[plugin] = {"expanded" : False, "left_visible" : False, "right_visible" : False}
       
   569             
       
   570         self.PluginInfos[plugin]["children"] = plugin.IECSortedChilds()
       
   571         plugin_infos = plugin.GetVariableLocationTree()
       
   572         plugin_locations = []
       
   573         if len(self.PluginInfos[plugin]["children"]) == 0:
       
   574             plugin_locations = plugin_infos["children"]
       
   575             if not self.PluginInfos[plugin].has_key("locations_infos"):
       
   576                 self.PluginInfos[plugin]["locations_infos"] = {"root": {"expanded" : False}}
       
   577                 
       
   578             self.PluginInfos[plugin]["locations_infos"]["root"]["children"] = []
       
   579         
       
   580         self.PluginTreeSizer.AddWindow(leftwindow, 0, border=0, flag=wx.GROW)
       
   581         
       
   582         leftwindowsizer = wx.BoxSizer(wx.HORIZONTAL)
       
   583         leftwindow.SetSizer(leftwindowsizer)
       
   584                 
       
   585         st = wx.StaticText(leftwindow, -1)
       
   586         st.SetFont(wx.Font(faces["size"], wx.DEFAULT, wx.NORMAL, wx.BOLD, faceName = faces["helv"]))
       
   587         st.SetLabel(plugin.GetFullIEC_Channel())
       
   588         leftwindowsizer.AddWindow(st, 0, border=5, flag=wx.RIGHT)
       
   589         
       
   590         expandbutton_id = wx.NewId()
       
   591         expandbutton = wx.lib.buttons.GenBitmapToggleButton(id=expandbutton_id, bitmap=wx.Bitmap(Bpath( 'images', 'plus.png')),
       
   592               name='ExpandButton', parent=leftwindow, pos=wx.Point(0, 0),
       
   593               size=wx.Size(13, 13), style=wx.NO_BORDER)
       
   594         expandbutton.labelDelta = 0
       
   595         expandbutton.SetBezelWidth(0)
       
   596         expandbutton.SetUseFocusIndicator(False)
       
   597         expandbutton.SetBitmapSelected(wx.Bitmap(Bpath( 'images', 'minus.png')))
       
   598             
       
   599         if len(self.PluginInfos[plugin]["children"]) > 0:
       
   600             expandbutton.SetToggle(self.PluginInfos[plugin]["expanded"])
       
   601             def togglebutton(event):
       
   602                 if expandbutton.GetToggle():
       
   603                     self.ExpandPlugin(plugin)
       
   604                 else:
       
   605                     self.CollapsePlugin(plugin)
       
   606                 self.PluginInfos[plugin]["expanded"] = expandbutton.GetToggle()
       
   607                 self.PLCConfigMainSizer.Layout()
       
   608                 self.RefreshScrollBars()
       
   609                 event.Skip()
       
   610             expandbutton.Bind(wx.EVT_BUTTON, togglebutton, id=expandbutton_id)
       
   611         elif len(plugin_locations) > 0:
       
   612             locations_infos = self.PluginInfos[plugin]["locations_infos"]
       
   613             expandbutton.SetToggle(locations_infos["root"]["expanded"])
       
   614             def togglebutton(event):
       
   615                 if expandbutton.GetToggle():
       
   616                     self.ExpandLocation(locations_infos, "root")
       
   617                 else:
       
   618                     self.CollapseLocation(locations_infos, "root")
       
   619                 self.PluginInfos[plugin]["expanded"] = expandbutton.GetToggle()
       
   620                 locations_infos["root"]["expanded"] = expandbutton.GetToggle()
       
   621                 self.PLCConfigMainSizer.Layout()
       
   622                 self.RefreshScrollBars()
       
   623                 event.Skip()
       
   624             expandbutton.Bind(wx.EVT_BUTTON, togglebutton, id=expandbutton_id)
       
   625         else:
       
   626             expandbutton.Enable(False)
       
   627         leftwindowsizer.AddWindow(expandbutton, 0, border=5, flag=wx.RIGHT|wx.ALIGN_CENTER_VERTICAL)
       
   628         
       
   629         sb = wx.StaticBitmap(leftwindow, -1)
       
   630         icon = plugin_infos.get("icon", None)
       
   631         if icon is None:
       
   632             icon = os.path.join(base_folder, "plcopeneditor", 'Images', '%s.png' % self.LOCATION_BITMAP[plugin_infos["type"]])
       
   633         sb.SetBitmap(wx.Bitmap(icon))
       
   634         leftwindowsizer.AddWindow(sb, 0, border=5, flag=wx.RIGHT|wx.ALIGN_CENTER_VERTICAL)
       
   635         
       
   636         st_id = wx.NewId()
       
   637         st = wx.StaticText(leftwindow, st_id, size=wx.DefaultSize, style=wx.NO_BORDER)
       
   638         st.SetFont(wx.Font(faces["size"] * 0.75, wx.DEFAULT, wx.NORMAL, wx.BOLD, faceName = faces["helv"]))
       
   639         st.SetLabel(plugin.MandatoryParams[1].getName())
       
   640         leftwindowsizer.AddWindow(st, 0, border=5, flag=wx.RIGHT|wx.ALIGN_CENTER_VERTICAL)
       
   641         
       
   642         rightwindow = wx.Panel(self.PLCConfig, -1, size=wx.Size(-1, -1))
       
   643         rightwindow.SetBackgroundColour(bkgdclr)
       
   644         
       
   645         self.PluginTreeSizer.AddWindow(rightwindow, 0, border=0, flag=wx.GROW)
       
   646 
       
   647         self.PluginInfos[plugin]["left"] = leftwindow
       
   648         self.PluginInfos[plugin]["right"] = rightwindow
       
   649         for child in self.PluginInfos[plugin]["children"]:
       
   650             self.GenerateTreeBranch(child)
       
   651             if not self.PluginInfos[child]["expanded"]:
       
   652                 self.CollapsePlugin(child)
       
   653         if len(plugin_locations) > 0:
       
   654             locations_infos = self.PluginInfos[plugin]["locations_infos"]
       
   655             for location in plugin_locations:
       
   656                 locations_infos["root"]["children"].append("root.%s" % location["name"])
       
   657                 self.GenerateLocationTreeBranch(locations_infos, "root", location)
       
   658             if not locations_infos["root"]["expanded"]:
       
   659                 self.CollapseLocation(locations_infos, "root")
       
   660 
       
   661 frame = None
       
   662 
       
   663 def BeremizStartProc(plugin_root):
       
   664     global frame
       
   665 
       
   666     app = wx.PySimpleApp()
       
   667     app.SetAppName('beremiz')
       
   668     wx.InitAllImageHandlers()
       
   669     
       
   670     # Get the english language
       
   671     langid = wx.LANGUAGE_ENGLISH
       
   672     # Import module for internationalization
       
   673     import gettext
       
   674     import __builtin__
       
   675     
       
   676     # Define locale for wx
       
   677     loc = wx.Locale(langid)
       
   678     for localedir in PseudoLocale.LocaleDirs:
       
   679         loc.AddCatalogLookupPathPrefix(localedir)
       
   680     for domain in PseudoLocale.Domains:
       
   681         loc.AddCatalog(domain)
       
   682     
       
   683     __builtin__.__dict__['_'] = wx.GetTranslation#unicode_translation
       
   684     
       
   685     # Install a exception handle for bug reports
       
   686     AddExceptHook(os.getcwd(),__version__)
       
   687 
       
   688     frame = LPCBeremiz(None, plugin_root=plugin_root, debug=False)
       
   689     plugin_root.SetAppFrame(frame, frame.Log)
       
   690     frame.Show()
       
   691     
       
   692     app.MainLoop()
       
   693 
       
   694 class StdoutPseudoFile:
       
   695     """ Base class for file like objects to facilitate StdOut for the Shell."""
       
   696     def write(self, s, style = None):
       
   697         if s != '':
       
   698             print s
       
   699         
       
   700     def write_warning(self, s):
       
   701         self.write(s)
       
   702 
       
   703     def write_error(self, s):
       
   704         self.write(s)
       
   705 
       
   706     def flush(self):
       
   707         pass
       
   708     
       
   709     def isatty(self):
       
   710         return false
       
   711 
       
   712 if __name__ == '__main__':
       
   713     
       
   714     from threading import Thread, Timer
       
   715     import cmd
       
   716 
       
   717     class LPCBeremiz_Cmd(cmd.Cmd):
       
   718         
       
   719         prompt = ""
       
   720         Log = StdoutPseudoFile()
       
   721         RefreshTimer = None
       
   722         
       
   723         def __init__(self, projectOpen, buildpath):
       
   724             cmd.Cmd.__init__(self)
       
   725             self.PluginRoot = LPCPluginsRoot(None, self.Log)
       
   726             if projectOpen is not None and os.path.isfile(projectOpen):
       
   727                 result = self.PluginRoot.LoadProject(projectOpen, buildpath)
       
   728                 if result:
       
   729                     print "Error: Invalid project directory", result
       
   730             else:
       
   731                 print "Error: No such file or directory"
       
   732             
       
   733         def RestartTimer(self):
       
   734             if self.RefreshTimer is not None:
       
   735                 self.RefreshTimer.cancel()
       
   736             self.RefreshTimer = Timer(0.1, self.Refresh)
       
   737             self.RefreshTimer.start()
       
   738         
       
   739         def Exit(self):
       
   740             self.Close()
       
   741             return True
       
   742         
       
   743         def do_EOF(self, line):
       
   744             return self.Exit()
       
   745         
       
   746         def Show(self):
       
   747             beremiz_thread=Thread(target=BeremizStartProc, args=[self.PluginRoot])
       
   748             beremiz_thread.start()
       
   749         
       
   750         def Refresh(self):
       
   751             global frame
       
   752             if frame is not None:
       
   753                 wx.CallAfter(frame._Refresh, TITLE, INSTANCESTREE, FILEMENU, EDITMENU)
       
   754                 wx.CallAfter(frame.RefreshEditor)
       
   755                 wx.CallAfter(frame.RefreshAll)
       
   756         
       
   757         def Close(self):
       
   758             global frame
       
   759             
       
   760             self.PluginRoot.ResetAppFrame(self.Log)
       
   761             if frame is not None:
       
   762                 wx.CallAfter(frame.Close)
       
   763         
       
   764         def Compile(self):
       
   765             if wx.GetApp() is None:
       
   766                 self.PluginRoot._build()
       
   767             else:
       
   768                 wx.CallAfter(self.PluginRoot._build)
       
   769         
       
   770         def SetProjectName(self, name):
       
   771             self.PluginRoot.SetProjectName(name)
       
   772             self.RestartTimer()
       
   773         
       
   774         def AddBus(self, iec_channel, name, icon=None):
       
   775             for child in self.PluginRoot.IterChilds():
       
   776                 if child.BaseParams.getName() == name:
       
   777                     return "Error: A bus named %s already exists" % name
       
   778                 elif child.BaseParams.getIEC_Channel() == iec_channel:
       
   779                     return "Error: A bus with IEC_channel %d already exists" % iec_channel
       
   780             bus = self.PluginRoot.PlugAddChild(name, "LPCBus", iec_channel)
       
   781             if bus is None:
       
   782                 return "Error: Unable to create bus"
       
   783             bus.SetIcon(icon)
       
   784             self.RestartTimer()
       
   785         
       
   786         def RenameBus(self, iec_channel, name):
       
   787             bus = self.PluginRoot.GetChildByIECLocation((iec_channel,))
       
   788             if bus is None:
       
   789                 return "Error: No bus found"
       
   790             for child in self.PluginRoot.IterChilds():
       
   791                 if child != bus and child.BaseParams.getName() == name:
       
   792                     return "Error: A bus named %s already exists" % name
       
   793             bus.BaseParams.setName(name)
       
   794             self.RestartTimer()
       
   795         
       
   796         def ChangeBusIECChannel(self, old_iec_channel, new_iec_channel):
       
   797             bus = self.PluginRoot.GetChildByIECLocation((old_iec_channel,))
       
   798             if bus is None:
       
   799                 return "Error: No bus found"
       
   800             for child in self.PluginRoot.IterChilds():
       
   801                 if child != bus and child.BaseParams.getIEC_Channel() == new_iec_channel:
       
   802                     return "Error: A bus with IEC_channel %d already exists" % new_iec_channel
       
   803             self.PluginRoot.UpdateProjectVariableLocation(str(old_iec_channel), str(new_iec_channel))
       
   804             bus.BaseParams.setIEC_Channel(new_iec_channel)
       
   805             self.RestartTimer()
       
   806         
       
   807         def RemoveBus(self, iec_channel):
       
   808             bus = self.PluginRoot.GetChildByIECLocation((iec_channel,))
       
   809             if bus is None:
       
   810                 return "Error: No bus found"
       
   811             self.PluginRoot.RemoveProjectVariableByFilter(str(iec_channel))
       
   812             self.PluginRoot.PluggedChilds["LPCBus"].remove(bus)
       
   813             self.RestartTimer()
       
   814     
       
   815         def AddModule(self, parent, iec_channel, name, icon=None):
       
   816             module = self.PluginRoot.GetChildByIECLocation(parent)
       
   817             if module is None:
       
   818                 return "Error: No parent found"
       
   819             for child in _GetModuleChildren(module):
       
   820                 if child["name"] == name:
       
   821                     return "Error: A module named %s already exists" % name
       
   822                 elif child["IEC_Channel"] == iec_channel:
       
   823                     return "Error: A module with IEC_channel %d already exists" % iec_channel 
       
   824             _GetLastModuleGroup(module).append({"name": name, 
       
   825                                                 "type": LOCATION_MODULE, 
       
   826                                                 "IEC_Channel": iec_channel, 
       
   827                                                 "icon": icon, 
       
   828                                                 "children": []})
       
   829             self.RestartTimer()
       
   830     
       
   831         def RenameModule(self, iec_location, name):
       
   832             module = self.PluginRoot.GetChildByIECLocation(iec_location)
       
   833             if module is None:
       
   834                 return "Error: No module found"
       
   835             parent = self.PluginRoot.GetChildByIECLocation(iec_location[:-1])
       
   836             if parent is self.PluginRoot:
       
   837                 return "Error: No module found"
       
   838             if module["name"] != name:
       
   839                 for child in _GetModuleChildren(parent):
       
   840                     if child["name"] == name:
       
   841                         return "Error: A module named %s already exists" % name
       
   842                 module["name"] = name
       
   843             self.RestartTimer()
       
   844     
       
   845         def ChangeModuleIECChannel(self, old_iec_location, new_iec_channel):
       
   846             module = self.PluginRoot.GetChildByIECLocation(old_iec_location)
       
   847             if module is None:
       
   848                 return "Error: No module found"
       
   849             parent = self.PluginRoot.GetChildByIECLocation(old_iec_location[:-1])
       
   850             if parent is self.PluginRoot:
       
   851                 return "Error: No module found"
       
   852             if module["IEC_Channel"] != new_iec_channel:
       
   853                 for child in _GetModuleChildren(parent):
       
   854                     if child["IEC_Channel"] == new_iec_channel:
       
   855                         return "Error: A module with IEC_channel %d already exists" % new_iec_channel
       
   856             self.PluginRoot.UpdateProjectVariableLocation(".".join(map(str, old_iec_location)), ".".join(map(str, old_iec_location[:1] + (new_iec_channel,))))
       
   857             module["IEC_Channel"] = new_iec_channel
       
   858             self.RestartTimer()
       
   859     
       
   860         def RemoveModule(self, parent, iec_channel):
       
   861             module = self.PluginRoot.GetChildByIECLocation(parent)
       
   862             if module is None:
       
   863                 return "Error: No parent found"
       
   864             child = _GetModuleBySomething(module, "IEC_Channel", (iec_channel,))
       
   865             if child is None:
       
   866                 return "Error: No module found"
       
   867             self.PluginRoot.RemoveProjectVariableByFilter(".".join(map(str, parent + (iec_channel,))))
       
   868             _RemoveModuleChild(module, child)
       
   869             self.RestartTimer()
       
   870         
       
   871         def StartGroup(self, parent, name, icon=None):
       
   872             module = self.PluginRoot.GetChildByIECLocation(parent)
       
   873             if module is None:
       
   874                 return "Error: No parent found"
       
   875             for child in module["children"]:
       
   876                 if child["type"] == LOCATION_GROUP and child["name"] == name:
       
   877                     return "Error: A group named %s already exists" % name
       
   878             module["children"].append({"name": name, 
       
   879                                       "type": LOCATION_GROUP, 
       
   880                                       "icon": icon, 
       
   881                                       "children": []})
       
   882             self.RestartTimer()
       
   883     
       
   884         def AddVariable(self, parent, location, name, direction, type, dcode, rcode, pcode, description=""):
       
   885             module = self.PluginRoot.GetChildByIECLocation(parent)
       
   886             if module is None:
       
   887                 return "Error: No parent found"
       
   888             for child in _GetModuleChildren(module):
       
   889                 if child["name"] == name:
       
   890                     return "Error: A variable named %s already exists" % name
       
   891                 if child["location"] == location:
       
   892                     return "Error: A variable with location %s already exists" % ".".join(map(str, location))
       
   893             _GetLastModuleGroup(module).append({"name": name, 
       
   894                                                 "location": location, 
       
   895                                                 "type": LOCATION_TYPES[direction], 
       
   896                                                 "IEC_type": type, 
       
   897                                                 "description": description, 
       
   898                                                 "declare": dcode, 
       
   899                                                 "retrieve": rcode, 
       
   900                                                 "publish": pcode})
       
   901             self.RestartTimer()
       
   902 
       
   903         def ChangeVariableParams(self, parent, location, new_name, new_direction, new_type, new_dcode, new_rcode, new_pcode, new_description=None):
       
   904             module = self.PluginRoot.GetChildByIECLocation(parent)
       
   905             if module is None:
       
   906                 return "Error: No parent found"
       
   907             variable = None
       
   908             for child in _GetModuleChildren(module):
       
   909                 if child["location"] == location:
       
   910                     variable = child
       
   911                 elif child["name"] == new_name:
       
   912                     return "Error: A variable named %s already exists" % new_name
       
   913             if variable is None:
       
   914                 return "Error: No variable found"
       
   915             if variable["name"] != new_name:
       
   916                 self.PluginRoot.UpdateProjectVariableName(variable["name"], new_name)
       
   917                 variable["name"] = new_name
       
   918             variable["type"] = LOCATION_TYPES[new_direction]
       
   919             variable["IEC_type"] = new_type
       
   920             variable["declare"] = new_dcode
       
   921             variable["retrieve"] = new_rcode
       
   922             variable["publish"] = new_pcode
       
   923             if new_description is not None:
       
   924                 variable["description"] = new_description
       
   925             self.RestartTimer()
       
   926     
       
   927         def RemoveVariable(self, parent, location):
       
   928             module = self.PluginRoot.GetChildByIECLocation(parent)
       
   929             if module is None:
       
   930                 return "Error: No parent found"
       
   931             child = _GetModuleVariable(module, location)
       
   932             if child is None:
       
   933                 return "Error: No variable found"
       
   934             size = LOCATION_SIZES[self.PluginRoot.GetBaseType(child["IEC_type"])]
       
   935             address = "%" + LOCATION_DIRS[child["type"]] + size + ".".join(map(str, parent + location))
       
   936             self.PluginRoot.RemoveProjectVariableByAddress(address)
       
   937             _RemoveModuleChild(module, child)
       
   938             self.RestartTimer()
       
   939         
       
   940     def location(loc):
       
   941         return tuple(map(int, loc.split(".")))
       
   942     
       
   943     def GetCmdFunction(function, arg_types, opt=0):
       
   944         arg_number = len(arg_types)
       
   945         def CmdFunction(self, line):
       
   946             args_toks = line.split('"')
       
   947             if len(args_toks) % 2 == 0:
       
   948                 print "Error: Invalid command"
       
   949                 return
       
   950             args = []
       
   951             for num, arg in enumerate(args_toks):
       
   952                 if num % 2 == 0:
       
   953                     stripped = arg.strip()
       
   954                     if stripped:
       
   955                         args.extend(stripped.split(" "))
       
   956                 else:
       
   957                     args.append(arg)
       
   958             number = None
       
   959             extra = ""
       
   960             if opt == 0 and len(args) != arg_number:
       
   961                 number = arg_number
       
   962             elif len(args) > arg_number:
       
   963                 number = arg_number
       
   964                 extra = " at most"
       
   965             elif len(args) < arg_number - opt:
       
   966                 number = arg_number - opt
       
   967                 extra = " at least"
       
   968             if number is not None:
       
   969                 if number == 0:
       
   970                     print "Error: No argument%s expected" % extra
       
   971                 elif number == 1:
       
   972                     print "Error: 1 argument%s expected" % extra
       
   973                 else:
       
   974                     print "Error: %d arguments%s expected" % (number, extra)
       
   975                 return
       
   976             for num, arg in enumerate(args):
       
   977                 try:
       
   978                     args[num] = arg_types[num](arg)
       
   979                 except:
       
   980                     print "Error: Invalid value for argument %d" % (num + 1)
       
   981                     return
       
   982             res = getattr(self, function)(*args)
       
   983             if isinstance(res, (StringType, UnicodeType)):
       
   984                 print res
       
   985                 return False
       
   986             else:
       
   987                 return res
       
   988         return CmdFunction
       
   989     
       
   990     for function, (arg_types, opt) in {"Exit": ([], 0),
       
   991                                        "Show": ([], 0),
       
   992                                        "Refresh": ([], 0),
       
   993                                        "Close": ([], 0),
       
   994                                        "Compile": ([], 0),
       
   995                                        "SetProjectName": ([str], 0),
       
   996                                        "AddBus": ([int, str, str], 1),
       
   997                                        "RenameBus": ([int, str], 0),
       
   998                                        "ChangeBusIECChannel": ([int, int], 0),
       
   999                                        "RemoveBus": ([int], 0),
       
  1000                                        "AddModule": ([location, int, str, str], 1), 
       
  1001                                        "RenameModule": ([location, str], 0),
       
  1002                                        "ChangeModuleIECChannel": ([location, int], 0),
       
  1003                                        "RemoveModule": ([location, int], 0),
       
  1004                                        "StartGroup": ([location, str, str], 1),
       
  1005                                        "AddVariable": ([location, location, str, str, str, str, str, str, str], 1),
       
  1006                                        "ChangeVariableParams": ([location, location, str, str, str, str, str, str, str], 1),
       
  1007                                        "RemoveVariable": ([location, location], 0)}.iteritems():
       
  1008         
       
  1009         setattr(LPCBeremiz_Cmd, "do_%s" % function, GetCmdFunction(function, arg_types, opt))
       
  1010     
       
  1011     lpcberemiz_cmd = LPCBeremiz_Cmd(projectOpen, buildpath)
       
  1012     lpcberemiz_cmd.cmdloop()
       
  1013