--- a/svghmi/Makefile Sun May 02 23:43:57 2021 +0200
+++ b/svghmi/Makefile Mon May 03 00:04:08 2021 +0200
@@ -11,7 +11,7 @@
yml2path ?= $(abspath ../../yml2)
-ysl2files := gen_index_xhtml.ysl2 gen_dnd_widget_svg.ysl2
+ysl2files := gen_index_xhtml.ysl2 gen_dnd_widget_svg.ysl2 analyse_widget.ysl2 ysl2includes := $(filter-out $(ysl2files), $(wildcard *.ysl2))
xsltfiles := $(patsubst %.ysl2, %.xslt, $(ysl2files))
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/svghmi/analyse_widget.xslt Mon May 03 00:04:08 2021 +0200
@@ -0,0 +1,153 @@
+<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:svg="http://www.w3.org/2000/svg" xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape" version="1.0" extension-element-prefixes="ns func exsl regexp str dyn" exclude-result-prefixes="ns func exsl regexp str dyn svg inkscape"> + <xsl:output method="xml"/> + <xsl:variable name="indexed_hmitree" select="/.."/> + <xsl:variable name="pathregex" select="'^([^\[,]+)(\[[^\]]+\])?([\d,]*)$'"/> + <xsl:template mode="parselabel" match="*"> + <xsl:variable name="label" select="@inkscape:label"/> + <xsl:variable name="id" select="@id"/> + <xsl:variable name="description" select="substring-after($label,'HMI:')"/> + <xsl:variable name="_args" select="substring-before($description,'@')"/> + <xsl:variable name="args"> + <xsl:when test="$_args"> + <xsl:value-of select="$_args"/> + <xsl:value-of select="$description"/> + <xsl:variable name="_type" select="substring-before($args,':')"/> + <xsl:variable name="type"> + <xsl:when test="$_type"> + <xsl:value-of select="$_type"/> + <xsl:value-of select="$args"/> + <xsl:attribute name="id"> + <xsl:value-of select="$id"/> + <xsl:attribute name="type"> + <xsl:value-of select="$type"/> + <xsl:for-each select="str:split(substring-after($args, ':'), ':')"> + <xsl:attribute name="value"> + <xsl:value-of select="."/> + <xsl:variable name="paths" select="substring-after($description,'@')"/> + <xsl:for-each select="str:split($paths, '@')"> + <xsl:if test="string-length(.) > 0"> + <xsl:variable name="path_match" select="regexp:match(.,$pathregex)"/> + <xsl:variable name="pathminmax" select="str:split($path_match[4],',')"/> + <xsl:variable name="path" select="$path_match[2]"/> + <xsl:variable name="path_accepts" select="$path_match[3]"/> + <xsl:variable name="pathminmaxcount" select="count($pathminmax)"/> + <xsl:attribute name="value"> + <xsl:value-of select="$path"/> + <xsl:if test="string-length($path_accepts)"> + <xsl:attribute name="accepts"> + <xsl:value-of select="$path_accepts"/> + <xsl:when test="$pathminmaxcount = 2"> + <xsl:attribute name="min"> + <xsl:value-of select="$pathminmax[1]"/> + <xsl:attribute name="max"> + <xsl:value-of select="$pathminmax[2]"/> + <xsl:when test="$pathminmaxcount = 1 or $pathminmaxcount > 2"> + <xsl:message terminate="yes"> + <xsl:text>Widget id:</xsl:text> + <xsl:value-of select="$id"/> + <xsl:text> label:</xsl:text> + <xsl:value-of select="$label"/> + <xsl:text> has wrong syntax of path section </xsl:text> + <xsl:value-of select="$pathminmax"/> + <xsl:if test="$indexed_hmitree"> + <xsl:when test="regexp:test($path,'^\.[a-zA-Z0-9_]+$')"> + <xsl:attribute name="type"> + <xsl:text>PAGE_LOCAL</xsl:text> + <xsl:when test="regexp:test($path,'^[a-zA-Z0-9_]+$')"> + <xsl:attribute name="type"> + <xsl:text>HMI_LOCAL</xsl:text> + <xsl:variable name="item" select="$indexed_hmitree/*[@hmipath = $path]"/> + <xsl:variable name="pathtype" select="local-name($item)"/> + <xsl:if test="$pathminmaxcount = 3 and not($pathtype = 'HMI_INT' or $pathtype = 'HMI_REAL')"> + <xsl:message terminate="yes"> + <xsl:text>Widget id:</xsl:text> + <xsl:value-of select="$id"/> + <xsl:text> label:</xsl:text> + <xsl:value-of select="$label"/> + <xsl:text> path section </xsl:text> + <xsl:value-of select="$pathminmax"/> + <xsl:text> use min and max on non mumeric value</xsl:text> + <xsl:if test="count($item) = 1"> + <xsl:attribute name="index"> + <xsl:value-of select="$item/@index"/> + <xsl:attribute name="type"> + <xsl:value-of select="$pathtype"/> + <xsl:template mode="genlabel" match="arg"> + <xsl:value-of select="@value"/> + <xsl:template mode="genlabel" match="path"> + <xsl:value-of select="@value"/> + <xsl:if test="string-length(@min)>0 or string-length(@max)>0"> + <xsl:value-of select="@min"/> + <xsl:value-of select="@max"/> + <xsl:template mode="genlabel" match="widget"> + <xsl:text>HMI:</xsl:text> + <xsl:value-of select="@type"/> + <xsl:apply-templates mode="genlabel" select="arg"/> + <xsl:apply-templates mode="genlabel" select="path"/> + <xsl:variable name="hmi_elements" select="//svg:*[starts-with(@inkscape:label, 'HMI:')]"/> + <xsl:template match="/"> + <xsl:apply-templates mode="parselabel" select="$hmi_elements"/> --- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/svghmi/analyse_widget.ysl2 Mon May 03 00:04:08 2021 +0200
@@ -0,0 +1,20 @@
+include yslt_noindent.yml2 + xmlns:svg="http://www.w3.org/2000/svg" + xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape" + extension-element-prefixes="ns func exsl regexp str dyn" + exclude-result-prefixes="ns func exsl regexp str dyn svg inkscape" { + const "indexed_hmitree", "/.."; // compatibility with parse_labels.ysl2 + include parse_labels.ysl2 + const "hmi_elements", "//svg:*[starts-with(@inkscape:label, 'HMI:')]"; + apply "$hmi_elements", mode="parselabel"; --- a/svghmi/ui.py Sun May 02 23:43:57 2021 +0200
+++ b/svghmi/ui.py Mon May 03 00:04:08 2021 +0200
@@ -299,10 +299,54 @@
def GetSubHMITree(self, _context):
return [self.hmitree_node.etree()]
+ def AnalyseWidget(self): + if self.selected_SVG is None: + raise Exception(_("No widget selected")) + transform = XSLTransform( + os.path.join(ScriptDirectory, "analyse_widget.xslt"),[]) + svgdom = etree.parse(self.selected_SVG) + result = transform.transform(svgdom) + for entry in transform.get_error_log(): + self.msg += "XSLT: " + entry.message + "\n" + except XSLTApplyError as e: + self.msg += "Widget analysis error: " + e.message + def UpdateUI(self, signature): + if signature is not None: + print(etree.tostring(signature, pretty_print=True)) + widgets = signature.getroot() + widget_type = widget.get("type") + path_value = path.get("value") + str.strip, path.get("accepts", '')[1:-1].split(',')) + print(path_value, path_accepts) def ValidateWidget(self):
+ signature = self.AnalyseWidget() + self.UpdateUI(signature) if self.tempf is not None:
os.unlink(self.tempf.name)
--- a/svghmi/widgetlib/modern_knob_1.svg Sun May 02 23:43:57 2021 +0200
+++ b/svghmi/widgetlib/modern_knob_1.svg Mon May 03 00:04:08 2021 +0200
@@ -159,16 +159,16 @@
inkscape:pageopacity="0.0"
- inkscape:cx="41.428571"
- inkscape:cy="555.71429"
+ inkscape:zoom="1.979899" + inkscape:cx="208.80035" inkscape:document-units="mm"
- inkscape:current-layer="svg2637"
+ inkscape:current-layer="g3058" - inkscape:window-width="1414"
- inkscape:window-height="840"
- inkscape:window-x="1690"
- inkscape:window-y="117"
+ inkscape:window-width="1623" + inkscape:window-height="1446" + inkscape:window-x="3346" + inkscape:window-y="244" inkscape:window-maximized="0" />
@@ -178,7 +178,7 @@
<dc:format>image/svg+xml</dc:format>
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
@@ -206,7 +206,7 @@
style="fill:none;stroke-width:1.47405899"
transform="matrix(0.53304115,0,0,0.53229017,1417.5153,1776.3135)"
- inkscape:label="HMI:CircularBar@/CIRCULARBAR"
+ inkscape:label="HMI:CircularBar@value[HMI_REAL,HMI_INT]0,111@label[HMI_STRING]"