plugins/c_ext/c_ext.py
changeset 45 00acf2162135
parent 31 33b38700d0db
child 47 fd45c291fed0
equal deleted inserted replaced
44:1f5407c0263f 45:00acf2162135
     1 import wx
     1 import wx
     2 import wx.stc as stc
     2 import wx.stc as stc
     3 import os, sys, shutil
     3 import os, sys, shutil
     4 from CppSTC import CppSTC
     4 from CppSTC import CppSTC
     5 from plugger import PlugTemplate
     5 from plugger import PlugTemplate
       
     6 import tempfile
     6 
     7 
     7 class _Cfile:
     8 class _Cfile:
     8     XSD = """<?xml version="1.0" encoding="ISO-8859-1" ?>
     9     XSD = """<?xml version="1.0" encoding="ISO-8859-1" ?>
     9     <xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema">
    10     <xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema">
    10       <xsd:element name="C_File">
    11       <xsd:element name="C_Extension">
    11         <xsd:complexType>
    12         <xsd:complexType>
    12           <xsd:attribute name="FileName" type="xsd:string" use="required" default="myfile.c"/>
    13           <xsd:attribute name="C_Files" type="xsd:string" use="required" default="myfile.c"/>
       
    14           <xsd:attribute name="CFLAGS" type="xsd:string" use="required"/>
       
    15           <xsd:attribute name="LDFLAGS" type="xsd:string" use="required"/>
    13         </xsd:complexType>
    16         </xsd:complexType>
    14       </xsd:element>
    17       </xsd:element>
    15     </xsd:schema>
    18     </xsd:schema>
    16     """
    19     """
    17     def __init__(self):
    20     def __init__(self):
    18         if not os.path.isfile(self.CFileName()):
    21         self.CheckCFilesExist()
    19             f = open(self.CFileName(), 'w')
    22         
    20             f.write("/*Empty*/")
    23     def CheckCFilesExist(self):
       
    24         for CFile in self.CFileNames():
       
    25             if not os.path.isfile(CFile):
       
    26                 f = open(CFile, 'w')
       
    27                 f.write("/*Empty*/")
       
    28                 f.close()
    21 
    29 
    22     def CFileName(self):
    30     def CFileBaseNames(self):
    23         return os.path.join(self.PlugPath(),self.C_File.getFileName())
    31         """
       
    32         Returns list of C files base names, out of C_Extension.C_Files, coma separated list
       
    33         """
       
    34         return map(str.strip,str(self.C_Extension.getC_Files()).split(','))
       
    35 
       
    36     def CFileName(self, fn):
       
    37         return os.path.join(self.PlugPath(),fn)
       
    38 
       
    39     def CFileNames(self):
       
    40         """
       
    41         Returns list of full C files paths, out of C_Extension.C_Files, coma separated list
       
    42         """
       
    43         return map(self.CFileName, self.CFileBaseNames())
    24 
    44 
    25     def SetParamsAttribute(self, path, value, logger):
    45     def SetParamsAttribute(self, path, value, logger):
    26         oldname = self.CFileName()
    46         """
       
    47         Take actions if C_Files changed
       
    48         """
       
    49         # Get a C files list before changes
       
    50         oldnames = self.CFileNames()
       
    51         # Apply changes
    27         res = PlugTemplate.SetParamsAttribute(self, path, value, logger)
    52         res = PlugTemplate.SetParamsAttribute(self, path, value, logger)
    28         if path == "C_File.FileName":
    53         # If changes was about C files,
    29             shutil.move(oldname, self.CFileName())
    54         if path == "C_Extension.C_Files":
    30             logger.write("\"%s\" renamed \"%s\"\n"%(oldname, self.CFileName()))
    55             # Create files if did not exist
       
    56             self.CheckCFilesExist()
       
    57             # Get new list
       
    58             newnames = self.CFileNames()
       
    59             # Move unused files into trash (temporary directory)
       
    60             for oldfile in oldnames:
       
    61                 if oldfile not in newnames:
       
    62                     # define new "trash" name
       
    63                     trashname = os.path.join(tempfile.gettempdir(),os.path.basename(oldfile))
       
    64                     # move the file
       
    65                     shutil.move(oldfile, trashname)
       
    66                     # warn user
       
    67                     logger.write_warning("\"%s\" moved to \"%s\"\n"%(oldfile, trashname))
    31             return value, False
    68             return value, False
    32         return res
    69         return res
    33 
    70 
    34     _View = None
    71     _Views = {}
    35     def _OpenView(self, logger):
    72     def _OpenView(self, logger):
    36         if not self._View:
    73         lst = self.CFileBaseNames()
    37             def _onclose(evt):
       
    38                 self.OnPlugSave()
       
    39                 self._View = None
       
    40                 evt.Skip()
       
    41             self._View = wx.Frame(self.GetPlugRoot().AppFrame,-1)
       
    42             self._View.Bind(wx.EVT_CLOSE, _onclose)
       
    43             ed = CppSTC(self._View, wx.NewId())
       
    44             ed.SetText(open(self.CFileName()).read())
       
    45             ed.EmptyUndoBuffer()
       
    46             ed.Colourise(0, -1)
       
    47             ed.SetMarginType(1, stc.STC_MARGIN_NUMBER)
       
    48             ed.SetMarginWidth(1, 25)
       
    49             self._View.ed = ed
       
    50 
    74 
    51             self._View.Show()
    75         dlg = wx.MultiChoiceDialog( self.GetPlugRoot().AppFrame, 
       
    76                                    "Pick some fruit from\nthis list",
       
    77                                    "wx.MultiChoiceDialog", lst)
    52 
    78 
    53     PluginMethods = [("Edit C File",_OpenView)]
    79         if (dlg.ShowModal() == wx.ID_OK):
       
    80             selections = dlg.GetSelections()
       
    81             for selected in [lst[x] for x in selections]:
       
    82                 if selected not in self._Views:
       
    83                     # keep track of selected name as static for later close
       
    84                     def _onclose(evt, sel = selected):
       
    85                         self.SaveCView(sel)
       
    86                         self._Views.pop(sel)
       
    87                         evt.Skip()
       
    88                     New_View = wx.Frame(self.GetPlugRoot().AppFrame,-1)
       
    89                     New_View.Bind(wx.EVT_CLOSE, _onclose)
       
    90                     ed = CppSTC(New_View, wx.NewId())
       
    91                     ed.SetText(open(self.CFileName(selected)).read())
       
    92                     ed.EmptyUndoBuffer()
       
    93                     ed.Colourise(0, -1)
       
    94                     ed.SetMarginType(1, stc.STC_MARGIN_NUMBER)
       
    95                     ed.SetMarginWidth(1, 25)
       
    96                     New_View.ed = ed
       
    97                     New_View.Show()
       
    98                     self._Views[selected] = New_View
    54 
    99 
       
   100         dlg.Destroy()
       
   101         
       
   102 
       
   103     PluginMethods = [("Edit C File",_OpenView), ("Import C File",_OpenView)]
       
   104 
       
   105     def SaveCView(self, name):
       
   106         f = open(self.CFileName(name),'w')
       
   107         f.write(self._Views[name].ed.GetText())
       
   108         f.close()
       
   109         
    55     def OnPlugSave(self):
   110     def OnPlugSave(self):
    56         if self._View:
   111         for name in self._Views:
    57             f = open(self.CFileName(),'w')
   112             self.SaveCView(name)
    58             f.write(self._View.ed.GetText())
       
    59         return True
   113         return True
    60 
   114 
    61     def PlugGenerate_C(self, buildpath, locations, logger):
   115     def PlugGenerate_C(self, buildpath, locations, logger):
    62         """
   116         """
    63         Generate C code
   117         Generate C code
    71             }, ...]
   125             }, ...]
    72         @return: [(C_file_name, CFLAGS),...] , LDFLAGS_TO_APPEND
   126         @return: [(C_file_name, CFLAGS),...] , LDFLAGS_TO_APPEND
    73         """
   127         """
    74         current_location = self.GetCurrentLocation()
   128         current_location = self.GetCurrentLocation()
    75         # define a unique name for the generated C file
   129         # define a unique name for the generated C file
    76         prefix = "_".join(map(lambda x:str(x), current_location))
   130         location_str = "_".join(map(lambda x:str(x), current_location))
    77         Gen_Cfile_path = os.path.join(buildpath, prefix + "_CFile.c" )
   131         res = []
    78         f = open(Gen_Cfile_path,'w')
   132         for CFile in self.CFileBaseNames():
    79         f.write("/* Header generated by Beremiz c_ext plugin */\n")
   133             Gen_Cfile_path = os.path.join(buildpath, location_str + "_" + os.path.splitext(CFile)[0] + "_CFile.c" )
    80         f.write("#include \"iec_std_lib.h\"\n")
   134             f = open(Gen_Cfile_path,'w')
    81         for loc in locations:
   135             f.write("/* Header generated by Beremiz c_ext plugin */\n")
    82             f.write(loc["IEC_TYPE"]+" "+loc["NAME"]+";\n")
   136             f.write("#include \"iec_std_lib.h\"\n")
    83         f.write("/* End of header generated by Beremiz c_ext plugin */\n")
   137             f.write("#define EXT_C_INIT __init_%s\n"%location_str)
    84         
   138             f.write("#define EXT_C_CLEANUP __init_%s\n"%location_str)
    85         return [(Gen_Cfile_path,"")],""
   139             f.write("#define EXT_C_PUBLISH __init_%s\n"%location_str)
       
   140             f.write("#define EXT_C_RETRIVE __init_%s\n"%location_str)
       
   141             for loc in locations:
       
   142                 f.write(loc["IEC_TYPE"]+" "+loc["NAME"]+";\n")
       
   143             f.write("/* End of header generated by Beremiz c_ext plugin */\n\n")
       
   144             src_file = open(self.CFileName(CFile),'r')
       
   145             f.write(src_file.read())
       
   146             src_file.close()
       
   147             f.close()
       
   148             res.append((Gen_Cfile_path,str(self.C_Extension.getCFLAGS())))
       
   149         return res,str(self.C_Extension.getLDFLAGS())
    86     
   150     
    87 class RootClass:
   151 class RootClass:
    88 
   152 
    89     PlugChildsTypes = [("C_File",_Cfile)]
   153     PlugChildsTypes = [("C_File",_Cfile)]
    90     
   154