svghmi/ui.py
branchsvghmi
changeset 3263 1205b2d0acf2
parent 3261 06ea7a1152af
child 3265 f3cb352048b6
equal deleted inserted replaced
3262:689ac4ac0dbe 3263:1205b2d0acf2
    86         """
    86         """
    87         Called when a drag is started in tree
    87         Called when a drag is started in tree
    88         @param event: wx.TreeEvent
    88         @param event: wx.TreeEvent
    89         """
    89         """
    90         if self.ordered_items:
    90         if self.ordered_items:
    91             print("boink")
       
    92             # Just send a recognizable mime-type, drop destination
    91             # Just send a recognizable mime-type, drop destination
    93             # will get python data from parent
    92             # will get python data from parent
    94             data = wx.CustomDataObject(HMITreeDndMagicWord)
    93             data = wx.CustomDataObject(HMITreeDndMagicWord)
    95             dragSource = wx.DropSource(self)
    94             dragSource = wx.DropSource(self)
    96             dragSource.SetData(data)
    95             dragSource.SetData(data)
   216         else :
   215         else :
   217             self.validity_sbmp.Show(False)
   216             self.validity_sbmp.Show(False)
   218 
   217 
   219 models = { typename: re.compile(regex) for typename, regex in [
   218 models = { typename: re.compile(regex) for typename, regex in [
   220     ("string", r".*"),
   219     ("string", r".*"),
   221     ("int", r"^-?([1-9][0-9]|0)*$"),
   220     ("int", r"^-?([1-9][0-9]*|0)$"),
   222     ("real", r"^-?([1-9][0-9]|0)*(\.[0-9]+)?$")]}
   221     ("real", r"^-?([1-9][0-9]*|0)(\.[0-9]+)?$")]}
   223 
   222 
   224 class ArgEditor(ParamEditor):
   223 class ArgEditor(ParamEditor):
   225     def __init__(self, parent, argdesc, prefillargdesc):
   224     def __init__(self, parent, argdesc, prefillargdesc):
   226         ParamEditor.__init__(self, parent, argdesc)
   225         ParamEditor.__init__(self, parent, argdesc)
   227         self.ParentObj = parent
   226         self.ParentObj = parent
   362                   self.RegenSVGTimer)
   361                   self.RegenSVGTimer)
   363 
   362 
   364         self.args_editors = []
   363         self.args_editors = []
   365         self.paths_editors = []
   364         self.paths_editors = []
   366 
   365 
       
   366     def SetMessage(self, msg):
       
   367         self.staticmsg.SetLabel(msg)
       
   368         self.main_sizer.Layout()
       
   369 
   367     def ResetSignature(self):
   370     def ResetSignature(self):
   368         self.args_sizer.Clear()
   371         self.args_sizer.Clear()
   369         for editor in self.args_editors:
   372         for editor in self.args_editors:
   370             editor.Destroy()
   373             editor.Destroy()
   371         self.args_editors = []
   374         self.args_editors = []
   495 
   498 
   496                 self.selected_SVG = svgpath if have_thumb else None
   499                 self.selected_SVG = svgpath if have_thumb else None
   497 
   500 
   498                 self.AnalyseWidgetAndUpdateUI(fname)
   501                 self.AnalyseWidgetAndUpdateUI(fname)
   499 
   502 
   500                 self.staticmsg.SetLabel(self.msg)
   503                 self.SetMessage(self.msg)
   501 
   504 
   502             except IOError:
   505             except IOError:
   503                 self.msg = _("Widget library must be writable")
   506                 self.msg = _("Widget library must be writable")
   504 
   507 
   505             self.Refresh()
   508             self.Refresh()
   516             dropSource = wx.DropSource(self)
   519             dropSource = wx.DropSource(self)
   517             dropSource.SetData(data)
   520             dropSource.SetData(data)
   518             dropSource.DoDragDrop(wx.Drag_AllowMove)
   521             dropSource.DoDragDrop(wx.Drag_AllowMove)
   519 
   522 
   520     def RegenSVGLater(self, when=1):
   523     def RegenSVGLater(self, when=1):
       
   524         self.SetMessage(_("SVG generation pending"))
   521         self.RegenSVGTimer.Start(milliseconds=when*1000, oneShot=True)
   525         self.RegenSVGTimer.Start(milliseconds=when*1000, oneShot=True)
   522 
   526 
   523     def RegenSVGNow(self):
   527     def RegenSVGNow(self):
   524         self.RegenSVGLater(when=0)
   528         self.RegenSVGLater(when=0)
   525 
   529 
   526     def RegenSVG(self, event):
   530     def RegenSVG(self, event):
       
   531         self.SetMessage(_("Generating SVG..."))
   527         args = [arged.GetValue() for arged in self.args_editors]
   532         args = [arged.GetValue() for arged in self.args_editors]
       
   533         while args and not args[-1]: args.pop(-1)
   528         paths = [pathed.GetValue() for pathed in self.paths_editors]
   534         paths = [pathed.GetValue() for pathed in self.paths_editors]
       
   535         while paths and not paths[-1]: paths.pop(-1)
   529         if self.RegenSVGLock.acquire(True):
   536         if self.RegenSVGLock.acquire(True):
   530             self.RegenSVGParams = (args, paths)
   537             self.RegenSVGParams = (args, paths)
   531             if self.RegenSVGThread is None:
   538             if self.RegenSVGThread is None:
   532                 self.RegenSVGThread = \
   539                 self.RegenSVGThread = \
   533                     Thread(target=self.RegenSVGProc,
   540                     Thread(target=self.RegenSVGProc,
   556         self.RegenSVGLock.release()
   563         self.RegenSVGLock.release()
   557 
   564 
   558         wx.CallAfter(self.DoneRegenSVG)
   565         wx.CallAfter(self.DoneRegenSVG)
   559         
   566         
   560     def DoneRegenSVG(self):
   567     def DoneRegenSVG(self):
   561         self.staticmsg.SetLabel(self.msg)
   568         self.SetMessage(self.msg if self.msg else _("SVG ready for drag'n'drop"))
   562         
   569         
   563     def AnalyseWidgetAndUpdateUI(self, fname):
   570     def AnalyseWidgetAndUpdateUI(self, fname):
   564         self.msg = ""
   571         self.msg = ""
   565         self.ResetSignature()
   572         self.ResetSignature()
   566 
   573 
   585             self.msg += "Widget " + fname + " analysis error: " + e.message
   592             self.msg += "Widget " + fname + " analysis error: " + e.message
   586             return
   593             return
   587             
   594             
   588         self.msg += "Widget " + fname + ": OK"
   595         self.msg += "Widget " + fname + ": OK"
   589 
   596 
   590         print(etree.tostring(signature, pretty_print=True))
       
   591         widgets = signature.getroot()
   597         widgets = signature.getroot()
   592         widget = widgets.find("widget")
   598         widget = widgets.find("widget")
   593         defs = widget.find("defs")
   599         defs = widget.find("defs")
   594         # Keep double newlines (to mark paragraphs)
   600         # Keep double newlines (to mark paragraphs)
   595         widget_desc = widget.find("desc")
   601         widget_desc = widget.find("desc")
   596         self.desc.SetValue(
   602         self.desc.SetValue(
   597             fname + ":\n" + (
   603             fname + ":\n" + (
   598                 _("No description given") if widget_desc is None else 
   604                 _("No description given") if widget_desc is None else 
   599                 KeepDoubleNewLines(widget_desc.text)
   605                 KeepDoubleNewLines(widget_desc.text)
   600             ) + "\n\n" +
   606             ) + "\n\n" +
   601             defs.find("type").text + ":\n" +
   607             defs.find("type").text + " Widget:\n" +
   602             KeepDoubleNewLines(defs.find("longdesc").text))
   608             KeepDoubleNewLines(defs.find("longdesc").text))
   603         prefillargs = widget.findall("arg")
   609         prefillargs = widget.findall("arg")
   604         args = defs.findall("arg")
   610         args = defs.findall("arg")
   605         # extend args description in prefilled args in longer 
   611         # extend args description in prefilled args in longer 
   606         # (case of variable list of args)
   612         # (case of variable list of args)
   611             # TODO: check that only last arg has multiple ordinality
   617             # TODO: check that only last arg has multiple ordinality
   612             args += [args[-1]]*(len(prefillargs)-len(args))
   618             args += [args[-1]]*(len(prefillargs)-len(args))
   613         self.args_box.Show(len(args)!=0)
   619         self.args_box.Show(len(args)!=0)
   614         for arg, prefillarg in izip(args,prefillargs):
   620         for arg, prefillarg in izip(args,prefillargs):
   615             self.AddArgToSignature(arg, prefillarg)
   621             self.AddArgToSignature(arg, prefillarg)
   616             print(arg.get("name"))
       
   617             print(arg.get("accepts"))
       
   618         paths = defs.findall("path")
   622         paths = defs.findall("path")
   619         self.paths_box.Show(len(paths)!=0)
   623         self.paths_box.Show(len(paths)!=0)
   620         for path in paths:
   624         for path in paths:
   621             self.AddPathToSignature(path)
   625             self.AddPathToSignature(path)
   622             print(path.get("name"))
       
   623             print(path.get("accepts"))
       
   624 
   626 
   625         for widget in widgets:
   627         for widget in widgets:
   626             widget_type = widget.get("type")
   628             widget_type = widget.get("type")
   627             print(widget_type)
       
   628             for path in widget.iterchildren("path"):
   629             for path in widget.iterchildren("path"):
   629                 path_value = path.get("value")
   630                 path_value = path.get("value")
   630                 path_accepts = map(
   631                 path_accepts = map(
   631                     str.strip, path.get("accepts", '')[1:-1].split(','))
   632                     str.strip, path.get("accepts", '')[1:-1].split(','))
   632                 print(path, path_value, path_accepts)
       
   633 
   633 
   634         self.main_panel.SetupScrolling(scroll_x=False)
   634         self.main_panel.SetupScrolling(scroll_x=False)
   635 
       
   636 
       
   637     def PassMessage(self, _context, msgs):
       
   638         for msg in msgs:
       
   639             self.msg += msg.text + "\n"
       
   640 
   635 
   641     def GetWidgetParams(self, _context):
   636     def GetWidgetParams(self, _context):
   642         args,paths = self.GenDnDSVGParams
   637         args,paths = self.GenDnDSVGParams
   643         root = etree.Element("params")
   638         root = etree.Element("params")
   644         for arg in args:
   639         for arg in args:
   661             if self.selected_SVG is None:
   656             if self.selected_SVG is None:
   662                 raise Exception(_("No widget selected"))
   657                 raise Exception(_("No widget selected"))
   663 
   658 
   664             transform = XSLTransform(
   659             transform = XSLTransform(
   665                 os.path.join(ScriptDirectory, "gen_dnd_widget_svg.xslt"),
   660                 os.path.join(ScriptDirectory, "gen_dnd_widget_svg.xslt"),
   666                 [("GetWidgetParams", self.GetWidgetParams),
   661                 [("GetWidgetParams", self.GetWidgetParams)])
   667                  ("PassMessage", self.PassMessage)])
       
   668 
   662 
   669             svgdom = etree.parse(self.selected_SVG)
   663             svgdom = etree.parse(self.selected_SVG)
   670 
   664 
   671             result = transform.transform(svgdom)
   665             result = transform.transform(svgdom)
   672 
   666