1 #!/usr/bin/env python |
|
2 # -*- coding: utf-8 -*- |
|
3 |
|
4 # This file is part of Beremiz, a Integrated Development Environment for |
|
5 # programming IEC 61131-3 automates supporting plcopen standard and CanFestival. |
|
6 # |
|
7 # Copyright (C) 2007: Edouard TISSERANT and Laurent BESSARD |
|
8 # Copyright (C) 2017: Andrey Skvortsov |
|
9 # |
|
10 # See COPYING file for copyrights details. |
|
11 # |
|
12 # This program is free software; you can redistribute it and/or |
|
13 # modify it under the terms of the GNU General Public License |
|
14 # as published by the Free Software Foundation; either version 2 |
|
15 # of the License, or (at your option) any later version. |
|
16 # |
|
17 # This program is distributed in the hope that it will be useful, |
|
18 # but WITHOUT ANY WARRANTY; without even the implied warranty of |
|
19 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
|
20 # GNU General Public License for more details. |
|
21 # |
|
22 # You should have received a copy of the GNU General Public License |
|
23 # along with this program; if not, write to the Free Software |
|
24 # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. |
|
25 |
|
26 |
|
27 from __future__ import absolute_import |
|
28 import os |
|
29 import shutil |
|
30 |
|
31 import wx |
|
32 from svgui.pyjs import translate |
|
33 |
|
34 import util.paths as paths |
|
35 from POULibrary import POULibrary |
|
36 from docutil import open_svg |
|
37 from py_ext import PythonFileCTNMixin |
|
38 |
|
39 |
|
40 class SVGUILibrary(POULibrary): |
|
41 def GetLibraryPath(self): |
|
42 return paths.AbsNeighbourFile(__file__, "pous.xml") |
|
43 |
|
44 |
|
45 class SVGUI(PythonFileCTNMixin): |
|
46 |
|
47 ConfNodeMethods = [ |
|
48 { |
|
49 "bitmap": "ImportSVG", |
|
50 "name": _("Import SVG"), |
|
51 "tooltip": _("Import SVG"), |
|
52 "method": "_ImportSVG" |
|
53 }, |
|
54 { |
|
55 "bitmap": "ImportSVG", # should be something different |
|
56 "name": _("Inkscape"), |
|
57 "tooltip": _("Create HMI"), |
|
58 "method": "_StartInkscape" |
|
59 }, |
|
60 ] |
|
61 |
|
62 def _getSVGpath(self, project_path=None): |
|
63 if project_path is None: |
|
64 project_path = self.CTNPath() |
|
65 # define name for SVG file containing gui layout |
|
66 return os.path.join(project_path, "gui.svg") |
|
67 |
|
68 def _getSVGUIserverpath(self): |
|
69 return paths.AbsNeighbourFile(__file__, "svgui_server.py") |
|
70 |
|
71 def OnCTNSave(self, from_project_path=None): |
|
72 if from_project_path is not None: |
|
73 shutil.copyfile(self._getSVGpath(from_project_path), |
|
74 self._getSVGpath()) |
|
75 return PythonFileCTNMixin.OnCTNSave(self, from_project_path) |
|
76 |
|
77 def CTNGenerate_C(self, buildpath, locations): |
|
78 """ |
|
79 Return C code generated by iec2c compiler |
|
80 when _generate_softPLC have been called |
|
81 @param locations: ignored |
|
82 @return: [(C_file_name, CFLAGS),...] , LDFLAGS_TO_APPEND |
|
83 """ |
|
84 |
|
85 current_location = self.GetCurrentLocation() |
|
86 # define a unique name for the generated C file |
|
87 location_str = "_".join(map(str, current_location)) |
|
88 |
|
89 res = ([], "", False) |
|
90 |
|
91 svgfile = self._getSVGpath() |
|
92 if os.path.exists(svgfile): |
|
93 res += (("gui.svg", open(svgfile, "rb")),) |
|
94 |
|
95 svguiserverfile = open(self._getSVGUIserverpath(), 'r') |
|
96 svguiservercode = svguiserverfile.read() |
|
97 svguiserverfile.close() |
|
98 |
|
99 svguilibpath = os.path.join(self._getBuildPath(), "svguilib.js") |
|
100 svguilibfile = open(svguilibpath, 'w') |
|
101 fpath = paths.AbsDir(__file__) |
|
102 svguilibfile.write(translate(os.path.join(fpath, "pyjs", "lib", "sys.py"), "sys")) |
|
103 svguilibfile.write(open(os.path.join(fpath, "pyjs", "lib", "_pyjs.js"), 'r').read()) |
|
104 svguilibfile.write(translate(os.path.join(fpath, "pyjs", "lib", "pyjslib.py"), "pyjslib")) |
|
105 svguilibfile.write(translate(os.path.join(fpath, "svguilib.py"), "svguilib")) |
|
106 svguilibfile.write("pyjslib();\nsvguilib();\n") |
|
107 svguilibfile.write(open(os.path.join(fpath, "pyjs", "lib", "json.js"), 'r').read()) |
|
108 svguilibfile.write(open(os.path.join(fpath, "livesvg.js"), 'r').read()) |
|
109 svguilibfile.close() |
|
110 jsmodules = {"LiveSVGPage": "svguilib.js"} |
|
111 res += (("svguilib.js", open(svguilibpath, "rb")),) |
|
112 |
|
113 runtimefile_path = os.path.join(buildpath, "runtime_%s.py" % location_str) |
|
114 runtimefile = open(runtimefile_path, 'w') |
|
115 runtimefile.write(svguiservercode % {"svgfile": "gui.svg"}) |
|
116 runtimefile.write(""" |
|
117 def _runtime_%(location)s_start(): |
|
118 website.LoadHMI(%(svgui_class)s, %(jsmodules)s) |
|
119 |
|
120 def _runtime_%(location)s_stop(): |
|
121 website.UnLoadHMI() |
|
122 |
|
123 """ % {"location": location_str, |
|
124 "svgui_class": "SVGUI_HMI", |
|
125 "jsmodules": str(jsmodules)}) |
|
126 runtimefile.close() |
|
127 |
|
128 res += (("runtime_%s.py" % location_str, open(runtimefile_path, "rb")),) |
|
129 |
|
130 return res |
|
131 |
|
132 def _ImportSVG(self): |
|
133 dialog = wx.FileDialog(self.GetCTRoot().AppFrame, _("Choose a SVG file"), os.getcwd(), "", _("SVG files (*.svg)|*.svg|All files|*.*"), wx.OPEN) |
|
134 if dialog.ShowModal() == wx.ID_OK: |
|
135 svgpath = dialog.GetPath() |
|
136 if os.path.isfile(svgpath): |
|
137 shutil.copy(svgpath, self._getSVGpath()) |
|
138 else: |
|
139 self.GetCTRoot().logger.write_error(_("No such SVG file: %s\n") % svgpath) |
|
140 dialog.Destroy() |
|
141 |
|
142 def _StartInkscape(self): |
|
143 svgfile = self._getSVGpath() |
|
144 open_inkscape = True |
|
145 if not self.GetCTRoot().CheckProjectPathPerm(): |
|
146 dialog = wx.MessageDialog(self.GetCTRoot().AppFrame, |
|
147 _("You don't have write permissions.\nOpen Inkscape anyway ?"), |
|
148 _("Open Inkscape"), |
|
149 wx.YES_NO | wx.ICON_QUESTION) |
|
150 open_inkscape = dialog.ShowModal() == wx.ID_YES |
|
151 dialog.Destroy() |
|
152 if open_inkscape: |
|
153 if not os.path.isfile(svgfile): |
|
154 svgfile = None |
|
155 open_svg(svgfile) |
|