1 import wx |
|
2 import os, sys |
|
3 from xml.dom import minidom |
|
4 |
|
5 from ConfigTree import opjimg |
|
6 from confnodes.python import PythonCodeTemplate |
|
7 |
|
8 class RootClass(PythonCodeTemplate): |
|
9 |
|
10 ConfNodeMethods = [ |
|
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.CTNPath(), "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 CTNGenerate_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 wxghmipyfile_path = "\"%s\""%hmipyfile_path |
|
62 else: |
|
63 wxghmipyfile_path = hmipyfile_path |
|
64 self.launch_wxglade(['-o', wxghmipyfile_path, '-g', 'python', wxgfile_path], wait=True) |
|
65 |
|
66 hmipyfile = open(hmipyfile_path, 'r') |
|
67 runtimefile.write(hmipyfile.read()) |
|
68 hmipyfile.close() |
|
69 |
|
70 runtimefile.write(self.GetPythonCode()) |
|
71 runtimefile.write(""" |
|
72 %(declare)s |
|
73 |
|
74 def _runtime_%(location)s_begin(): |
|
75 global %(global)s |
|
76 |
|
77 def OnCloseFrame(evt): |
|
78 wx.MessageBox(_("Please stop PLC to close")) |
|
79 |
|
80 %(init)s |
|
81 |
|
82 def _runtime_%(location)s_cleanup(): |
|
83 global %(global)s |
|
84 |
|
85 %(cleanup)s |
|
86 |
|
87 """ % {"location": location_str, |
|
88 "declare": "\n".join(map(lambda x:"%s = None" % x, hmi_frames.keys())), |
|
89 "global": ",".join(hmi_frames.keys()), |
|
90 "init": "\n".join(map(lambda x: """ |
|
91 %(name)s = %(class)s(None) |
|
92 %(name)s.Bind(wx.EVT_CLOSE, OnCloseFrame) |
|
93 %(name)s.Show() |
|
94 """ % {"name": x[0], "class": x[1]}, |
|
95 hmi_frames.items())), |
|
96 "cleanup": "\n ".join(map(lambda x:"%s.Destroy()" % x, hmi_frames.keys()))}) |
|
97 runtimefile.close() |
|
98 |
|
99 return [], "", False, ("runtime_%s.py"%location_str, file(runtimefile_path,"rb")) |
|
100 |
|
101 def _editWXGLADE(self): |
|
102 wxg_filename = self._getWXGLADEpath() |
|
103 open_wxglade = True |
|
104 if not self.GetCTRoot().CheckProjectPathPerm(): |
|
105 dialog = wx.MessageDialog(self.GetCTRoot().AppFrame, |
|
106 _("You don't have write permissions.\nOpen wxGlade anyway ?"), |
|
107 _("Open wxGlade"), |
|
108 wx.YES_NO|wx.ICON_QUESTION) |
|
109 open_wxglade = dialog.ShowModal() == wx.ID_YES |
|
110 dialog.Destroy() |
|
111 if open_wxglade: |
|
112 if not os.path.exists(wxg_filename): |
|
113 hmi_name = self.BaseParams.getName() |
|
114 open(wxg_filename,"w").write("""<?xml version="1.0"?> |
|
115 <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"> |
|
116 <object class="%(class)s" name="%(name)s" base="EditFrame"> |
|
117 <style>wxDEFAULT_FRAME_STYLE</style> |
|
118 <title>frame_1</title> |
|
119 </object> |
|
120 </application> |
|
121 """ % {"name": hmi_name, "class": "Class_%s" % hmi_name}) |
|
122 if wx.Platform == '__WXMSW__': |
|
123 wxg_filename = "\"%s\""%wxg_filename |
|
124 self.launch_wxglade([wxg_filename]) |
|