andrej@1511: #!/usr/bin/env python andrej@1511: # -*- coding: utf-8 -*- andrej@1511: andrej@1511: # This file is part of Beremiz, a Integrated Development Environment for andrej@1511: # programming IEC 61131-3 automates supporting plcopen standard and CanFestival. andrej@1511: # andrej@1511: # Copyright (C) 2007: Edouard TISSERANT and Laurent BESSARD andrej@1680: # Copyright (C) 2017: Andrey Skvortsov andrej@1511: # andrej@1511: # See COPYING file for copyrights details. andrej@1511: # andrej@1511: # This program is free software; you can redistribute it and/or andrej@1511: # modify it under the terms of the GNU General Public License andrej@1511: # as published by the Free Software Foundation; either version 2 andrej@1511: # of the License, or (at your option) any later version. andrej@1511: # andrej@1511: # This program is distributed in the hope that it will be useful, andrej@1511: # but WITHOUT ANY WARRANTY; without even the implied warranty of andrej@1511: # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the andrej@1511: # GNU General Public License for more details. andrej@1511: # andrej@1511: # You should have received a copy of the GNU General Public License andrej@1511: # along with this program; if not, write to the Free Software andrej@1511: # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. andrej@1511: andrej@1853: andrej@1853: from __future__ import absolute_import andrej@1732: import os andrej@1732: import shutil laurent@371: andrej@1832: import wx andrej@1853: from svgui.pyjs import translate laurent@371: andrej@1680: import util.paths as paths Edouard@728: from POULibrary import POULibrary Edouard@737: from docutil import open_svg Laurent@1061: from py_ext import PythonFileCTNMixin laurent@371: andrej@1736: Edouard@728: class SVGUILibrary(POULibrary): Edouard@728: def GetLibraryPath(self): andrej@1730: return paths.AbsNeighbourFile(__file__, "pous.xml") Edouard@728: andrej@1736: Laurent@1061: class SVGUI(PythonFileCTNMixin): laurent@371: Edouard@717: ConfNodeMethods = [ andrej@1739: { andrej@1739: "bitmap": "ImportSVG", andrej@1739: "name": _("Import SVG"), andrej@1739: "tooltip": _("Import SVG"), andrej@1739: "method": "_ImportSVG" andrej@1739: }, andrej@1739: { andrej@1739: "bitmap": "ImportSVG", # should be something different andrej@1739: "name": _("Inkscape"), andrej@1739: "tooltip": _("Create HMI"), andrej@1739: "method": "_StartInkscape" andrej@1739: }, laurent@371: ] laurent@371: Edouard@717: def ConfNodePath(self): andrej@1680: return paths.AbsDir(__file__) laurent@371: Laurent@1061: def _getSVGpath(self, project_path=None): Laurent@1061: if project_path is None: Laurent@1061: project_path = self.CTNPath() Laurent@1061: # define name for SVG file containing gui layout Laurent@1061: return os.path.join(project_path, "gui.svg") laurent@371: laurent@371: def _getSVGUIserverpath(self): andrej@1680: return paths.AbsNeighbourFile(__file__, "svgui_server.py") laurent@371: Laurent@1061: def OnCTNSave(self, from_project_path=None): Laurent@1061: if from_project_path is not None: Laurent@1061: shutil.copyfile(self._getSVGpath(from_project_path), Laurent@1061: self._getSVGpath()) Laurent@1061: return PythonFileCTNMixin.OnCTNSave(self, from_project_path) Laurent@1061: Edouard@718: def CTNGenerate_C(self, buildpath, locations): laurent@371: """ andrej@1730: Return C code generated by iec2c compiler laurent@371: when _generate_softPLC have been called laurent@371: @param locations: ignored laurent@371: @return: [(C_file_name, CFLAGS),...] , LDFLAGS_TO_APPEND laurent@371: """ andrej@1730: laurent@371: current_location = self.GetCurrentLocation() laurent@371: # define a unique name for the generated C file andrej@1833: location_str = "_".join(map(str, current_location)) andrej@1730: laurent@371: res = ([], "", False) andrej@1730: andrej@1742: svgfile = self._getSVGpath() laurent@371: if os.path.exists(svgfile): andrej@1740: res += (("gui.svg", file(svgfile, "rb")),) laurent@371: laurent@371: svguiserverfile = open(self._getSVGUIserverpath(), 'r') laurent@371: svguiservercode = svguiserverfile.read() laurent@371: svguiserverfile.close() laurent@371: laurent@371: svguilibpath = os.path.join(self._getBuildPath(), "svguilib.js") laurent@371: svguilibfile = open(svguilibpath, 'w') andrej@1742: fpath = paths.AbsDir(__file__) andrej@1680: svguilibfile.write(translate(os.path.join(fpath, "pyjs", "lib", "sys.py"), "sys")) andrej@1680: svguilibfile.write(open(os.path.join(fpath, "pyjs", "lib", "_pyjs.js"), 'r').read()) andrej@1680: svguilibfile.write(translate(os.path.join(fpath, "pyjs", "lib", "pyjslib.py"), "pyjslib")) andrej@1680: svguilibfile.write(translate(os.path.join(fpath, "svguilib.py"), "svguilib")) laurent@371: svguilibfile.write("pyjslib();\nsvguilib();\n") andrej@1680: svguilibfile.write(open(os.path.join(fpath, "pyjs", "lib", "json.js"), 'r').read()) andrej@1680: svguilibfile.write(open(os.path.join(fpath, "livesvg.js"), 'r').read()) laurent@371: svguilibfile.close() laurent@371: jsmodules = {"LiveSVGPage": "svguilib.js"} andrej@1740: res += (("svguilib.js", file(svguilibpath, "rb")),) andrej@1730: andrej@1734: runtimefile_path = os.path.join(buildpath, "runtime_%s.py" % location_str) laurent@371: runtimefile = open(runtimefile_path, 'w') andrej@1739: runtimefile.write(svguiservercode % {"svgfile": "gui.svg"}) laurent@371: runtimefile.write(""" Edouard@1014: def _runtime_%(location)s_start(): laurent@371: website.LoadHMI(%(svgui_class)s, %(jsmodules)s) andrej@1730: Edouard@1014: def _runtime_%(location)s_stop(): laurent@371: website.UnLoadHMI() andrej@1730: andrej@1776: """ % {"location": location_str, andrej@1776: "svgui_class": "SVGUI_HMI", andrej@1776: "jsmodules": str(jsmodules)}) laurent@371: runtimefile.close() andrej@1730: andrej@1740: res += (("runtime_%s.py" % location_str, file(runtimefile_path, "rb")),) andrej@1730: laurent@371: return res laurent@371: laurent@371: def _ImportSVG(self): Edouard@718: dialog = wx.FileDialog(self.GetCTRoot().AppFrame, _("Choose a SVG file"), os.getcwd(), "", _("SVG files (*.svg)|*.svg|All files|*.*"), wx.OPEN) laurent@371: if dialog.ShowModal() == wx.ID_OK: laurent@371: svgpath = dialog.GetPath() laurent@371: if os.path.isfile(svgpath): laurent@371: shutil.copy(svgpath, self._getSVGpath()) laurent@371: else: andrej@1734: self.GetCTRoot().logger.write_error(_("No such SVG file: %s\n") % svgpath) andrej@1730: dialog.Destroy() laurent@371: laurent@371: def _StartInkscape(self): laurent@371: svgfile = self._getSVGpath() greg@427: open_inkscape = True Edouard@718: if not self.GetCTRoot().CheckProjectPathPerm(): Edouard@718: dialog = wx.MessageDialog(self.GetCTRoot().AppFrame, greg@427: _("You don't have write permissions.\nOpen Inkscape anyway ?"), greg@427: _("Open Inkscape"), andrej@1745: wx.YES_NO | wx.ICON_QUESTION) greg@427: open_inkscape = dialog.ShowModal() == wx.ID_YES greg@427: dialog.Destroy() greg@427: if open_inkscape: greg@427: if not os.path.isfile(svgfile): greg@427: svgfile = None greg@427: open_svg(svgfile)