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: laurent@371: import wx laurent@407: import os, sys, shutil laurent@371: laurent@371: from 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: Edouard@728: class SVGUILibrary(POULibrary): Edouard@728: def GetLibraryPath(self): andrej@1680: return paths.AbsNeighbourFile(__file__, "pous.xml") Edouard@728: Laurent@1061: class SVGUI(PythonFileCTNMixin): laurent@371: Edouard@717: ConfNodeMethods = [ Edouard@734: {"bitmap" : "ImportSVG", laurent@415: "name" : _("Import SVG"), laurent@415: "tooltip" : _("Import SVG"), laurent@371: "method" : "_ImportSVG"}, Edouard@734: {"bitmap" : "ImportSVG", # should be something different laurent@415: "name" : _("Inkscape"), laurent@415: "tooltip" : _("Create HMI"), laurent@371: "method" : "_StartInkscape"}, 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: """ laurent@371: 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: """ laurent@371: laurent@371: current_location = self.GetCurrentLocation() laurent@371: # define a unique name for the generated C file laurent@371: location_str = "_".join(map(lambda x:str(x), current_location)) laurent@371: laurent@371: res = ([], "", False) laurent@371: laurent@371: svgfile=self._getSVGpath() laurent@371: if os.path.exists(svgfile): laurent@371: 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@1680: 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"} laurent@371: res += (("svguilib.js", file(svguilibpath,"rb")),) laurent@371: laurent@371: runtimefile_path = os.path.join(buildpath, "runtime_%s.py"%location_str) laurent@371: runtimefile = open(runtimefile_path, 'w') laurent@371: 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) laurent@371: Edouard@1014: def _runtime_%(location)s_stop(): laurent@371: website.UnLoadHMI() laurent@371: laurent@371: """ % {"location": location_str, laurent@371: "svgui_class": "SVGUI_HMI", laurent@371: "jsmodules" : str(jsmodules), laurent@371: }) laurent@371: runtimefile.close() laurent@371: laurent@371: res += (("runtime_%s.py"%location_str, file(runtimefile_path,"rb")),) laurent@371: 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: Edouard@718: self.GetCTRoot().logger.write_error(_("No such SVG file: %s\n")%svgpath) laurent@371: 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"), greg@427: 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)