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 |