svghmi/ui.py
branchsvghmi
changeset 3259 76da573569a6
parent 3255 07f10dc95d2f
child 3261 06ea7a1152af
equal deleted inserted replaced
3255:07f10dc95d2f 3259:76da573569a6
    10 import os
    10 import os
    11 import hashlib
    11 import hashlib
    12 import weakref
    12 import weakref
    13 import re
    13 import re
    14 from functools import reduce
    14 from functools import reduce
       
    15 from itertools import izip
    15 from operator import or_
    16 from operator import or_
    16 from tempfile import NamedTemporaryFile
    17 from tempfile import NamedTemporaryFile
    17 
    18 
    18 import wx
    19 import wx
    19 from wx.lib.scrolledpanel import ScrolledPanel
    20 from wx.lib.scrolledpanel import ScrolledPanel
   211         else :
   212         else :
   212             self.validity_sbmp.Show(False)
   213             self.validity_sbmp.Show(False)
   213 
   214 
   214 models = { typename: re.compile(regex) for typename, regex in [
   215 models = { typename: re.compile(regex) for typename, regex in [
   215     ("string", r".*"),
   216     ("string", r".*"),
   216     ("int", r"^-?[1-9][0-9]*$"),
   217     ("int", r"^-?([1-9][0-9]|0)*$"),
   217     ("real", r"^-?[1-9][0-9]*(\.[0-9]+)?$")]}
   218     ("real", r"^-?([1-9][0-9]|0)*(\.[0-9]+)?$")]}
   218 
   219 
   219 class ArgEditor(ParamEditor):
   220 class ArgEditor(ParamEditor):
   220     def __init__(self, parent, argdesc):
   221     def __init__(self, parent, argdesc, prefillargdesc):
   221         ParamEditor.__init__(self, parent, argdesc)
   222         ParamEditor.__init__(self, parent, argdesc)
   222         self.ParentObj = parent
   223         self.ParentObj = parent
   223         self.argdesc = argdesc
   224         self.argdesc = argdesc
   224         self.Bind(wx.EVT_TEXT, self.OnArgChanged, self.edit)
   225         self.Bind(wx.EVT_TEXT, self.OnArgChanged, self.edit)
       
   226         prefill = "" if prefillargdesc is None else prefillargdesc.get("value")
       
   227         self.edit.SetValue(prefill)
       
   228         # TODO add a button to add more ArgEditror instance 
       
   229         #      when ordinality is multiple
   225 
   230 
   226     def OnArgChanged(self, event):
   231     def OnArgChanged(self, event):
   227         txt = self.edit.GetValue()
   232         txt = self.edit.GetValue()
   228         accepts = self.argdesc.get("accepts").split(',')
   233         accepts = self.argdesc.get("accepts").split(',')
   229         self.setValidity(
   234         self.setValidity(
   256         # TODO : find corresponding hmitre node and type to update validity
   261         # TODO : find corresponding hmitre node and type to update validity
   257         # Lazy way : hide validity
   262         # Lazy way : hide validity
   258         self.setValidity(None)
   263         self.setValidity(None)
   259         event.Skip()
   264         event.Skip()
   260     
   265     
       
   266 def KeepDoubleNewLines(txt):
       
   267     return "\n\n".join(map(
       
   268         lambda s:re.sub(r'\s+',' ',s),
       
   269         txt.split("\n\n")))
   261 
   270 
   262 _conf_key = "SVGHMIWidgetLib"
   271 _conf_key = "SVGHMIWidgetLib"
   263 _preview_height = 200
   272 _preview_height = 200
   264 _preview_margin = 5
   273 _preview_margin = 5
   265 class WidgetLibBrowser(wx.SplitterWindow):
   274 class WidgetLibBrowser(wx.SplitterWindow):
   309         self.staticmsg = wx.StaticText(self, label = _("Drag selected Widget from here to Inkscape"))
   318         self.staticmsg = wx.StaticText(self, label = _("Drag selected Widget from here to Inkscape"))
   310         self.preview = wx.Panel(self.main_panel, size=(-1, _preview_height + _preview_margin*2))
   319         self.preview = wx.Panel(self.main_panel, size=(-1, _preview_height + _preview_margin*2))
   311         self.signature_sizer = wx.BoxSizer(wx.VERTICAL)
   320         self.signature_sizer = wx.BoxSizer(wx.VERTICAL)
   312         self.args_box = wx.StaticBox(self.main_panel, -1,
   321         self.args_box = wx.StaticBox(self.main_panel, -1,
   313                                      _("Widget's arguments"),
   322                                      _("Widget's arguments"),
   314                                      style = wx.ALIGN_RIGHT)
   323                                      style = wx.ALIGN_CENTRE_HORIZONTAL)
   315         self.args_sizer = wx.StaticBoxSizer(self.args_box, wx.VERTICAL)
   324         self.args_sizer = wx.StaticBoxSizer(self.args_box, wx.VERTICAL)
   316         self.paths_box = wx.StaticBox(self.main_panel, -1,
   325         self.paths_box = wx.StaticBox(self.main_panel, -1,
   317                                       _("Widget's variables"),
   326                                       _("Widget's variables"),
   318                                       style = wx.ALIGN_RIGHT)
   327                                       style = wx.ALIGN_CENTRE_HORIZONTAL)
   319         self.paths_sizer = wx.StaticBoxSizer(self.paths_box, wx.VERTICAL)
   328         self.paths_sizer = wx.StaticBoxSizer(self.paths_box, wx.VERTICAL)
   320         self.signature_sizer.Add(self.args_sizer, flag=wx.GROW)
   329         self.signature_sizer.Add(self.args_sizer, flag=wx.GROW)
   321         self.signature_sizer.AddSpacer(5)
   330         self.signature_sizer.AddSpacer(5)
   322         self.signature_sizer.Add(self.paths_sizer, flag=wx.GROW)
   331         self.signature_sizer.Add(self.paths_sizer, flag=wx.GROW)
   323         self.main_sizer.Add(self.staticmsg, flag=wx.GROW)
   332         self.main_sizer.Add(self.staticmsg, flag=wx.GROW)
   350         self.paths_sizer.Clear()
   359         self.paths_sizer.Clear()
   351         for editor in self.paths_editors:
   360         for editor in self.paths_editors:
   352             editor.Destroy()
   361             editor.Destroy()
   353         self.paths_editors = []
   362         self.paths_editors = []
   354 
   363 
   355     def AddArgToSignature(self, arg):
   364     def AddArgToSignature(self, arg, prefillarg):
   356         new_editor = ArgEditor(self, arg)
   365         new_editor = ArgEditor(self, arg, prefillarg)
   357         self.args_editors.append(new_editor)
   366         self.args_editors.append(new_editor)
   358         self.args_sizer.Add(new_editor, flag=wx.GROW)
   367         self.args_sizer.Add(new_editor, flag=wx.GROW)
   359 
   368 
   360     def AddPathToSignature(self, path):
   369     def AddPathToSignature(self, path):
   361         new_editor = PathEditor(self, path)
   370         new_editor = PathEditor(self, path)
   529             for entry in transform.get_error_log():
   538             for entry in transform.get_error_log():
   530                 self.msg += "XSLT: " + entry.message + "\n" 
   539                 self.msg += "XSLT: " + entry.message + "\n" 
   531 
   540 
   532         except Exception as e:
   541         except Exception as e:
   533             self.msg += str(e)
   542             self.msg += str(e)
       
   543             return
   534         except XSLTApplyError as e:
   544         except XSLTApplyError as e:
   535             self.msg += "Widget " + fname + " analysis error: " + e.message
   545             self.msg += "Widget " + fname + " analysis error: " + e.message
   536         else:
   546             return
   537             
   547             
   538             self.msg += "Widget " + fname + ": OK"
   548         self.msg += "Widget " + fname + ": OK"
   539 
   549 
   540             print(etree.tostring(signature, pretty_print=True))
   550         print(etree.tostring(signature, pretty_print=True))
   541             widgets = signature.getroot()
   551         widgets = signature.getroot()
   542             for defs in widgets.iter("defs"):
   552         widget = widgets.find("widget")
   543 
   553         defs = widget.find("defs")
   544                 # Keep double newlines (to mark paragraphs)
   554         # Keep double newlines (to mark paragraphs)
   545                 self.desc.SetValue(defs.find("type").text + ":\n" + "\n\n".join(map(
   555         widget_desc = widget.find("desc")
   546                     lambda s:s.replace("\n"," ").replace("  ", " "),
   556         self.desc.SetValue(
   547                     defs.find("longdesc").text.split("\n\n"))))
   557             fname + ":\n" + (
   548                 args = [arg for arg in defs.iter("arg")]
   558                 _("No description given") if widget_desc is None else 
   549                 self.args_box.Show(len(args)!=0)
   559                 KeepDoubleNewLines(widget_desc.text)
   550                 for arg in args:
   560             ) + "\n\n" +
   551                     self.AddArgToSignature(arg)
   561             defs.find("type").text + ":\n" +
   552                     print(arg.get("name"))
   562             KeepDoubleNewLines(defs.find("longdesc").text))
   553                     print(arg.get("accepts"))
   563         prefillargs = widget.findall("arg")
   554                 paths = [path for path in defs.iter("path")]
   564         args = defs.findall("arg")
   555                 self.paths_box.Show(len(paths)!=0)
   565         # extend args description in prefilled args in longer 
   556                 for path in paths:
   566         # (case of variable list of args)
   557                     self.AddPathToSignature(path)
   567         if len(prefillargs) < len(args):
   558                     print(path.get("name"))
   568             prefillargs += [None]*(len(args)-len(prefillargs))
   559                     print(path.get("accepts"))
   569         if args and len(prefillargs) > len(args):
   560 
   570             # TODO: check ordinality of last arg
   561             for widget in widgets:
   571             # TODO: check that only last arg has multiple ordinality
   562                 widget_type = widget.get("type")
   572             args += [args[-1]]*(len(prefillargs)-len(args))
   563                 print(widget_type)
   573         self.args_box.Show(len(args)!=0)
   564                 for path in widget.iterchildren("path"):
   574         for arg, prefillarg in izip(args,prefillargs):
   565                     path_value = path.get("value")
   575             self.AddArgToSignature(arg, prefillarg)
   566                     path_accepts = map(
   576             print(arg.get("name"))
   567                         str.strip, path.get("accepts", '')[1:-1].split(','))
   577             print(arg.get("accepts"))
   568                     print(path, path_value, path_accepts)
   578         paths = defs.findall("path")
       
   579         self.paths_box.Show(len(paths)!=0)
       
   580         for path in paths:
       
   581             self.AddPathToSignature(path)
       
   582             print(path.get("name"))
       
   583             print(path.get("accepts"))
       
   584 
       
   585         for widget in widgets:
       
   586             widget_type = widget.get("type")
       
   587             print(widget_type)
       
   588             for path in widget.iterchildren("path"):
       
   589                 path_value = path.get("value")
       
   590                 path_accepts = map(
       
   591                     str.strip, path.get("accepts", '')[1:-1].split(','))
       
   592                 print(path, path_value, path_accepts)
   569 
   593 
   570         self.main_panel.SetupScrolling(scroll_x=False)
   594         self.main_panel.SetupScrolling(scroll_x=False)
   571 
   595 
   572 
   596 
   573 
   597