SVGHMI: Widget DnD to Inkscape : Added source SVG widget label parsing and pass selecte HMI subtree to XSLT tranform, so that SVG containing multiple widgets can later be matched against hmi tree fragments, in order to DnD complex groups of widgets. svghmi
authorEdouard Tisserant <edouard.tisserant@gmail.com>
Mon, 05 Apr 2021 18:22:30 +0200
branchsvghmi
changeset 3222 6adeeb16ac3e
parent 3221 3d307ad803ea
child 3223 061796d9855e
SVGHMI: Widget DnD to Inkscape : Added source SVG widget label parsing and pass selecte HMI subtree to XSLT tranform, so that SVG containing multiple widgets can later be matched against hmi tree fragments, in order to DnD complex groups of widgets.
svghmi/gen_dnd_widget_svg.xslt
svghmi/gen_dnd_widget_svg.ysl2
svghmi/gen_index_xhtml.xslt
svghmi/ui.py
--- a/svghmi/gen_dnd_widget_svg.xslt	Fri Apr 02 21:16:18 2021 +0200
+++ b/svghmi/gen_dnd_widget_svg.xslt	Mon Apr 05 18:22:30 2021 +0200
@@ -3,6 +3,8 @@
   <xsl:output method="xml"/>
   <xsl:variable name="svg" select="/svg:svg"/>
   <xsl:variable name="hmi_elements" select="//svg:*[starts-with(@inkscape:label, 'HMI:')]"/>
+  <xsl:variable name="subhmitree" select="ns:GetSubHMITree()"/>
+  <xsl:variable name="indexed_hmitree" select="/.."/>
   <xsl:template mode="parselabel" match="*">
     <xsl:variable name="label" select="@inkscape:label"/>
     <xsl:variable name="id" select="@id"/>
@@ -115,6 +117,10 @@
       </widget>
     </xsl:if>
   </xsl:template>
+  <xsl:variable name="_parsed_widgets">
+    <xsl:apply-templates mode="parselabel" select="$hmi_elements"/>
+  </xsl:variable>
+  <xsl:variable name="parsed_widgets" select="exsl:node-set($_parsed_widgets)"/>
   <xsl:template xmlns="http://www.w3.org/2000/svg" mode="inline_svg" match="@*">
     <xsl:copy/>
   </xsl:template>
@@ -123,10 +129,41 @@
       <xsl:apply-templates mode="inline_svg" select="@* | node()"/>
     </xsl:copy>
   </xsl:template>
+  <xsl:variable name="NODES_TYPES" select="str:split('HMI_ROOT HMI_NODE')"/>
+  <xsl:variable name="HMI_NODES_COMPAT" select="str:split('Page Jump Foreach')"/>
   <xsl:template match="/">
     <xsl:comment>
       <xsl:text>Widget dropped in Inkscape from Beremiz</xsl:text>
     </xsl:comment>
+    <xsl:variable name="selected_node_type" select="local-name($subhmitree)"/>
+    <xsl:variable name="svg_widget_type" select="$parsed_widgets/widget[1]/@type"/>
+    <xsl:variable name="svg_widget_count" select="count($parsed_widgets/widget)"/>
+    <xsl:choose>
+      <xsl:when test="$svg_widget_count &lt; 1">
+        <xsl:message terminate="yes">
+          <xsl:text>No widget detected on selected SVG</xsl:text>
+        </xsl:message>
+      </xsl:when>
+      <xsl:when test="$svg_widget_count &gt; 1">
+        <xsl:message terminate="yes">
+          <xsl:text>Multiple widget DnD not yet supported</xsl:text>
+        </xsl:message>
+      </xsl:when>
+      <xsl:when test="$selected_node_type = $NODES_TYPES and                     not($svg_widget_type = $HMI_NODES_COMPAT)">
+        <xsl:message terminate="yes">
+          <xsl:text>Widget incopatible with selected HMI tree node</xsl:text>
+        </xsl:message>
+      </xsl:when>
+    </xsl:choose>
+    <xsl:variable name="testmsg">
+      <msg>
+        <xsl:value-of select="$selected_node_type"/>
+      </msg>
+      <msg>
+        <xsl:value-of select="$svg_widget_type"/>
+      </msg>
+    </xsl:variable>
+    <xsl:value-of select="ns:GiveDetails($testmsg)"/>
     <xsl:apply-templates mode="inline_svg" select="/"/>
   </xsl:template>
 </xsl:stylesheet>
--- a/svghmi/gen_dnd_widget_svg.ysl2	Fri Apr 02 21:16:18 2021 +0200
+++ b/svghmi/gen_dnd_widget_svg.ysl2	Mon Apr 05 18:22:30 2021 +0200
@@ -21,8 +21,12 @@
 
     const "svg", "/svg:svg";
     const "hmi_elements", "//svg:*[starts-with(@inkscape:label, 'HMI:')]";
+    const "subhmitree", "ns:GetSubHMITree()";
 
+    const "indexed_hmitree", "/.."; // compatibility with parse_labels.ysl2
     include parse_labels.ysl2
+    const "_parsed_widgets" apply "$hmi_elements", mode="parselabel";
+    const "parsed_widgets","exsl:node-set($_parsed_widgets)";
 
     svgtmpl "@*", mode="inline_svg" xsl:copy;
 
@@ -30,9 +34,32 @@
       xsl:copy apply "@* | node()", mode="inline_svg";
     }
 
+
+    const "NODES_TYPES","str:split('HMI_ROOT HMI_NODE')";
+    const "HMI_NODES_COMPAT","str:split('Page Jump Foreach')";
     template "/" {
         comment > Widget dropped in Inkscape from Beremiz
 
+        const "selected_node_type","local-name($subhmitree)";
+        const "svg_widget_type", "$parsed_widgets/widget[1]/@type";
+        const "svg_widget_count", "count($parsed_widgets/widget)";
+
+        choose {
+            when "$svg_widget_count < 1"
+                error > No widget detected on selected SVG
+            when "$svg_widget_count > 1"
+                error > Multiple widget DnD not yet supported
+            when """$selected_node_type = $NODES_TYPES and \
+                    not($svg_widget_type = $HMI_NODES_COMPAT)"""
+                error > Widget incopatible with selected HMI tree node
+        }
+        const "testmsg" {
+            msg value "$selected_node_type";
+            msg value "$svg_widget_type";
+        }
+
+        value "ns:GiveDetails($testmsg)";
+
         apply "/", mode="inline_svg";
     }
 }
--- a/svghmi/gen_index_xhtml.xslt	Fri Apr 02 21:16:18 2021 +0200
+++ b/svghmi/gen_index_xhtml.xslt	Mon Apr 05 18:22:30 2021 +0200
@@ -1,6 +1,6 @@
 <?xml version="1.0"?>
-<xsl:stylesheet xmlns:ns="beremiz" xmlns:definitions="definitions" xmlns:xhtml="http://www.w3.org/1999/xhtml" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:func="http://exslt.org/functions" xmlns:epilogue="epilogue" xmlns:preamble="preamble" xmlns:xlink="http://www.w3.org/1999/xlink" xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd" xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape" xmlns:svg="http://www.w3.org/2000/svg" xmlns:cc="http://creativecommons.org/ns#" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" xmlns:str="http://exslt.org/strings" xmlns:regexp="http://exslt.org/regular-expressions" xmlns:exsl="http://exslt.org/common" xmlns:declarations="declarations" xmlns:debug="debug" exclude-result-prefixes="ns func exsl regexp str dyn debug preamble epilogue declarations definitions" extension-element-prefixes="ns func exsl regexp str dyn" version="1.0">
-  <xsl:output method="xml" cdata-section-elements="xhtml:script"/>
+<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:exsl="http://exslt.org/common" xmlns:regexp="http://exslt.org/regular-expressions" xmlns:str="http://exslt.org/strings" xmlns:func="http://exslt.org/functions" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:cc="http://creativecommons.org/ns#" xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" xmlns:svg="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd" xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape" xmlns:xhtml="http://www.w3.org/1999/xhtml" xmlns:debug="debug" xmlns:preamble="preamble" xmlns:declarations="declarations" xmlns:definitions="definitions" xmlns:epilogue="epilogue" xmlns:ns="beremiz" version="1.0" extension-element-prefixes="ns func exsl regexp str dyn" exclude-result-prefixes="ns func exsl regexp str dyn debug preamble epilogue declarations definitions">
+  <xsl:output cdata-section-elements="xhtml:script" method="xml"/>
   <xsl:variable name="svg" select="/svg:svg"/>
   <xsl:variable name="hmi_elements" select="//svg:*[starts-with(@inkscape:label, 'HMI:')]"/>
   <xsl:variable name="hmitree" select="ns:GetHMITree()"/>
@@ -1713,7 +1713,7 @@
 </xsl:text>
   </xsl:template>
   <xsl:variable name="excluded_types" select="str:split('Page VarInit VarInitPersistent')"/>
-  <xsl:key use="@type" name="TypesKey" match="widget"/>
+  <xsl:key name="TypesKey" match="widget" use="@type"/>
   <declarations:hmi-classes/>
   <xsl:template match="declarations:hmi-classes">
     <xsl:text>
@@ -6838,9 +6838,9 @@
     <xsl:comment>
       <xsl:text>Made with SVGHMI. https://beremiz.org</xsl:text>
     </xsl:comment>
-    <html xmlns:svg="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" xmlns="http://www.w3.org/1999/xhtml">
+    <html xmlns="http://www.w3.org/1999/xhtml" xmlns:svg="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
       <head>
-        <style media="screen" type="text/css">
+        <style type="text/css" media="screen">
           <xsl:value-of select="ns:GetFonts()"/>
         </style>
       </head>
--- a/svghmi/ui.py	Fri Apr 02 21:16:18 2021 +0200
+++ b/svghmi/ui.py	Mon Apr 05 18:22:30 2021 +0200
@@ -290,8 +290,11 @@
 
     def GiveDetails(self, _context, msgs):
         for msg in msgs:
-            self.msg += msg+"\n"
+            self.msg += msg.text + "\n"
         
+    def GetSubHMITree(self, _context):
+        return [self.hmitree_node.etree()]
+
     def ValidateWidget(self):
         self.msg = ""
 
@@ -307,13 +310,12 @@
 
             transform = XSLTransform(
                 os.path.join(ScriptDirectory, "gen_dnd_widget_svg.xslt"),
-                [("GiveDetails", self.GiveDetails)])
+                [("GetSubHMITree", self.GetSubHMITree),
+                 ("GiveDetails", self.GiveDetails)])
 
             svgdom = etree.parse(self.selected_SVG)
 
-            result = transform.transform(svgdom) 
-                # hmi_path=self.hmitree_node.path,
-                # hmi_type=self.hmitree_node.nodetype)
+            result = transform.transform(svgdom)
 
             for entry in transform.get_error_log():
                 self.msg += "XSLT: " + entry.message + "\n"