wxglade_hmi/wxglade_hmi.py
changeset 1784 64beb9e9c749
parent 1768 691083b5682a
child 1832 0f1081928d65
equal deleted inserted replaced
1729:31e63e25b4cc 1784:64beb9e9c749
    22 # You should have received a copy of the GNU General Public License
    22 # You should have received a copy of the GNU General Public License
    23 # along with this program; if not, write to the Free Software
    23 # along with this program; if not, write to the Free Software
    24 # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
    24 # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
    25 
    25 
    26 import wx
    26 import wx
    27 import os, sys, shutil
    27 import os
       
    28 import sys
       
    29 import shutil
    28 from xml.dom import minidom
    30 from xml.dom import minidom
    29 
    31 
    30 import util.paths as paths
    32 import util.paths as paths
    31 from py_ext import PythonFileCTNMixin
    33 from py_ext import PythonFileCTNMixin
    32 
    34 
       
    35 
    33 class WxGladeHMI(PythonFileCTNMixin):
    36 class WxGladeHMI(PythonFileCTNMixin):
    34 
    37 
    35     ConfNodeMethods = [
    38     ConfNodeMethods = [
    36         {"bitmap" : "editWXGLADE",
    39         {
    37          "name" : _("WXGLADE GUI"),
    40             "bitmap":    "editWXGLADE",
    38          "tooltip" : _("Edit a WxWidgets GUI with WXGlade"),
    41             "name":    _("WXGLADE GUI"),
    39          "method" : "_editWXGLADE"},
    42             "tooltip": _("Edit a WxWidgets GUI with WXGlade"),
       
    43             "method":   "_editWXGLADE"
       
    44         },
    40     ]
    45     ]
    41 
    46 
    42     def GetIconName(self):
    47     def GetIconName(self):
    43         return "wxGlade"
    48         return "wxGlade"
    44 
    49 
    49         if project_path is None:
    54         if project_path is None:
    50             project_path = self.CTNPath()
    55             project_path = self.CTNPath()
    51         # define name for wxGlade gui file
    56         # define name for wxGlade gui file
    52         return os.path.join(project_path, "hmi.wxg")
    57         return os.path.join(project_path, "hmi.wxg")
    53 
    58 
    54 
       
    55     def GetWxGladePath(self):
    59     def GetWxGladePath(self):
    56         path = None
    60         path = None
    57         try:
    61         try:
    58             from wxglade import __file__ as fileName
    62             from wxglade import __file__ as fileName
    59             path = os.path.dirname(fileName)         
    63             path = os.path.dirname(fileName)
    60             return path
    64             return path
    61         except ImportError:
    65         except ImportError:
    62             pass
    66             pass
    63 
    67 
    64         defLibDir="/usr/share/wxglade"
    68         defLibDir = "/usr/share/wxglade"
    65         if os.path.isdir(defLibDir):
    69         if os.path.isdir(defLibDir):
    66             path = defLibDir
    70             path = defLibDir
    67 
    71 
    68         return path
    72         return path
    69     
    73 
    70     def launch_wxglade(self, options, wait=False):
    74     def launch_wxglade(self, options, wait=False):
    71         path = self.GetWxGladePath()
    75         path = self.GetWxGladePath()
    72         glade = os.path.join(path, 'wxglade.py')
    76         glade = os.path.join(path, 'wxglade.py')
    73         if wx.Platform == '__WXMSW__':
    77         if wx.Platform == '__WXMSW__':
    74             glade = "\"%s\""%glade
    78             glade = "\"%s\"" % glade
    75         mode = {False:os.P_NOWAIT, True:os.P_WAIT}[wait]
    79         mode = {False: os.P_NOWAIT, True: os.P_WAIT}[wait]
    76         os.spawnv(mode, sys.executable, ["\"%s\""%sys.executable] + [glade] + options)
    80         os.spawnv(mode, sys.executable, ["\"%s\"" % sys.executable] + [glade] + options)
    77 
    81 
    78     def OnCTNSave(self, from_project_path=None):
    82     def OnCTNSave(self, from_project_path=None):
    79         if from_project_path is not None:
    83         if from_project_path is not None:
    80             shutil.copyfile(self._getWXGLADEpath(from_project_path),
    84             shutil.copyfile(self._getWXGLADEpath(from_project_path),
    81                             self._getWXGLADEpath())
    85                             self._getWXGLADEpath())
    82         return PythonFileCTNMixin.OnCTNSave(self, from_project_path)
    86         return PythonFileCTNMixin.OnCTNSave(self, from_project_path)
    83 
    87 
    84     def CTNGenerate_C(self, buildpath, locations):
    88     def CTNGenerate_C(self, buildpath, locations):
    85         
    89 
    86         hmi_frames = []
    90         hmi_frames = []
    87         
    91 
    88         wxgfile_path=self._getWXGLADEpath()
    92         wxgfile_path = self._getWXGLADEpath()
    89         if os.path.exists(wxgfile_path):
    93         if os.path.exists(wxgfile_path):
    90             wxgfile = open(wxgfile_path, 'r')
    94             wxgfile = open(wxgfile_path, 'r')
    91             wxgtree = minidom.parse(wxgfile)
    95             wxgtree = minidom.parse(wxgfile)
    92             wxgfile.close()
    96             wxgfile.close()
    93             
    97 
    94             for node in wxgtree.childNodes[1].childNodes:
    98             for node in wxgtree.childNodes[1].childNodes:
    95                 if node.nodeType == wxgtree.ELEMENT_NODE:
    99                 if node.nodeType == wxgtree.ELEMENT_NODE:
    96                     hmi_frames.append({
   100                     hmi_frames.append({
    97                         "name" : node.getAttribute("name"),
   101                         "name": node.getAttribute("name"),
    98                         "class" : node.getAttribute("class"),
   102                         "class": node.getAttribute("class"),
    99                         "handlers" : [
   103                         "handlers": [
   100                             hnode.firstChild.data for hnode in 
   104                             hnode.firstChild.data for hnode in
   101                             node.getElementsByTagName("handler")]})
   105                             node.getElementsByTagName("handler")]})
   102                     
   106 
   103             hmipyfile_path=os.path.join(self._getBuildPath(), "hmi.py")
   107             hmipyfile_path = os.path.join(self._getBuildPath(), "hmi.py")
   104             if wx.Platform == '__WXMSW__':
   108             if wx.Platform == '__WXMSW__':
   105                 wxgfile_path = "\"%s\""%wxgfile_path
   109                 wxgfile_path = "\"%s\"" % wxgfile_path
   106                 wxghmipyfile_path = "\"%s\""%hmipyfile_path
   110                 wxghmipyfile_path = "\"%s\"" % hmipyfile_path
   107             else:
   111             else:
   108                 wxghmipyfile_path = hmipyfile_path
   112                 wxghmipyfile_path = hmipyfile_path
   109             self.launch_wxglade(['-o', wxghmipyfile_path, '-g', 'python', wxgfile_path], wait=True)
   113             self.launch_wxglade(['-o', wxghmipyfile_path, '-g', 'python', wxgfile_path], wait=True)
   110             
   114 
   111             hmipyfile = open(hmipyfile_path, 'r')
   115             hmipyfile = open(hmipyfile_path, 'r')
   112             define_hmi = hmipyfile.read().decode('utf-8')
   116             define_hmi = hmipyfile.read().decode('utf-8')
   113             hmipyfile.close()
   117             hmipyfile.close()
   114         
   118 
   115         else:
   119         else:
   116             define_hmi = ""
   120             define_hmi = ""
   117         
   121 
   118         declare_hmi = "\n".join(["%(name)s = None\n" % x + 
   122         declare_hmi = "\n".join(["%(name)s = None\n" % x +
   119                           "\n".join(["%(class)s.%(h)s = %(h)s"%
   123                                  "\n".join(["%(class)s.%(h)s = %(h)s" %
   120                             dict(x,h=h) for h in x['handlers']])
   124                                             dict(x, h=h) for h in x['handlers']])
   121                                 for x in hmi_frames])
   125                                 for x in hmi_frames])
   122         global_hmi = ("global %s\n"%",".join(
   126         global_hmi = ("global %s\n" % ",".join(
   123                          [x["name"] for x in hmi_frames]) 
   127                          [x["name"] for x in hmi_frames])
   124                       if len(hmi_frames) > 0 else "")
   128                       if len(hmi_frames) > 0 else "")
   125         init_hmi = "\n".join(["""\
   129         init_hmi = "\n".join(["""\
   126 def OnCloseFrame(evt):
   130 def OnCloseFrame(evt):
   127     wx.MessageBox(_("Please stop PLC to close"))
   131     wx.MessageBox(_("Please stop PLC to close"))
   128 
   132 
   129 %(name)s = %(class)s(None)
   133 %(name)s = %(class)s(None)
   130 %(name)s.Bind(wx.EVT_CLOSE, OnCloseFrame)
   134 %(name)s.Bind(wx.EVT_CLOSE, OnCloseFrame)
   131 %(name)s.Show()
   135 %(name)s.Show()
   132 """ % x for x in hmi_frames])
   136 """ % x for x in hmi_frames])
   133         cleanup_hmi = "\n".join(
   137         cleanup_hmi = "\n".join(
   134             ["if %(name)s is not None: %(name)s.Destroy()" % x 
   138             ["if %(name)s is not None: %(name)s.Destroy()" % x
   135                 for x in hmi_frames])
   139                 for x in hmi_frames])
   136         
   140 
   137         self.PreSectionsTexts = {
   141         self.PreSectionsTexts = {
   138             "globals":define_hmi,
   142             "globals": define_hmi,
   139             "start":global_hmi,
   143             "start":   global_hmi,
   140             "stop":global_hmi + cleanup_hmi
   144             "stop":    global_hmi + cleanup_hmi
   141         }
   145         }
   142         self.PostSectionsTexts = {
   146         self.PostSectionsTexts = {
   143             "globals":declare_hmi,
   147             "globals": declare_hmi,
   144             "start":init_hmi,
   148             "start":   init_hmi,
   145         }
   149         }
   146 
   150 
   147         return PythonFileCTNMixin.CTNGenerate_C(self, buildpath, locations)
   151         return PythonFileCTNMixin.CTNGenerate_C(self, buildpath, locations)
   148 
   152 
   149     def _editWXGLADE(self):
   153     def _editWXGLADE(self):
   151         open_wxglade = True
   155         open_wxglade = True
   152         if not self.GetCTRoot().CheckProjectPathPerm():
   156         if not self.GetCTRoot().CheckProjectPathPerm():
   153             dialog = wx.MessageDialog(self.GetCTRoot().AppFrame,
   157             dialog = wx.MessageDialog(self.GetCTRoot().AppFrame,
   154                                       _("You don't have write permissions.\nOpen wxGlade anyway ?"),
   158                                       _("You don't have write permissions.\nOpen wxGlade anyway ?"),
   155                                       _("Open wxGlade"),
   159                                       _("Open wxGlade"),
   156                                       wx.YES_NO|wx.ICON_QUESTION)
   160                                       wx.YES_NO | wx.ICON_QUESTION)
   157             open_wxglade = dialog.ShowModal() == wx.ID_YES
   161             open_wxglade = dialog.ShowModal() == wx.ID_YES
   158             dialog.Destroy()
   162             dialog.Destroy()
   159         if open_wxglade:
   163         if open_wxglade:
   160             if not os.path.exists(wxg_filename):
   164             if not os.path.exists(wxg_filename):
   161                 hmi_name = self.BaseParams.getName()
   165                 hmi_name = self.BaseParams.getName()
   162                 open(wxg_filename,"w").write("""<?xml version="1.0"?>
   166                 open(wxg_filename, "w").write("""<?xml version="1.0"?>
   163     <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">
   167     <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">
   164         <object class="%(class)s" name="%(name)s" base="EditFrame">
   168         <object class="%(class)s" name="%(name)s" base="EditFrame">
   165             <style>wxDEFAULT_FRAME_STYLE</style>
   169             <style>wxDEFAULT_FRAME_STYLE</style>
   166             <title>frame_1</title>
   170             <title>frame_1</title>
   167             <object class="wxBoxSizer" name="sizer_1" base="EditBoxSizer">
   171             <object class="wxBoxSizer" name="sizer_1" base="EditBoxSizer">
   170         </object>
   174         </object>
   171         </object>
   175         </object>
   172     </application>
   176     </application>
   173     """ % {"name": hmi_name, "class": "Class_%s" % hmi_name})
   177     """ % {"name": hmi_name, "class": "Class_%s" % hmi_name})
   174             if wx.Platform == '__WXMSW__':
   178             if wx.Platform == '__WXMSW__':
   175                 wxg_filename = "\"%s\""%wxg_filename
   179                 wxg_filename = "\"%s\"" % wxg_filename
   176             self.launch_wxglade([wxg_filename])
   180             self.launch_wxglade([wxg_filename])
   177