confnodes/python/modules/wxglade_hmi/wxglade_hmi.py
changeset 721 ecf4d203c4d4
parent 720 6be032177e2a
child 722 a94f361fc42e
equal deleted inserted replaced
720:6be032177e2a 721:ecf4d203c4d4
     1 import wx
       
     2 import os, sys
       
     3 from xml.dom import minidom
       
     4 
       
     5 from ConfigTree import opjimg
       
     6 from confnodes.python import PythonCodeTemplate
       
     7 
       
     8 class RootClass(PythonCodeTemplate):
       
     9 
       
    10     ConfNodeMethods = [
       
    11         {"bitmap" : opjimg("editWXGLADE"),
       
    12          "name" : _("WXGLADE GUI"),
       
    13          "tooltip" : _("Edit a WxWidgets GUI with WXGlade"),
       
    14          "method" : "_editWXGLADE"},
       
    15     ]
       
    16 
       
    17     def _getWXGLADEpath(self):
       
    18         # define name for IEC raw code file
       
    19         return os.path.join(self.CTNPath(), "hmi.wxg")
       
    20 
       
    21     def launch_wxglade(self, options, wait=False):
       
    22         from wxglade import __file__ as fileName
       
    23         path = os.path.dirname(fileName)
       
    24         glade = os.path.join(path, 'wxglade.py')
       
    25         if wx.Platform == '__WXMSW__':
       
    26             glade = "\"%s\""%glade
       
    27         mode = {False:os.P_NOWAIT, True:os.P_WAIT}[wait]
       
    28         os.spawnv(mode, sys.executable, ["\"%s\""%sys.executable] + [glade] + options)
       
    29 
       
    30 
       
    31     def CTNGenerate_C(self, buildpath, locations):
       
    32         """
       
    33         Return C code generated by iec2c compiler 
       
    34         when _generate_softPLC have been called
       
    35         @param locations: ignored
       
    36         @return: [(C_file_name, CFLAGS),...] , LDFLAGS_TO_APPEND
       
    37         """
       
    38         
       
    39         current_location = self.GetCurrentLocation()
       
    40         # define a unique name for the generated C file
       
    41         location_str = "_".join(map(lambda x:str(x), current_location))
       
    42         
       
    43         runtimefile_path = os.path.join(buildpath, "runtime_%s.py"%location_str)
       
    44         runtimefile = open(runtimefile_path, 'w')
       
    45         
       
    46         hmi_frames = {}
       
    47         
       
    48         wxgfile_path=self._getWXGLADEpath()
       
    49         if os.path.exists(wxgfile_path):
       
    50             wxgfile = open(wxgfile_path, 'r')
       
    51             wxgtree = minidom.parse(wxgfile)
       
    52             wxgfile.close()
       
    53             
       
    54             for node in wxgtree.childNodes[1].childNodes:
       
    55                 if node.nodeType == wxgtree.ELEMENT_NODE:
       
    56                     hmi_frames[node._attrs["name"].value] =  node._attrs["class"].value
       
    57                     
       
    58             hmipyfile_path=os.path.join(self._getBuildPath(), "hmi.py")
       
    59             if wx.Platform == '__WXMSW__':
       
    60                 wxgfile_path = "\"%s\""%wxgfile_path
       
    61                 wxghmipyfile_path = "\"%s\""%hmipyfile_path
       
    62             else:
       
    63                 wxghmipyfile_path = hmipyfile_path
       
    64             self.launch_wxglade(['-o', wxghmipyfile_path, '-g', 'python', wxgfile_path], wait=True)
       
    65             
       
    66             hmipyfile = open(hmipyfile_path, 'r')
       
    67             runtimefile.write(hmipyfile.read())
       
    68             hmipyfile.close()
       
    69         
       
    70         runtimefile.write(self.GetPythonCode())
       
    71         runtimefile.write("""
       
    72 %(declare)s
       
    73 
       
    74 def _runtime_%(location)s_begin():
       
    75     global %(global)s
       
    76     
       
    77     def OnCloseFrame(evt):
       
    78         wx.MessageBox(_("Please stop PLC to close"))
       
    79     
       
    80     %(init)s
       
    81     
       
    82 def _runtime_%(location)s_cleanup():
       
    83     global %(global)s
       
    84     
       
    85     %(cleanup)s
       
    86 
       
    87 """ % {"location": location_str,
       
    88        "declare": "\n".join(map(lambda x:"%s = None" % x, hmi_frames.keys())),
       
    89        "global": ",".join(hmi_frames.keys()),
       
    90        "init": "\n".join(map(lambda x: """
       
    91     %(name)s = %(class)s(None)
       
    92     %(name)s.Bind(wx.EVT_CLOSE, OnCloseFrame)
       
    93     %(name)s.Show()
       
    94 """ % {"name": x[0], "class": x[1]},
       
    95                              hmi_frames.items())),
       
    96        "cleanup": "\n    ".join(map(lambda x:"%s.Destroy()" % x, hmi_frames.keys()))})
       
    97         runtimefile.close()
       
    98         
       
    99         return [], "", False, ("runtime_%s.py"%location_str, file(runtimefile_path,"rb"))
       
   100 
       
   101     def _editWXGLADE(self):
       
   102         wxg_filename = self._getWXGLADEpath()
       
   103         open_wxglade = True
       
   104         if not self.GetCTRoot().CheckProjectPathPerm():
       
   105             dialog = wx.MessageDialog(self.GetCTRoot().AppFrame,
       
   106                                       _("You don't have write permissions.\nOpen wxGlade anyway ?"),
       
   107                                       _("Open wxGlade"),
       
   108                                       wx.YES_NO|wx.ICON_QUESTION)
       
   109             open_wxglade = dialog.ShowModal() == wx.ID_YES
       
   110             dialog.Destroy()
       
   111         if open_wxglade:
       
   112             if not os.path.exists(wxg_filename):
       
   113                 hmi_name = self.BaseParams.getName()
       
   114                 open(wxg_filename,"w").write("""<?xml version="1.0"?>
       
   115     <application path="" name="" class="" option="0" language="python" top_window="%(name)s" encoding="UTF-8" use_gettext="0" overwrite="0" use_new_namespace="1" for_version="2.8" is_template="0">
       
   116         <object class="%(class)s" name="%(name)s" base="EditFrame">
       
   117             <style>wxDEFAULT_FRAME_STYLE</style>
       
   118             <title>frame_1</title>
       
   119         </object>
       
   120     </application>
       
   121     """ % {"name": hmi_name, "class": "Class_%s" % hmi_name})
       
   122             if wx.Platform == '__WXMSW__':
       
   123                 wxg_filename = "\"%s\""%wxg_filename
       
   124             self.launch_wxglade([wxg_filename])