|
1 import wx |
|
2 import os, sys |
|
3 from xml.dom import minidom |
|
4 |
|
5 from plugger import opjimg |
|
6 from plugins.python import PythonCodeTemplate |
|
7 |
|
8 class RootClass(PythonCodeTemplate): |
|
9 |
|
10 PluginMethods = [ |
|
11 {"bitmap" : opjimg("editWXGLADE"), |
|
12 "name" : _("WXGLADE GUI"), |
|
13 "tooltip" : _("Edit a WxWidgets GUI with WXGlade"), |
|
14 "method" : "_editWXGLADE"}, |
|
15 ] |
|
16 |
|
17 def _getWXGLADEpath(self): |
|
18 # define name for IEC raw code file |
|
19 return os.path.join(self.PlugPath(), "hmi.wxg") |
|
20 |
|
21 def launch_wxglade(self, options, wait=False): |
|
22 from wxglade import __file__ as fileName |
|
23 path = os.path.dirname(fileName) |
|
24 glade = os.path.join(path, 'wxglade.py') |
|
25 if wx.Platform == '__WXMSW__': |
|
26 glade = "\"%s\""%glade |
|
27 mode = {False:os.P_NOWAIT, True:os.P_WAIT}[wait] |
|
28 os.spawnv(mode, sys.executable, ["\"%s\""%sys.executable] + [glade] + options) |
|
29 |
|
30 |
|
31 def PlugGenerate_C(self, buildpath, locations): |
|
32 """ |
|
33 Return C code generated by iec2c compiler |
|
34 when _generate_softPLC have been called |
|
35 @param locations: ignored |
|
36 @return: [(C_file_name, CFLAGS),...] , LDFLAGS_TO_APPEND |
|
37 """ |
|
38 |
|
39 current_location = self.GetCurrentLocation() |
|
40 # define a unique name for the generated C file |
|
41 location_str = "_".join(map(lambda x:str(x), current_location)) |
|
42 |
|
43 runtimefile_path = os.path.join(buildpath, "runtime_%s.py"%location_str) |
|
44 runtimefile = open(runtimefile_path, 'w') |
|
45 |
|
46 hmi_frames = {} |
|
47 |
|
48 wxgfile_path=self._getWXGLADEpath() |
|
49 if os.path.exists(wxgfile_path): |
|
50 wxgfile = open(wxgfile_path, 'r') |
|
51 wxgtree = minidom.parse(wxgfile) |
|
52 wxgfile.close() |
|
53 |
|
54 for node in wxgtree.childNodes[1].childNodes: |
|
55 if node.nodeType == wxgtree.ELEMENT_NODE: |
|
56 hmi_frames[node._attrs["name"].value] = node._attrs["class"].value |
|
57 |
|
58 hmipyfile_path=os.path.join(self._getBuildPath(), "hmi.py") |
|
59 if wx.Platform == '__WXMSW__': |
|
60 wxgfile_path = "\"%s\""%wxgfile_path |
|
61 hmipyfile_path = "\"%s\""%hmipyfile_path |
|
62 self.launch_wxglade(['-o', hmipyfile_path, '-g', 'python', wxgfile_path], wait=True) |
|
63 |
|
64 hmipyfile = open(hmipyfile_path, 'r') |
|
65 runtimefile.write(hmipyfile.read()) |
|
66 hmipyfile.close() |
|
67 |
|
68 runtimefile.write(self.GetPythonCode()) |
|
69 runtimefile.write(""" |
|
70 %(declare)s |
|
71 |
|
72 def _runtime_%(location)s_begin(): |
|
73 global %(global)s |
|
74 |
|
75 def OnCloseFrame(evt): |
|
76 wx.MessageBox(_("Please stop PLC to close")) |
|
77 |
|
78 %(init)s |
|
79 |
|
80 def _runtime_%(location)s_cleanup(): |
|
81 global %(global)s |
|
82 |
|
83 %(cleanup)s |
|
84 |
|
85 """ % {"location": location_str, |
|
86 "declare": "\n".join(map(lambda x:"%s = None" % x, hmi_frames.keys())), |
|
87 "global": ",".join(hmi_frames.keys()), |
|
88 "init": "\n".join(map(lambda x: """ |
|
89 %(name)s = %(class)s(None) |
|
90 %(name)s.Bind(wx.EVT_CLOSE, OnCloseFrame) |
|
91 %(name)s.Show() |
|
92 """ % {"name": x[0], "class": x[1]}, |
|
93 hmi_frames.items())), |
|
94 "cleanup": "\n ".join(map(lambda x:"%s.Destroy()" % x, hmi_frames.keys()))}) |
|
95 runtimefile.close() |
|
96 |
|
97 return [], "", False, ("runtime_%s.py"%location_str, file(runtimefile_path,"rb")) |
|
98 |
|
99 def _editWXGLADE(self): |
|
100 wxg_filename = self._getWXGLADEpath() |
|
101 if not os.path.exists(wxg_filename): |
|
102 hmi_name = self.BaseParams.getName() |
|
103 open(wxg_filename,"w").write("""<?xml version="1.0"?> |
|
104 <application path="" name="" class="" option="0" language="python" top_window="%(name)s" encoding="UTF-8" use_gettext="0" overwrite="0" use_new_namespace="1" for_version="2.8" is_template="0"> |
|
105 <object class="%(class)s" name="%(name)s" base="EditFrame"> |
|
106 <style>wxDEFAULT_FRAME_STYLE</style> |
|
107 <title>frame_1</title> |
|
108 </object> |
|
109 </application> |
|
110 """ % {"name": hmi_name, "class": "Class_%s" % hmi_name}) |
|
111 if wx.Platform == '__WXMSW__': |
|
112 wxg_filename = "\"%s\""%wxg_filename |
|
113 self.launch_wxglade([wxg_filename]) |