svghmi/svghmi.py
branchsvghmi
changeset 2745 535eb0b8bd9d
child 2747 e96aa2e3231e
equal deleted inserted replaced
2623:26ba948a2e51 2745:535eb0b8bd9d
       
     1 #!/usr/bin/env python
       
     2 # -*- coding: utf-8 -*-
       
     3 
       
     4 # This file is part of Beremiz
       
     5 # Copyright (C) 2019: Edouard TISSERANT
       
     6 #
       
     7 # See COPYING file for copyrights details.
       
     8 
       
     9 from __future__ import absolute_import
       
    10 import os
       
    11 import shutil
       
    12 
       
    13 import wx
       
    14 
       
    15 import util.paths as paths
       
    16 from POULibrary import POULibrary
       
    17 from docutil import open_svg
       
    18 
       
    19 
       
    20 class SVGHMILibrary(POULibrary):
       
    21     def GetLibraryPath(self):
       
    22         return paths.AbsNeighbourFile(__file__, "pous.xml")
       
    23 
       
    24 
       
    25 class SVGHMI(object):
       
    26     XSD = """<?xml version="1.0" encoding="ISO-8859-1" ?>
       
    27     <xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema">
       
    28       <xsd:element name="SVGHMI">
       
    29         <xsd:complexType>
       
    30           <xsd:attribute name="enableHTTP" type="xsd:boolean" use="optional" default="false"/>
       
    31           <xsd:attribute name="bindAddress" type="xsd:string" use="optional" default="localhost"/>
       
    32           <xsd:attribute name="port" type="xsd:string" use="optional" default="8080"/>
       
    33         </xsd:complexType>
       
    34       </xsd:element>
       
    35     </xsd:schema>
       
    36     """
       
    37 
       
    38     ConfNodeMethods = [
       
    39         {
       
    40             "bitmap":    "ImportSVG",
       
    41             "name":    _("Import SVG"),
       
    42             "tooltip": _("Import SVG"),
       
    43             "method":   "_ImportSVG"
       
    44         },
       
    45         {
       
    46             "bitmap":    "ImportSVG",  # should be something different
       
    47             "name":    _("Inkscape"),
       
    48             "tooltip": _("Edit HMI"),
       
    49             "method":   "_StartInkscape"
       
    50         },
       
    51     ]
       
    52 
       
    53     def _getSVGpath(self, project_path=None):
       
    54         if project_path is None:
       
    55             project_path = self.CTNPath()
       
    56         # define name for SVG file containing gui layout
       
    57         return os.path.join(project_path, "gui.svg")
       
    58 
       
    59 
       
    60     def OnCTNSave(self, from_project_path=None):
       
    61         if from_project_path is not None:
       
    62             shutil.copyfile(self._getSVGpath(from_project_path),
       
    63                             self._getSVGpath())
       
    64         return PythonFileCTNMixin.OnCTNSave(self, from_project_path)
       
    65 
       
    66     def CTNGenerate_C(self, buildpath, locations):
       
    67         """
       
    68         Return C code generated by iec2c compiler
       
    69         when _generate_softPLC have been called
       
    70         @param locations: ignored
       
    71         @return: [(C_file_name, CFLAGS),...] , LDFLAGS_TO_APPEND
       
    72         """
       
    73 
       
    74         # TODO : get variable list from Controller
       
    75         # self.GetCTRoot().blah
       
    76         # TODO deduce HMI tree
       
    77 
       
    78         svgfile = self._getSVGpath()
       
    79         if os.path.exists(svgfile):
       
    80             # TODO : call xslt transform on Inkscape's SVG to generate
       
    81             #   - Errors on HMI semantics
       
    82             #   - Target XHTML as a DOM
       
    83             #   - ... maybe something to have a global view of what is declared in SVG.
       
    84             pass
       
    85         else:
       
    86             # TODO : use default svg that expose the HMI tree as-is 
       
    87             pass
       
    88 
       
    89 
       
    90         res = ([], "", False)
       
    91 
       
    92         targetpath = os.path.join(self._getBuildPath(), "target.xhtml")
       
    93         targetfile = open(targetpath, 'w')
       
    94 
       
    95         # TODO : DOM to string
       
    96         targetfile.write("TODO")
       
    97         targetfile.close()
       
    98         res += (("target.js", open(targetpath, "rb")),)
       
    99 
       
   100         # TODO add C code to expose HMI tree variables to shared memory
       
   101         # TODO generate a description of shared memory (xml or CSV) 
       
   102         #      that can be loaded by svghmi QTWeb* app or svghmi server
       
   103 
       
   104 
       
   105         return res
       
   106 
       
   107     def _ImportSVG(self):
       
   108         dialog = wx.FileDialog(self.GetCTRoot().AppFrame, _("Choose a SVG file"), os.getcwd(), "",  _("SVG files (*.svg)|*.svg|All files|*.*"), wx.OPEN)
       
   109         if dialog.ShowModal() == wx.ID_OK:
       
   110             svgpath = dialog.GetPath()
       
   111             if os.path.isfile(svgpath):
       
   112                 shutil.copy(svgpath, self._getSVGpath())
       
   113             else:
       
   114                 self.GetCTRoot().logger.write_error(_("No such SVG file: %s\n") % svgpath)
       
   115         dialog.Destroy()
       
   116 
       
   117     def _StartInkscape(self):
       
   118         svgfile = self._getSVGpath()
       
   119         open_inkscape = True
       
   120         if not self.GetCTRoot().CheckProjectPathPerm():
       
   121             dialog = wx.MessageDialog(self.GetCTRoot().AppFrame,
       
   122                                       _("You don't have write permissions.\nOpen Inkscape anyway ?"),
       
   123                                       _("Open Inkscape"),
       
   124                                       wx.YES_NO | wx.ICON_QUESTION)
       
   125             open_inkscape = dialog.ShowModal() == wx.ID_YES
       
   126             dialog.Destroy()
       
   127         if open_inkscape:
       
   128             if not os.path.isfile(svgfile):
       
   129                 svgfile = None
       
   130             open_svg(svgfile)