PLCOpenEditor.py
changeset 1451 94e620cbd9de
parent 1388 67c9a9482d24
child 1492 14ce1a631f44
equal deleted inserted replaced
1450:44bf0ba866e9 1451:94e620cbd9de
     1 #!/usr/bin/env python
     1 #!/usr/bin/env python
     2 # -*- coding: utf-8 -*-
     2 # -*- coding: utf-8 -*-
     3 
     3 
     4 #This file is part of PLCOpenEditor, a library implementing an IEC 61131-3 editor
     4 #This file is part of PLCOpenEditor, a library implementing an IEC 61131-3 editor
     5 #based on the plcopen standard. 
     5 #based on the plcopen standard.
     6 #
     6 #
     7 #Copyright (C) 2007: Edouard TISSERANT and Laurent BESSARD
     7 #Copyright (C) 2007: Edouard TISSERANT and Laurent BESSARD
     8 #
     8 #
     9 #See COPYING file for copyrights details.
     9 #See COPYING file for copyrights details.
    10 #
    10 #
    23 #Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
    23 #Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
    24 
    24 
    25 import wx
    25 import wx
    26 import os, sys, platform, time, traceback, getopt
    26 import os, sys, platform, time, traceback, getopt
    27 
    27 
    28 CWD = os.path.split(os.path.realpath(__file__))[0]
    28 beremiz_dir = os.path.dirname(os.path.realpath(__file__))
    29 
    29 
    30 __version__ = "$Revision: 1.130 $"
    30 __version__ = "$Revision: 1.130 $"
    31 
    31 
    32 if __name__ == '__main__':
    32 if __name__ == '__main__':
    33     # Usage message displayed when help request or when error detected in 
    33     # Usage message displayed when help request or when error detected in
    34     # command line
    34     # command line
    35     def usage():
    35     def usage():
    36         print "\nUsage of PLCOpenEditor.py :"
    36         print "\nUsage of PLCOpenEditor.py :"
    37         print "\n   %s [Filepath]\n"%sys.argv[0]
    37         print "\n   %s [Filepath]\n"%sys.argv[0]
    38 
    38 
    41         opts, args = getopt.getopt(sys.argv[1:], "h", ["help"])
    41         opts, args = getopt.getopt(sys.argv[1:], "h", ["help"])
    42     except getopt.GetoptError:
    42     except getopt.GetoptError:
    43         # print help information and exit:
    43         # print help information and exit:
    44         usage()
    44         usage()
    45         sys.exit(2)
    45         sys.exit(2)
    46     
    46 
    47     # Extract if help has been requested
    47     # Extract if help has been requested
    48     for o, a in opts:
    48     for o, a in opts:
    49         if o in ("-h", "--help"):
    49         if o in ("-h", "--help"):
    50             usage()
    50             usage()
    51             sys.exit()
    51             sys.exit()
    52     
    52 
    53     # Extract the optional filename to open
    53     # Extract the optional filename to open
    54     fileOpen = None
    54     fileOpen = None
    55     if len(args) > 1:
    55     if len(args) > 1:
    56         usage()
    56         usage()
    57         sys.exit()
    57         sys.exit()
    58     elif len(args) == 1:
    58     elif len(args) == 1:
    59         fileOpen = args[0]
    59         fileOpen = args[0]
    60     
    60 
    61     # Create wxApp (Need to create App before internationalization because of
    61     # Create wxApp (Need to create App before internationalization because of
    62     # Windows) 
    62     # Windows)
    63     app = wx.PySimpleApp()
    63     app = wx.PySimpleApp()
    64 
    64 
    65     from util.misc import InstallLocalRessources
    65     from util.misc import InstallLocalRessources
    66     InstallLocalRessources(CWD)
    66     InstallLocalRessources(beremiz_dir)
    67 
    67 
    68 from docutil import *
    68 from docutil import *
    69 from IDEFrame import IDEFrame, AppendMenu
    69 from IDEFrame import IDEFrame, AppendMenu
    70 from IDEFrame import TITLE, EDITORTOOLBAR, FILEMENU, EDITMENU, DISPLAYMENU, PROJECTTREE, POUINSTANCEVARIABLESPANEL, LIBRARYTREE, PAGETITLES
    70 from IDEFrame import TITLE, EDITORTOOLBAR, FILEMENU, EDITMENU, DISPLAYMENU, PROJECTTREE, POUINSTANCEVARIABLESPANEL, LIBRARYTREE, PAGETITLES
    71 from IDEFrame import EncodeFileSystemPath, DecodeFileSystemPath
    71 from IDEFrame import EncodeFileSystemPath, DecodeFileSystemPath
    76 #-------------------------------------------------------------------------------
    76 #-------------------------------------------------------------------------------
    77 #                            PLCOpenEditor Main Class
    77 #                            PLCOpenEditor Main Class
    78 #-------------------------------------------------------------------------------
    78 #-------------------------------------------------------------------------------
    79 
    79 
    80 # Define PLCOpenEditor FileMenu extra items id
    80 # Define PLCOpenEditor FileMenu extra items id
    81 [ID_PLCOPENEDITORFILEMENUGENERATE, 
    81 [ID_PLCOPENEDITORFILEMENUGENERATE,
    82 ] = [wx.NewId() for _init_coll_FileMenu_Items in range(1)]
    82 ] = [wx.NewId() for _init_coll_FileMenu_Items in range(1)]
    83 
    83 
    84 class PLCOpenEditor(IDEFrame):
    84 class PLCOpenEditor(IDEFrame):
    85 
    85 
    86     # Compatibility function for wx versions < 2.6
    86     # Compatibility function for wx versions < 2.6
   118         AppendMenu(parent, help='', id=wx.ID_PROPERTIES,
   118         AppendMenu(parent, help='', id=wx.ID_PROPERTIES,
   119               kind=wx.ITEM_NORMAL, text=_(u'&Properties'))
   119               kind=wx.ITEM_NORMAL, text=_(u'&Properties'))
   120         parent.AppendSeparator()
   120         parent.AppendSeparator()
   121         AppendMenu(parent, help='', id=wx.ID_EXIT,
   121         AppendMenu(parent, help='', id=wx.ID_EXIT,
   122               kind=wx.ITEM_NORMAL, text=_(u'Quit') + '\tCTRL+Q')
   122               kind=wx.ITEM_NORMAL, text=_(u'Quit') + '\tCTRL+Q')
   123         
   123 
   124         self.Bind(wx.EVT_MENU, self.OnNewProjectMenu, id=wx.ID_NEW)
   124         self.Bind(wx.EVT_MENU, self.OnNewProjectMenu, id=wx.ID_NEW)
   125         self.Bind(wx.EVT_MENU, self.OnOpenProjectMenu, id=wx.ID_OPEN)
   125         self.Bind(wx.EVT_MENU, self.OnOpenProjectMenu, id=wx.ID_OPEN)
   126         self.Bind(wx.EVT_MENU, self.OnCloseTabMenu, id=wx.ID_CLOSE)
   126         self.Bind(wx.EVT_MENU, self.OnCloseTabMenu, id=wx.ID_CLOSE)
   127         self.Bind(wx.EVT_MENU, self.OnCloseProjectMenu, id=wx.ID_CLOSE_ALL)
   127         self.Bind(wx.EVT_MENU, self.OnCloseProjectMenu, id=wx.ID_CLOSE_ALL)
   128         self.Bind(wx.EVT_MENU, self.OnSaveProjectMenu, id=wx.ID_SAVE)
   128         self.Bind(wx.EVT_MENU, self.OnSaveProjectMenu, id=wx.ID_SAVE)
   132         self.Bind(wx.EVT_MENU, self.OnPageSetupMenu, id=wx.ID_PAGE_SETUP)
   132         self.Bind(wx.EVT_MENU, self.OnPageSetupMenu, id=wx.ID_PAGE_SETUP)
   133         self.Bind(wx.EVT_MENU, self.OnPreviewMenu, id=wx.ID_PREVIEW)
   133         self.Bind(wx.EVT_MENU, self.OnPreviewMenu, id=wx.ID_PREVIEW)
   134         self.Bind(wx.EVT_MENU, self.OnPrintMenu, id=wx.ID_PRINT)
   134         self.Bind(wx.EVT_MENU, self.OnPrintMenu, id=wx.ID_PRINT)
   135         self.Bind(wx.EVT_MENU, self.OnPropertiesMenu, id=wx.ID_PROPERTIES)
   135         self.Bind(wx.EVT_MENU, self.OnPropertiesMenu, id=wx.ID_PROPERTIES)
   136         self.Bind(wx.EVT_MENU, self.OnQuitMenu, id=wx.ID_EXIT)
   136         self.Bind(wx.EVT_MENU, self.OnQuitMenu, id=wx.ID_EXIT)
   137         
   137 
   138         self.AddToMenuToolBar([(wx.ID_NEW, "new", _(u'New'), None),
   138         self.AddToMenuToolBar([(wx.ID_NEW, "new", _(u'New'), None),
   139                                (wx.ID_OPEN, "open", _(u'Open'), None),
   139                                (wx.ID_OPEN, "open", _(u'Open'), None),
   140                                (wx.ID_SAVE, "save", _(u'Save'), None),
   140                                (wx.ID_SAVE, "save", _(u'Save'), None),
   141                                (wx.ID_SAVEAS, "saveas", _(u'Save As...'), None),
   141                                (wx.ID_SAVEAS, "saveas", _(u'Save As...'), None),
   142                                (wx.ID_PRINT, "print", _(u'Print'), None)])
   142                                (wx.ID_PRINT, "print", _(u'Print'), None)])
   143             
   143 
   144     def _init_coll_HelpMenu_Items(self, parent):
   144     def _init_coll_HelpMenu_Items(self, parent):
   145         AppendMenu(parent, help='', id=wx.ID_HELP, 
   145         AppendMenu(parent, help='', id=wx.ID_HELP,
   146             kind=wx.ITEM_NORMAL, text=_(u'PLCOpenEditor') + '\tF1')
   146             kind=wx.ITEM_NORMAL, text=_(u'PLCOpenEditor') + '\tF1')
   147         #AppendMenu(parent, help='', id=wx.ID_HELP_CONTENTS,
   147         #AppendMenu(parent, help='', id=wx.ID_HELP_CONTENTS,
   148         #      kind=wx.ITEM_NORMAL, text=u'PLCOpen\tF2')
   148         #      kind=wx.ITEM_NORMAL, text=u'PLCOpen\tF2')
   149         #AppendMenu(parent, help='', id=wx.ID_HELP_CONTEXT,
   149         #AppendMenu(parent, help='', id=wx.ID_HELP_CONTEXT,
   150         #      kind=wx.ITEM_NORMAL, text=u'IEC 61131-3\tF3')
   150         #      kind=wx.ITEM_NORMAL, text=u'IEC 61131-3\tF3')
   159     #  @param controler The controler been used by PLCOpenEditor (default: None).
   159     #  @param controler The controler been used by PLCOpenEditor (default: None).
   160     #  @param fileOpen The filepath to open if no controler defined (default: None).
   160     #  @param fileOpen The filepath to open if no controler defined (default: None).
   161     #  @param debug The filepath to open if no controler defined (default: False).
   161     #  @param debug The filepath to open if no controler defined (default: False).
   162     def __init__(self, parent, fileOpen = None):
   162     def __init__(self, parent, fileOpen = None):
   163         IDEFrame.__init__(self, parent)
   163         IDEFrame.__init__(self, parent)
   164         
   164 
   165         result = None
   165         result = None
   166         
   166 
   167         # Open the filepath if defined
   167         # Open the filepath if defined
   168         if fileOpen is not None:
   168         if fileOpen is not None:
   169             fileOpen = DecodeFileSystemPath(fileOpen, False)
   169             fileOpen = DecodeFileSystemPath(fileOpen, False)
   170             if os.path.isfile(fileOpen):
   170             if os.path.isfile(fileOpen):
   171                 # Create a new controller
   171                 # Create a new controller
   174                 self.Controler = controler
   174                 self.Controler = controler
   175                 self.LibraryPanel.SetController(controler)
   175                 self.LibraryPanel.SetController(controler)
   176                 self.ProjectTree.Enable(True)
   176                 self.ProjectTree.Enable(True)
   177                 self.PouInstanceVariablesPanel.SetController(controler)
   177                 self.PouInstanceVariablesPanel.SetController(controler)
   178                 self._Refresh(PROJECTTREE, POUINSTANCEVARIABLESPANEL, LIBRARYTREE)
   178                 self._Refresh(PROJECTTREE, POUINSTANCEVARIABLESPANEL, LIBRARYTREE)
   179         
   179 
   180         # Define PLCOpenEditor icon
   180         # Define PLCOpenEditor icon
   181         self.SetIcon(wx.Icon(os.path.join(CWD, "images", "poe.ico"),wx.BITMAP_TYPE_ICO))
   181         self.SetIcon(wx.Icon(os.path.join(beremiz_dir, "images", "poe.ico"),wx.BITMAP_TYPE_ICO))
   182 
   182 
   183         self.Bind(wx.EVT_CLOSE, self.OnCloseFrame)
   183         self.Bind(wx.EVT_CLOSE, self.OnCloseFrame)
   184         
   184 
   185         self._Refresh(TITLE, EDITORTOOLBAR, FILEMENU, EDITMENU, DISPLAYMENU)
   185         self._Refresh(TITLE, EDITORTOOLBAR, FILEMENU, EDITMENU, DISPLAYMENU)
   186         
   186 
   187         if result is not None:
   187         if result is not None:
   188             self.ShowErrorMessage(
   188             self.ShowErrorMessage(
   189                 _("PLC syntax error at line %d:\n%s") % result)
   189                 _("PLC syntax error at line %d:\n%s") % result)
   190 
   190 
   191     def OnCloseFrame(self, event):
   191     def OnCloseFrame(self, event):
   192         if self.Controler is None or self.CheckSaveBeforeClosing(_("Close Application")):
   192         if self.Controler is None or self.CheckSaveBeforeClosing(_("Close Application")):
   193             self.AUIManager.UnInit()
   193             self.AUIManager.UnInit()
   194             
   194 
   195             self.SaveLastState()
   195             self.SaveLastState()
   196             
   196 
   197             event.Skip()
   197             event.Skip()
   198         else:
   198         else:
   199             event.Veto()
   199             event.Veto()
   200 
   200 
   201     def RefreshTitle(self):
   201     def RefreshTitle(self):
   264             self.ResetView()
   264             self.ResetView()
   265             self.Controler = PLCControler()
   265             self.Controler = PLCControler()
   266             self.Controler.CreateNewProject(properties)
   266             self.Controler.CreateNewProject(properties)
   267             self.LibraryPanel.SetController(self.Controler)
   267             self.LibraryPanel.SetController(self.Controler)
   268             self.ProjectTree.Enable(True)
   268             self.ProjectTree.Enable(True)
   269             self._Refresh(TITLE, FILEMENU, EDITMENU, PROJECTTREE, POUINSTANCEVARIABLESPANEL, 
   269             self._Refresh(TITLE, FILEMENU, EDITMENU, PROJECTTREE, POUINSTANCEVARIABLESPANEL,
   270                           LIBRARYTREE)
   270                           LIBRARYTREE)
   271 
   271 
   272     def OnOpenProjectMenu(self, event):
   272     def OnOpenProjectMenu(self, event):
   273         if self.Controler is not None and not self.CheckSaveBeforeClosing():
   273         if self.Controler is not None and not self.CheckSaveBeforeClosing():
   274             return
   274             return
   277             filepath = self.Controler.GetFilePath()
   277             filepath = self.Controler.GetFilePath()
   278         if filepath != "":
   278         if filepath != "":
   279             directory = os.path.dirname(filepath)
   279             directory = os.path.dirname(filepath)
   280         else:
   280         else:
   281             directory = os.getcwd()
   281             directory = os.getcwd()
   282         
   282 
   283         result = None
   283         result = None
   284         
   284 
   285         dialog = wx.FileDialog(self, _("Choose a file"), directory, "",  _("PLCOpen files (*.xml)|*.xml|All files|*.*"), wx.OPEN)
   285         dialog = wx.FileDialog(self, _("Choose a file"), directory, "",  _("PLCOpen files (*.xml)|*.xml|All files|*.*"), wx.OPEN)
   286         if dialog.ShowModal() == wx.ID_OK:
   286         if dialog.ShowModal() == wx.ID_OK:
   287             filepath = dialog.GetPath()
   287             filepath = dialog.GetPath()
   288             if os.path.isfile(filepath):
   288             if os.path.isfile(filepath):
   289                 self.ResetView()
   289                 self.ResetView()
   294                 self.ProjectTree.Enable(True)
   294                 self.ProjectTree.Enable(True)
   295                 self.PouInstanceVariablesPanel.SetController(controler)
   295                 self.PouInstanceVariablesPanel.SetController(controler)
   296                 self._Refresh(PROJECTTREE, LIBRARYTREE)
   296                 self._Refresh(PROJECTTREE, LIBRARYTREE)
   297             self._Refresh(TITLE, EDITORTOOLBAR, FILEMENU, EDITMENU)
   297             self._Refresh(TITLE, EDITORTOOLBAR, FILEMENU, EDITMENU)
   298         dialog.Destroy()
   298         dialog.Destroy()
   299         
   299 
   300         if result is not None:
   300         if result is not None:
   301             self.ShowErrorMessage(
   301             self.ShowErrorMessage(
   302                 _("PLC syntax error at line %d:\n%s") % result)
   302                 _("PLC syntax error at line %d:\n%s") % result)
   303     
   303 
   304     def OnCloseProjectMenu(self, event):
   304     def OnCloseProjectMenu(self, event):
   305         if not self.CheckSaveBeforeClosing():
   305         if not self.CheckSaveBeforeClosing():
   306             return
   306             return
   307         self.ResetView()
   307         self.ResetView()
   308         self._Refresh(TITLE, EDITORTOOLBAR, FILEMENU, EDITMENU)
   308         self._Refresh(TITLE, EDITORTOOLBAR, FILEMENU, EDITMENU)
   336             message.Destroy()
   336             message.Destroy()
   337         dialog.Destroy()
   337         dialog.Destroy()
   338 
   338 
   339     def OnPLCOpenEditorMenu(self, event):
   339     def OnPLCOpenEditorMenu(self, event):
   340         wx.MessageBox(_("No documentation available.\nComing soon."))
   340         wx.MessageBox(_("No documentation available.\nComing soon."))
   341         
   341 
   342     def OnPLCOpenMenu(self, event):
   342     def OnPLCOpenMenu(self, event):
   343         open_pdf(os.path.join(CWD, "plcopen", "TC6_XML_V101.pdf"))
   343         open_pdf(os.path.join(beremiz_dir, "plcopen", "TC6_XML_V101.pdf"))
   344     
   344 
   345     def OnAboutMenu(self, event):
   345     def OnAboutMenu(self, event):
   346         OpenHtmlFrame(self,_("About PLCOpenEditor"), os.path.join(CWD, "doc", "plcopen_about.html"), wx.Size(350, 350))
   346         OpenHtmlFrame(self,_("About PLCOpenEditor"), os.path.join(beremiz_dir, "doc", "plcopen_about.html"), wx.Size(350, 350))
   347 
   347 
   348     def SaveProject(self):
   348     def SaveProject(self):
   349         result = self.Controler.SaveXMLFile()
   349         result = self.Controler.SaveXMLFile()
   350         if not result:
   350         if not result:
   351             self.SaveProjectAs()
   351             self.SaveProjectAs()
   352         else:
   352         else:
   353             self._Refresh(TITLE, FILEMENU, PAGETITLES)
   353             self._Refresh(TITLE, FILEMENU, PAGETITLES)
   354         
   354 
   355     def SaveProjectAs(self):
   355     def SaveProjectAs(self):
   356         filepath = self.Controler.GetFilePath()
   356         filepath = self.Controler.GetFilePath()
   357         if filepath != "":
   357         if filepath != "":
   358             directory, filename = os.path.split(filepath)
   358             directory, filename = os.path.split(filepath)
   359         else:
   359         else:
   384             trcbck += _("file : ") + str(line[0]) + _(",   ")
   384             trcbck += _("file : ") + str(line[0]) + _(",   ")
   385         else:
   385         else:
   386             trcbck += _("file : ") + str(line[0][len(os.getcwd()):]) + _(",   ")
   386             trcbck += _("file : ") + str(line[0][len(os.getcwd()):]) + _(",   ")
   387         trcbck += _("line : ") + str(line[1]) + _(",   ") + _("function : ") + str(line[2])
   387         trcbck += _("line : ") + str(line[1]) + _(",   ") + _("function : ") + str(line[2])
   388         trcbck_lst.append(trcbck)
   388         trcbck_lst.append(trcbck)
   389         
   389 
   390     # Allow clicking....
   390     # Allow clicking....
   391     cap = wx.Window_GetCapture()
   391     cap = wx.Window_GetCapture()
   392     if cap:
   392     if cap:
   393         cap.ReleaseMouse()
   393         cap.ReleaseMouse()
   394 
   394 
   395     dlg = wx.SingleChoiceDialog(None, 
   395     dlg = wx.SingleChoiceDialog(None,
   396         _("""
   396         _("""
   397 An error has occurred.
   397 An error has occurred.
   398 
   398 
   399 Click OK to save an error report.
   399 Click OK to save an error report.
   400 
   400 
   401 Please be kind enough to send this file to:
   401 Please be kind enough to send this file to:
   402 edouard.tisserant@gmail.com
   402 edouard.tisserant@gmail.com
   403 
   403 
   404 Error:
   404 Error:
   405 """) +
   405 """) +
   406         str(e_type) + _(" : ") + str(e_value), 
   406         str(e_type) + _(" : ") + str(e_value),
   407         _("Error"),
   407         _("Error"),
   408         trcbck_lst)
   408         trcbck_lst)
   409     try:
   409     try:
   410         res = (dlg.ShowModal() == wx.ID_OK)
   410         res = (dlg.ShowModal() == wx.ID_OK)
   411     finally:
   411     finally:
   429 
   429 
   430 
   430 
   431 ignored_exceptions = [] # a problem with a line in a module is only reported once per session
   431 ignored_exceptions = [] # a problem with a line in a module is only reported once per session
   432 
   432 
   433 def AddExceptHook(path, app_version='[No version]'):#, ignored_exceptions=[]):
   433 def AddExceptHook(path, app_version='[No version]'):#, ignored_exceptions=[]):
   434     
   434 
   435     def handle_exception(e_type, e_value, e_traceback):
   435     def handle_exception(e_type, e_value, e_traceback):
   436         traceback.print_exception(e_type, e_value, e_traceback) # this is very helpful when there's an exception in the rest of this func
   436         traceback.print_exception(e_type, e_value, e_traceback) # this is very helpful when there's an exception in the rest of this func
   437         last_tb = get_last_traceback(e_traceback)
   437         last_tb = get_last_traceback(e_traceback)
   438         ex = (last_tb.tb_frame.f_code.co_filename, last_tb.tb_frame.f_lineno)
   438         ex = (last_tb.tb_frame.f_code.co_filename, last_tb.tb_frame.f_lineno)
   439         if str(e_value).startswith("!!!"):
   439         if str(e_value).startswith("!!!"):
   459                     last_tb = get_last_traceback(e_traceback)
   459                     last_tb = get_last_traceback(e_traceback)
   460                     exception_locals = last_tb.tb_frame.f_locals # the locals at the level of the stack trace where the exception actually occurred
   460                     exception_locals = last_tb.tb_frame.f_locals # the locals at the level of the stack trace where the exception actually occurred
   461                     info['locals'] = format_namespace(exception_locals)
   461                     info['locals'] = format_namespace(exception_locals)
   462                     if 'self' in exception_locals:
   462                     if 'self' in exception_locals:
   463                         info['self'] = format_namespace(exception_locals['self'].__dict__)
   463                         info['self'] = format_namespace(exception_locals['self'].__dict__)
   464                 
   464 
   465                 output = open(path+os.sep+"bug_report_"+info['date'].replace(':','-').replace(' ','_')+".txt",'w')
   465                 output = open(path+os.sep+"bug_report_"+info['date'].replace(':','-').replace(' ','_')+".txt",'w')
   466                 lst = info.keys()
   466                 lst = info.keys()
   467                 lst.sort()
   467                 lst.sort()
   468                 for a in lst:
   468                 for a in lst:
   469                     output.write(a+":\n"+str(info[a])+"\n\n")
   469                     output.write(a+":\n"+str(info[a])+"\n\n")
   471     #sys.excepthook = lambda *args: wx.CallAfter(handle_exception, *args)
   471     #sys.excepthook = lambda *args: wx.CallAfter(handle_exception, *args)
   472     sys.excepthook = handle_exception
   472     sys.excepthook = handle_exception
   473 
   473 
   474 if __name__ == '__main__':
   474 if __name__ == '__main__':
   475     wx.InitAllImageHandlers()
   475     wx.InitAllImageHandlers()
   476     
   476 
   477     # Install a exception handle for bug reports
   477     # Install a exception handle for bug reports
   478     AddExceptHook(os.getcwd(),__version__)
   478     AddExceptHook(os.getcwd(),__version__)
   479     
   479 
   480     frame = PLCOpenEditor(None, fileOpen=fileOpen)
   480     frame = PLCOpenEditor(None, fileOpen=fileOpen)
   481 
   481 
   482     frame.Show()
   482     frame.Show()
   483     app.MainLoop()
   483     app.MainLoop()
   484     
   484