PLCOpenEditor.py
changeset 0 b622defdfd98
child 1 e9d01d824086
equal deleted inserted replaced
-1:000000000000 0:b622defdfd98
       
     1 #Boa:Frame:PLCOpenEditor
       
     2 #!/usr/bin/env python
       
     3 # -*- coding: utf-8 -*-
       
     4 
       
     5 #This file is part of PLCOpenEditor, a library implementing an IEC 61131-3 editor
       
     6 #based on the plcopen standard. 
       
     7 #
       
     8 #Copyright (C): Edouard TISSERANT and Laurent BESSARD
       
     9 #
       
    10 #See COPYING file for copyrights details.
       
    11 #
       
    12 #This library is free software; you can redistribute it and/or
       
    13 #modify it under the terms of the GNU Lesser General Public
       
    14 #License as published by the Free Software Foundation; either
       
    15 #version 2.1 of the License, or (at your option) any later version.
       
    16 #
       
    17 #This library is distributed in the hope that it will be useful,
       
    18 #but WITHOUT ANY WARRANTY; without even the implied warranty of
       
    19 #MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
       
    20 #Lesser General Public License for more details.
       
    21 #
       
    22 #You should have received a copy of the GNU Lesser General Public
       
    23 #License along with this library; if not, write to the Free Software
       
    24 #Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
       
    25 
       
    26 from wxPython.wx import *
       
    27 from wxPython.grid import *
       
    28 from time import localtime
       
    29 from datetime import datetime
       
    30 import wx
       
    31 
       
    32 from SFCViewer import *
       
    33 from FBDViewer import *
       
    34 from LDViewer import *
       
    35 from Viewer import *
       
    36 from PLCControler import *
       
    37 from plcopen import OpenPDFDoc
       
    38 from plcopen.structures import *
       
    39 
       
    40 import os, re, platform, sys, time, traceback, getopt
       
    41 
       
    42 __version__ = "$Revision$"
       
    43 
       
    44 def create(parent):
       
    45     return PLCOpenEditor(parent)
       
    46 
       
    47 def usage():
       
    48     print "\nUsage of PLCOpenEditor.py :"
       
    49     print "\n   %s [Filepath]\n"%sys.argv[0]
       
    50 
       
    51 try:
       
    52     opts, args = getopt.getopt(sys.argv[1:], "h", ["help"])
       
    53 except getopt.GetoptError:
       
    54     # print help information and exit:
       
    55     usage()
       
    56     sys.exit(2)
       
    57 
       
    58 for o, a in opts:
       
    59     if o in ("-h", "--help"):
       
    60         usage()
       
    61         sys.exit()
       
    62 
       
    63 fileOpen = None
       
    64 if len(args) > 1:
       
    65     usage()
       
    66     sys.exit()
       
    67 elif len(args) == 1:
       
    68     fileOpen = args[0]
       
    69 
       
    70 
       
    71 # Test if identifier is valid
       
    72 def TestIdentifier(identifier):
       
    73      if identifier[0].isdigit():
       
    74         return False
       
    75      words = identifier.split('_')
       
    76      for i, word in enumerate(words):
       
    77          if len(word) == 0 and i != 0:
       
    78              return False
       
    79          if len(word) != 0 and not word.isalnum():
       
    80              return False
       
    81      return True
       
    82 
       
    83 [wxID_PLCOPENEDITOR, wxID_PLCOPENEDITORPROJECTTREE, 
       
    84  wxID_PLCOPENEDITORSPLITTERWINDOW1, wxID_PLCOPENEDITORTABSOPENED,
       
    85  wxID_PLCOPENEDITORDEFAULTTOOLBAR, wxID_PLCOPENEDITORSFCTOOLBAR,
       
    86  wxID_PLCOPENEDITORFBDTOOLBAR, wxID_PLCOPENEDITORLDTOOLBAR,
       
    87 ] = [wx.NewId() for _init_ctrls in range(8)]
       
    88 
       
    89 [wxID_PLCOPENEDITORDEFAULTTOOLBARITEMS0, 
       
    90 ] = [wx.NewId() for _init_coll_DefaultToolBar_Items in range(1)]
       
    91 
       
    92 [wxID_PLCOPENEDITORSFCTOOLBARITEMS0, wxID_PLCOPENEDITORSFCTOOLBARITEMS1, 
       
    93  wxID_PLCOPENEDITORSFCTOOLBARITEMS2, wxID_PLCOPENEDITORSFCTOOLBARITEMS3, 
       
    94  wxID_PLCOPENEDITORSFCTOOLBARITEMS4, wxID_PLCOPENEDITORSFCTOOLBARITEMS5,
       
    95  wxID_PLCOPENEDITORSFCTOOLBARITEMS6,
       
    96 ] = [wx.NewId() for _init_coll_SFCToolBar_Items in range(7)]
       
    97 
       
    98 [wxID_PLCOPENEDITORFBDTOOLBARITEMS0, wxID_PLCOPENEDITORFBDTOOLBARITEMS1, 
       
    99  wxID_PLCOPENEDITORFBDTOOLBARITEMS2, wxID_PLCOPENEDITORFBDTOOLBARITEMS3, 
       
   100  wxID_PLCOPENEDITORFBDTOOLBARITEMS4, wxID_PLCOPENEDITORFBDTOOLBARITEMS5,
       
   101 ] = [wx.NewId() for _init_coll_FBDToolBar_Items in range(6)]
       
   102 
       
   103 [wxID_PLCOPENEDITORLDTOOLBARITEMS0, wxID_PLCOPENEDITORLDTOOLBARITEMS1, 
       
   104  wxID_PLCOPENEDITORLDTOOLBARITEMS2, wxID_PLCOPENEDITORLDTOOLBARITEMS3, 
       
   105  wxID_PLCOPENEDITORLDTOOLBARITEMS4,
       
   106 ] = [wx.NewId() for _init_coll_LDToolBar_Items in range(5)]
       
   107 
       
   108 [wxID_PLCOPENEDITORFILEMENUITEMS0, wxID_PLCOPENEDITORFILEMENUITEMS1, 
       
   109  wxID_PLCOPENEDITORFILEMENUITEMS2, wxID_PLCOPENEDITORFILEMENUITEMS3, 
       
   110  wxID_PLCOPENEDITORFILEMENUITEMS5, wxID_PLCOPENEDITORFILEMENUITEMS6, 
       
   111  wxID_PLCOPENEDITORFILEMENUITEMS7, wxID_PLCOPENEDITORFILEMENUITEMS9, 
       
   112  wxID_PLCOPENEDITORFILEMENUITEMS11,
       
   113 ] = [wx.NewId() for _init_coll_FileMenu_Items in range(9)]
       
   114 
       
   115 [wxID_PLCOPENEDITORHELPMENUITEMS0, wxID_PLCOPENEDITORHELPMENUITEMS1, 
       
   116  wxID_PLCOPENEDITORHELPMENUITEMS2, wxID_PLCOPENEDITORHELPMENUITEMS3, 
       
   117 ] = [wx.NewId() for _init_coll_HelpMenu_Items in range(4)]
       
   118 
       
   119 [wxID_PLCOPENEDITORSFCMENUITEMS0, wxID_PLCOPENEDITORSFCMENUITEMS1, 
       
   120  wxID_PLCOPENEDITORSFCMENUITEMS2, wxID_PLCOPENEDITORSFCMENUITEMS3,
       
   121 ] = [wx.NewId() for _init_coll_HelpMenu_Items in range(4)]
       
   122 
       
   123 [wxID_PLCOPENEDITORCONFIGMENUITEMS0, wxID_PLCOPENEDITORCONFIGMENUITEMS1, 
       
   124 ] = [wx.NewId() for _init_coll_HelpMenu_Items in range(2)]
       
   125 
       
   126 [wxID_PLCOPENEDITOREDITMENUITEMS0, wxID_PLCOPENEDITOREDITMENUITEMS1, 
       
   127  wxID_PLCOPENEDITOREDITMENUITEMS11, wxID_PLCOPENEDITOREDITMENUITEMS12, 
       
   128  wxID_PLCOPENEDITOREDITMENUITEMS2, wxID_PLCOPENEDITOREDITMENUITEMS4, 
       
   129  wxID_PLCOPENEDITOREDITMENUITEMS5, wxID_PLCOPENEDITOREDITMENUITEMS6, 
       
   130  wxID_PLCOPENEDITOREDITMENUITEMS8, wxID_PLCOPENEDITOREDITMENUITEMS9, 
       
   131 ] = [wx.NewId() for _init_coll_EditMenu_Items in range(10)]
       
   132 
       
   133 [wxID_PLCOPENEDITORSFCMENUITEMS0, wxID_PLCOPENEDITORSFCMENUITEMS1, 
       
   134  wxID_PLCOPENEDITORSFCMENUITEMS2, wxID_PLCOPENEDITORSFCMENUITEMS3, 
       
   135 ] = [wx.NewId() for _init_coll_SFCMenu_Items in range(4)]
       
   136 
       
   137 [wxID_PLCOPENEDITORCONFIGMENUITEMS0, wxID_PLCOPENEDITORCONFIGMENUITEMS1, 
       
   138 ] = [wx.NewId() for _init_coll_ConfigMenu_Items in range(2)]
       
   139 
       
   140 class PLCOpenEditor(wx.Frame):
       
   141     _custom_classes = {'wx.SashWindow' : ['Viewer']}
       
   142     
       
   143     def _init_coll_EditMenu_Items(self, parent):
       
   144         # generated method, don't edit
       
   145 
       
   146         parent.Append(help='', id=wxID_PLCOPENEDITOREDITMENUITEMS0,
       
   147               kind=wx.ITEM_NORMAL, text=u'Refresh\tCTRL+R')
       
   148         parent.Append(help='', id=wxID_PLCOPENEDITOREDITMENUITEMS1,
       
   149               kind=wx.ITEM_NORMAL, text=u'Undo\tCTRL+Z')
       
   150         parent.Append(help='', id=wxID_PLCOPENEDITOREDITMENUITEMS2,
       
   151               kind=wx.ITEM_NORMAL, text=u'Redo\tCTRL+Y')
       
   152         parent.AppendSeparator()
       
   153         parent.Append(help='', id=wxID_PLCOPENEDITOREDITMENUITEMS4,
       
   154               kind=wx.ITEM_NORMAL, text=u'Cut\tCTRL+X')
       
   155         parent.Append(help='', id=wxID_PLCOPENEDITOREDITMENUITEMS5,
       
   156               kind=wx.ITEM_NORMAL, text=u'Copy\tCTRL+C')
       
   157         parent.Append(help='', id=wxID_PLCOPENEDITOREDITMENUITEMS6,
       
   158               kind=wx.ITEM_NORMAL, text=u'Paste\tCTRL+V')
       
   159         parent.AppendSeparator()
       
   160         parent.Append(help='', id=wxID_PLCOPENEDITOREDITMENUITEMS8,
       
   161               kind=wx.ITEM_NORMAL, text=u'Add POU')
       
   162         parent.Append(help='', id=wxID_PLCOPENEDITOREDITMENUITEMS9,
       
   163               kind=wx.ITEM_NORMAL, text=u'Remove POU')
       
   164         parent.AppendSeparator()
       
   165         parent.Append(help='', id=wxID_PLCOPENEDITOREDITMENUITEMS11,
       
   166               kind=wx.ITEM_NORMAL, text=u'Add Configuration')
       
   167         parent.Append(help='', id=wxID_PLCOPENEDITOREDITMENUITEMS12,
       
   168               kind=wx.ITEM_NORMAL, text=u'Remove Configuration')
       
   169         self.Bind(wx.EVT_MENU, self.OnRefreshMenu,
       
   170               id=wxID_PLCOPENEDITOREDITMENUITEMS0)
       
   171         self.Bind(wx.EVT_MENU, self.OnCutMenu,
       
   172               id=wxID_PLCOPENEDITOREDITMENUITEMS4)
       
   173         self.Bind(wx.EVT_MENU, self.OnCopyMenu,
       
   174               id=wxID_PLCOPENEDITOREDITMENUITEMS5)
       
   175         self.Bind(wx.EVT_MENU, self.OnPasteMenu,
       
   176               id=wxID_PLCOPENEDITOREDITMENUITEMS6)
       
   177         self.Bind(wx.EVT_MENU, self.OnAddPouMenu,
       
   178               id=wxID_PLCOPENEDITOREDITMENUITEMS8)
       
   179         self.Bind(wx.EVT_MENU, self.OnRemovePouMenu,
       
   180               id=wxID_PLCOPENEDITOREDITMENUITEMS9)
       
   181         self.Bind(wx.EVT_MENU, self.OnAddConfigurationMenu,
       
   182               id=wxID_PLCOPENEDITOREDITMENUITEMS11)
       
   183         self.Bind(wx.EVT_MENU, self.OnRemoveConfigurationMenu,
       
   184               id=wxID_PLCOPENEDITOREDITMENUITEMS12)
       
   185 
       
   186     def _init_coll_menuBar1_Menus(self, parent):
       
   187         # generated method, don't edit
       
   188 
       
   189         parent.Append(menu=self.FileMenu, title=u'File')
       
   190         parent.Append(menu=self.EditMenu, title=u'Edit')
       
   191         parent.Append(menu=self.HelpMenu, title=u'Help')
       
   192 
       
   193     def _init_coll_ConfigMenu_Items(self, parent):
       
   194         # generated method, don't edit
       
   195 
       
   196         parent.Append(help='', id=wxID_PLCOPENEDITORCONFIGMENUITEMS0,
       
   197               kind=wx.ITEM_NORMAL, text=u'Add Resource')
       
   198         parent.Append(help='', id=wxID_PLCOPENEDITORCONFIGMENUITEMS1,
       
   199               kind=wx.ITEM_NORMAL, text=u'Remove Resource')
       
   200         self.Bind(wx.EVT_MENU, self.OnAddResourceMenu,
       
   201               id=wxID_PLCOPENEDITORCONFIGMENUITEMS0)
       
   202         self.Bind(wx.EVT_MENU, self.OnRemoveResourceMenu,
       
   203               id=wxID_PLCOPENEDITORCONFIGMENUITEMS1)
       
   204 
       
   205     def _init_coll_HelpMenu_Items(self, parent):
       
   206         # generated method, don't edit
       
   207 
       
   208         parent.Append(help='', id=wxID_PLCOPENEDITORHELPMENUITEMS0,
       
   209               kind=wx.ITEM_NORMAL, text=u'PLCOpenEditor\tF1')
       
   210         parent.Append(help='', id=wxID_PLCOPENEDITORHELPMENUITEMS1,
       
   211               kind=wx.ITEM_NORMAL, text=u'PLCOpen\tF2')
       
   212         parent.Append(help='', id=wxID_PLCOPENEDITORHELPMENUITEMS2,
       
   213               kind=wx.ITEM_NORMAL, text=u'IEC 61131-3\tF3')
       
   214         parent.Append(help='', id=wxID_PLCOPENEDITORHELPMENUITEMS3,
       
   215               kind=wx.ITEM_NORMAL, text=u'About')
       
   216         self.Bind(wx.EVT_MENU, self.OnPLCOpenMenu,
       
   217               id=wxID_PLCOPENEDITORHELPMENUITEMS1)
       
   218 
       
   219     def _init_coll_FileMenu_Items(self, parent):
       
   220         # generated method, don't edit
       
   221 
       
   222         parent.Append(help='', id=wxID_PLCOPENEDITORFILEMENUITEMS0,
       
   223               kind=wx.ITEM_NORMAL, text=u'New\tCTRL+N')
       
   224         parent.Append(help='', id=wxID_PLCOPENEDITORFILEMENUITEMS1,
       
   225               kind=wx.ITEM_NORMAL, text=u'Open\tCTRL+O')
       
   226         parent.Append(help='', id=wxID_PLCOPENEDITORFILEMENUITEMS2,
       
   227               kind=wx.ITEM_NORMAL, text=u'Close Tab\tCTRL+W')
       
   228         parent.Append(help='', id=wxID_PLCOPENEDITORFILEMENUITEMS3,
       
   229               kind=wx.ITEM_NORMAL, text=u'Close Project')
       
   230         parent.AppendSeparator()
       
   231         parent.Append(help='', id=wxID_PLCOPENEDITORFILEMENUITEMS5,
       
   232               kind=wx.ITEM_NORMAL, text=u'Save\tCTRL+S')
       
   233         parent.Append(help='', id=wxID_PLCOPENEDITORFILEMENUITEMS6,
       
   234               kind=wx.ITEM_NORMAL, text=u'Save As...\tCTRL+SHIFT+S')
       
   235         parent.Append(help='', id=wxID_PLCOPENEDITORFILEMENUITEMS7,
       
   236               kind=wx.ITEM_NORMAL, text=u'Generate Program\tCTRL+G')
       
   237         parent.AppendSeparator()
       
   238         parent.Append(help='', id=wxID_PLCOPENEDITORFILEMENUITEMS9,
       
   239               kind=wx.ITEM_NORMAL, text=u'Properties')
       
   240         parent.AppendSeparator()
       
   241         parent.Append(help='', id=wxID_PLCOPENEDITORFILEMENUITEMS11,
       
   242               kind=wx.ITEM_NORMAL, text=u'Quit\tCTRL+Q')
       
   243         self.Bind(wx.EVT_MENU, self.OnNewProjectMenu,
       
   244               id=wxID_PLCOPENEDITORFILEMENUITEMS0)
       
   245         self.Bind(wx.EVT_MENU, self.OnOpenProjectMenu,
       
   246               id=wxID_PLCOPENEDITORFILEMENUITEMS1)
       
   247         self.Bind(wx.EVT_MENU, self.OnCloseTabMenu,
       
   248               id=wxID_PLCOPENEDITORFILEMENUITEMS2)
       
   249         self.Bind(wx.EVT_MENU, self.OnCloseProjectMenu,
       
   250               id=wxID_PLCOPENEDITORFILEMENUITEMS3)
       
   251         self.Bind(wx.EVT_MENU, self.OnSaveProjectMenu,
       
   252               id=wxID_PLCOPENEDITORFILEMENUITEMS5)
       
   253         self.Bind(wx.EVT_MENU, self.OnSaveProjectAsMenu,
       
   254               id=wxID_PLCOPENEDITORFILEMENUITEMS6)
       
   255         self.Bind(wx.EVT_MENU, self.OnGenerateProgramMenu,
       
   256               id=wxID_PLCOPENEDITORFILEMENUITEMS7)
       
   257         self.Bind(wx.EVT_MENU, self.OnQuitMenu,
       
   258               id=wxID_PLCOPENEDITORFILEMENUITEMS11)
       
   259 
       
   260     def _init_coll_SFCMenu_Items(self, parent):
       
   261         # generated method, don't edit
       
   262 
       
   263         parent.Append(help='', id=wxID_PLCOPENEDITORSFCMENUITEMS0,
       
   264               kind=wx.ITEM_NORMAL, text=u'Add Transition')
       
   265         parent.Append(help='', id=wxID_PLCOPENEDITORSFCMENUITEMS1,
       
   266               kind=wx.ITEM_NORMAL, text=u'Add Action')
       
   267         parent.Append(help='', id=wxID_PLCOPENEDITORSFCMENUITEMS2,
       
   268               kind=wx.ITEM_NORMAL, text=u'Remove Transition')
       
   269         parent.Append(help='', id=wxID_PLCOPENEDITORSFCMENUITEMS3,
       
   270               kind=wx.ITEM_NORMAL, text=u'Remove Action')
       
   271         self.Bind(wx.EVT_MENU, self.OnAddPouTransitionMenu,
       
   272               id=wxID_PLCOPENEDITORSFCMENUITEMS0)
       
   273         self.Bind(wx.EVT_MENU, self.OnAddPouActionMenu,
       
   274               id=wxID_PLCOPENEDITORSFCMENUITEMS1)
       
   275         self.Bind(wx.EVT_MENU, self.OnRemovePouTransitionMenu,
       
   276               id=wxID_PLCOPENEDITORSFCMENUITEMS2)
       
   277         self.Bind(wx.EVT_MENU, self.OnRemovePouActionMenu,
       
   278               id=wxID_PLCOPENEDITORSFCMENUITEMS3)
       
   279 
       
   280     def _init_utils(self):
       
   281         # generated method, don't edit
       
   282         self.menuBar1 = wx.MenuBar()
       
   283 
       
   284         self.FileMenu = wx.Menu(title=u'')
       
   285 
       
   286         self.EditMenu = wx.Menu(title=u'')
       
   287 
       
   288         self.HelpMenu = wx.Menu(title='')
       
   289 
       
   290         self.SFCMenu = wx.Menu(title='')
       
   291 
       
   292         self.ConfigMenu = wx.Menu(title='')
       
   293 
       
   294         self._init_coll_menuBar1_Menus(self.menuBar1)
       
   295         self._init_coll_FileMenu_Items(self.FileMenu)
       
   296         self._init_coll_EditMenu_Items(self.EditMenu)
       
   297         self._init_coll_HelpMenu_Items(self.HelpMenu)
       
   298         self._init_coll_SFCMenu_Items(self.SFCMenu)
       
   299         self._init_coll_ConfigMenu_Items(self.ConfigMenu)
       
   300 
       
   301     def _init_coll_MainGridSizer_Items(self, parent):
       
   302         # generated method, don't edit
       
   303 
       
   304         parent.AddWindow(self.splitterWindow1, 0, border=0, flag=wxGROW)
       
   305 
       
   306     def _init_coll_MainGridSizer_Growables(self, parent):
       
   307         # generated method, don't edit
       
   308 
       
   309         parent.AddGrowableCol(0)
       
   310         parent.AddGrowableRow(0)
       
   311 
       
   312     def _init_sizers(self):
       
   313         # generated method, don't edit
       
   314         self.MainGridSizer = wx.FlexGridSizer(cols=1, hgap=0, rows=1, vgap=0)
       
   315 
       
   316         self._init_coll_MainGridSizer_Growables(self.MainGridSizer)
       
   317         self._init_coll_MainGridSizer_Items(self.MainGridSizer)
       
   318 
       
   319         self.SetSizer(self.MainGridSizer)
       
   320 
       
   321     def _init_ctrls(self, prnt):
       
   322         # generated method, don't edit
       
   323         wx.Frame.__init__(self, id=wxID_PLCOPENEDITOR, name=u'PLCOpenEditor',
       
   324               parent=prnt, pos=wx.Point(235, 287), size=wx.Size(1000, 600),
       
   325               style=wx.DEFAULT_FRAME_STYLE, title=u'PLCOpenEditor')
       
   326         self._init_utils()
       
   327         self.SetClientSize(wx.Size(1000, 600))
       
   328         self.SetMenuBar(self.menuBar1)
       
   329         self.Bind(wx.EVT_TREE_BEGIN_LABEL_EDIT, self.OnProjectTreeItemBeginEdit,
       
   330               id=wxID_PLCOPENEDITORPROJECTTREE)
       
   331         self.Bind(wx.EVT_TREE_END_LABEL_EDIT, self.OnProjectTreeItemEndEdit,
       
   332               id=wxID_PLCOPENEDITORPROJECTTREE)
       
   333         self.Bind(wx.EVT_TREE_ITEM_ACTIVATED, self.OnProjectTreeItemActivated,
       
   334               id=wxID_PLCOPENEDITORPROJECTTREE)
       
   335         self.Bind(wx.EVT_TREE_SEL_CHANGED, self.OnProjectTreeItemSelected,
       
   336               id=wxID_PLCOPENEDITORPROJECTTREE)
       
   337         
       
   338         self.splitterWindow1 = wx.SplitterWindow(id=wxID_PLCOPENEDITORSPLITTERWINDOW1,
       
   339               name='splitterWindow1', parent=self, point=wx.Point(0, 0),
       
   340               size=wx.Size(-1, -1), style=wx.SP_3D)
       
   341         self.splitterWindow1.SetNeedUpdating(True)
       
   342         self.splitterWindow1.SetMinimumPaneSize(1)
       
   343 
       
   344         self.TabsOpened = wx.Notebook(id=wxID_PLCOPENEDITORTABSOPENED,
       
   345               name='TabsOpened', parent=self.splitterWindow1, pos=wx.Point(0,
       
   346               0), size=wx.Size(-1, -1), style=0)
       
   347         self.TabsOpened.Bind(wx.EVT_NOTEBOOK_PAGE_CHANGED,
       
   348               self.OnPouSelectedChanged, id=wxID_PLCOPENEDITORTABSOPENED)
       
   349 
       
   350         self.ProjectTree = wx.TreeCtrl(id=wxID_PLCOPENEDITORPROJECTTREE,
       
   351               name='treeCtrl1', parent=self.splitterWindow1, pos=wx.Point(0, 0),
       
   352               size=wx.Size(-1, -1),
       
   353               style=wx.TR_HAS_BUTTONS|wx.TR_EDIT_LABELS|wx.TR_SINGLE|wx.SUNKEN_BORDER)
       
   354         self.ProjectTree.Bind(wx.EVT_RIGHT_UP, self.OnProjectTreeRightUp)
       
   355         self.splitterWindow1.SplitVertically(self.ProjectTree, self.TabsOpened,
       
   356               200)
       
   357               
       
   358         self._init_sizers()
       
   359 
       
   360     def init_coll_DefaultToolBar_Items(self, parent):
       
   361         parent.AddRadioTool(wxID_PLCOPENEDITORDEFAULTTOOLBARITEMS0, 
       
   362               wxBitmap('Images/select.png'), wxNullBitmap, "Select an object")
       
   363         self.Bind(wx.EVT_TOOL, self.OnSelectionTool, 
       
   364               id=wxID_PLCOPENEDITORDEFAULTTOOLBARITEMS0)
       
   365 
       
   366     def init_coll_SFCToolBar_Items(self, parent):
       
   367         parent.AddRadioTool(wxID_PLCOPENEDITORSFCTOOLBARITEMS0, 
       
   368               wxBitmap('Images/select.png'), wxNullBitmap, "Select an object")
       
   369         parent.AddRadioTool(wxID_PLCOPENEDITORSFCTOOLBARITEMS1, 
       
   370               wxBitmap('Images/comment.png'), wxNullBitmap, "Create a new comment")
       
   371         parent.AddRadioTool(wxID_PLCOPENEDITORSFCTOOLBARITEMS2, 
       
   372               wxBitmap('Images/initial_step.png'), wxNullBitmap, "Create a new initial step")
       
   373         parent.AddSimpleTool(wxID_PLCOPENEDITORSFCTOOLBARITEMS3, 
       
   374               wxBitmap('Images/step.png'), "Create a new step")
       
   375         parent.AddSimpleTool(wxID_PLCOPENEDITORSFCTOOLBARITEMS4, 
       
   376               wxBitmap('Images/action.png'), "Add action block to step")
       
   377         parent.AddSimpleTool(wxID_PLCOPENEDITORSFCTOOLBARITEMS5, 
       
   378               wxBitmap('Images/divergence.png'), "Create a new divergence")
       
   379         parent.AddSimpleTool(wxID_PLCOPENEDITORSFCTOOLBARITEMS6, 
       
   380               wxBitmap('Images/jump.png'), "Create a new jump")
       
   381         self.Bind(wx.EVT_TOOL, self.OnSelectionTool, 
       
   382               id=wxID_PLCOPENEDITORSFCTOOLBARITEMS0)
       
   383         self.Bind(wx.EVT_TOOL, self.OnCommentTool, 
       
   384               id=wxID_PLCOPENEDITORSFCTOOLBARITEMS1)
       
   385         self.Bind(wx.EVT_TOOL, self.OnSFCInitialStepTool,
       
   386               id=wxID_PLCOPENEDITORSFCTOOLBARITEMS2)
       
   387         self.Bind(wx.EVT_TOOL, self.OnSFCStepTool,
       
   388               id=wxID_PLCOPENEDITORSFCTOOLBARITEMS3)
       
   389         self.Bind(wx.EVT_TOOL, self.OnSFCActionBlockTool,
       
   390               id=wxID_PLCOPENEDITORSFCTOOLBARITEMS4)
       
   391         self.Bind(wx.EVT_TOOL, self.OnSFCDivergenceTool,
       
   392               id=wxID_PLCOPENEDITORSFCTOOLBARITEMS5)
       
   393         self.Bind(wx.EVT_TOOL, self.OnSFCJumpTool,
       
   394               id=wxID_PLCOPENEDITORSFCTOOLBARITEMS6)
       
   395 
       
   396     def init_coll_FBDToolBar_Items(self, parent):
       
   397         parent.AddRadioTool(wxID_PLCOPENEDITORFBDTOOLBARITEMS0, 
       
   398               wxBitmap('Images/select.png'), wxNullBitmap, "Select an object")
       
   399         parent.AddRadioTool(wxID_PLCOPENEDITORFBDTOOLBARITEMS1, 
       
   400               wxBitmap('Images/comment.png'), wxNullBitmap, "Create a new comment")
       
   401         parent.AddRadioTool(wxID_PLCOPENEDITORFBDTOOLBARITEMS2, 
       
   402               wxBitmap('Images/variable.png'), wxNullBitmap, "Create a new variable")
       
   403         parent.AddRadioTool(wxID_PLCOPENEDITORFBDTOOLBARITEMS3, 
       
   404               wxBitmap('Images/block.png'), wxNullBitmap, "Create a new block")
       
   405         parent.AddRadioTool(wxID_PLCOPENEDITORFBDTOOLBARITEMS4, 
       
   406               wxBitmap('Images/connection.png'), wxNullBitmap, "Create a new connection")
       
   407         parent.AddRadioTool(wxID_PLCOPENEDITORFBDTOOLBARITEMS5, 
       
   408               wxBitmap('Images/wire.png'), wxNullBitmap, "Create a new wire")
       
   409         self.Bind(wx.EVT_TOOL, self.OnSelectionTool, 
       
   410               id=wxID_PLCOPENEDITORFBDTOOLBARITEMS0)
       
   411         self.Bind(wx.EVT_TOOL, self.OnCommentTool, 
       
   412               id=wxID_PLCOPENEDITORFBDTOOLBARITEMS1)
       
   413         self.Bind(wx.EVT_TOOL, self.OnFBDVariableTool,
       
   414               id=wxID_PLCOPENEDITORFBDTOOLBARITEMS2)
       
   415         self.Bind(wx.EVT_TOOL, self.OnFBDBlockTool,
       
   416               id=wxID_PLCOPENEDITORFBDTOOLBARITEMS3)
       
   417         self.Bind(wx.EVT_TOOL, self.OnFBDConnectionTool, 
       
   418               id=wxID_PLCOPENEDITORFBDTOOLBARITEMS4)
       
   419         self.Bind(wx.EVT_TOOL, self.OnWireTool, 
       
   420               id=wxID_PLCOPENEDITORFBDTOOLBARITEMS5)
       
   421     
       
   422     def init_coll_LDToolBar_Items(self, parent):
       
   423         parent.AddRadioTool(wxID_PLCOPENEDITORLDTOOLBARITEMS0, 
       
   424               wxBitmap('Images/select.png'), wxNullBitmap, "Select an object")
       
   425         parent.AddSimpleTool(wxID_PLCOPENEDITORLDTOOLBARITEMS1, 
       
   426               wxBitmap('Images/coil.png'), "Create a new rung")
       
   427         parent.AddSimpleTool(wxID_PLCOPENEDITORLDTOOLBARITEMS2, 
       
   428               wxBitmap('Images/contact.png'), "Create a new contact")
       
   429         parent.AddSimpleTool(wxID_PLCOPENEDITORLDTOOLBARITEMS3, 
       
   430               wxBitmap('Images/block.png'), "Create a new block")
       
   431         parent.AddSimpleTool(wxID_PLCOPENEDITORLDTOOLBARITEMS4, 
       
   432               wxBitmap('Images/branch.png'), "Create a new branch")
       
   433         self.Bind(wx.EVT_TOOL, self.OnSelectionTool, 
       
   434               id=wxID_PLCOPENEDITORLDTOOLBARITEMS0)
       
   435         self.Bind(wx.EVT_TOOL, self.OnLDCoilTool,
       
   436               id=wxID_PLCOPENEDITORLDTOOLBARITEMS1)
       
   437         self.Bind(wx.EVT_TOOL, self.OnLDContactTool,
       
   438               id=wxID_PLCOPENEDITORLDTOOLBARITEMS2)
       
   439         self.Bind(wx.EVT_TOOL, self.OnLDBlockTool, 
       
   440               id=wxID_PLCOPENEDITORLDTOOLBARITEMS3)
       
   441         self.Bind(wx.EVT_TOOL, self.OnLDBranchTool, 
       
   442               id=wxID_PLCOPENEDITORLDTOOLBARITEMS4)
       
   443     
       
   444     def init_toolbars(self, parent):
       
   445         self.DefaultToolBar = wxToolBar(id=wxID_PLCOPENEDITORDEFAULTTOOLBAR, name='DefaultToolBar',
       
   446               parent=parent, pos=wx.Point(0, 27), size=wx.Size(0, 0),
       
   447               style=wxTB_HORIZONTAL | wxNO_BORDER)
       
   448 
       
   449         self.SFCToolBar = wxToolBar(id=wxID_PLCOPENEDITORSFCTOOLBAR, name='SFCToolBar',
       
   450               parent=parent, pos=wx.Point(0, 27), size=wx.Size(0, 0),
       
   451               style=wxTB_HORIZONTAL | wxNO_BORDER)
       
   452         
       
   453         self.FBDToolBar = wxToolBar(id=wxID_PLCOPENEDITORFBDTOOLBAR, name='FBDToolBar',
       
   454               parent=parent, pos=wx.Point(0, 27), size=wx.Size(0, 0),
       
   455               style=wxTB_HORIZONTAL | wxNO_BORDER)
       
   456         
       
   457         self.LDToolBar = wxToolBar(id=wxID_PLCOPENEDITORLDTOOLBAR, name='LDToolBar',
       
   458               parent=parent, pos=wx.Point(0, 27), size=wx.Size(0, 0),
       
   459               style=wxTB_HORIZONTAL | wxNO_BORDER)
       
   460               
       
   461         self.init_coll_DefaultToolBar_Items(self.DefaultToolBar)
       
   462         self.init_coll_SFCToolBar_Items(self.SFCToolBar)
       
   463         self.init_coll_FBDToolBar_Items(self.FBDToolBar)
       
   464         self.init_coll_LDToolBar_Items(self.LDToolBar)
       
   465 
       
   466     def __init__(self, parent):
       
   467         self._init_ctrls(parent)
       
   468         self.init_toolbars(self)
       
   469         
       
   470         self.Controler = PLCControler()
       
   471         
       
   472         if fileOpen:
       
   473             self.Controler.OpenXMLFile(fileOpen)
       
   474             self.RefreshProjectTree()
       
   475 
       
   476         self.RefreshFileMenu()
       
   477         self.RefreshEditMenu()
       
   478         self.RefreshToolBar()
       
   479 
       
   480     def RefreshFileMenu(self):
       
   481         if self.Controler.HasOpenedProject():
       
   482             if self.TabsOpened.GetPageCount() > 0:
       
   483                 self.FileMenu.FindItemByPosition(2).Enable(True)
       
   484             else:
       
   485                 self.FileMenu.FindItemByPosition(2).Enable(False)
       
   486             self.FileMenu.FindItemByPosition(3).Enable(True)
       
   487             self.FileMenu.FindItemByPosition(5).Enable(True)
       
   488             self.FileMenu.FindItemByPosition(6).Enable(True)
       
   489             self.FileMenu.FindItemByPosition(7).Enable(True)
       
   490             self.FileMenu.FindItemByPosition(9).Enable(True)
       
   491         else:
       
   492             self.FileMenu.FindItemByPosition(2).Enable(False)
       
   493             self.FileMenu.FindItemByPosition(3).Enable(False)
       
   494             self.FileMenu.FindItemByPosition(5).Enable(False)
       
   495             self.FileMenu.FindItemByPosition(6).Enable(False)
       
   496             self.FileMenu.FindItemByPosition(7).Enable(False)
       
   497             self.FileMenu.FindItemByPosition(9).Enable(False)
       
   498 
       
   499     def RefreshEditMenu(self):
       
   500         self.EditMenu.FindItemByPosition(1).Enable(False)
       
   501         self.EditMenu.FindItemByPosition(2).Enable(False)
       
   502         if self.Controler.HasOpenedProject():
       
   503             if self.TabsOpened.GetPageCount() > 0:
       
   504                 self.EditMenu.FindItemByPosition(0).Enable(True)
       
   505             else:
       
   506                 self.EditMenu.FindItemByPosition(0).Enable(False)
       
   507             self.EditMenu.FindItemByPosition(8).Enable(True)
       
   508             self.EditMenu.FindItemByPosition(9).Enable(True)
       
   509         else:
       
   510             self.EditMenu.FindItemByPosition(0).Enable(False)
       
   511             self.EditMenu.FindItemByPosition(8).Enable(False)
       
   512             self.EditMenu.FindItemByPosition(9).Enable(False)
       
   513         bodytype = self.Controler.GetCurrentElementEditingBodyType()
       
   514         if bodytype in ["LD","ST"]:
       
   515             self.EditMenu.FindItemByPosition(4).Enable(True)
       
   516             self.EditMenu.FindItemByPosition(5).Enable(True)
       
   517             self.EditMenu.FindItemByPosition(6).Enable(True)
       
   518         else:
       
   519             self.EditMenu.FindItemByPosition(4).Enable(False)
       
   520             self.EditMenu.FindItemByPosition(5).Enable(False)
       
   521             self.EditMenu.FindItemByPosition(6).Enable(False)
       
   522 
       
   523     def OnNewProjectMenu(self, event):
       
   524         dialog = ProjectDialog(self)
       
   525         if dialog.ShowModal() == wxID_OK:
       
   526             values = dialog.GetValues()
       
   527             projectname = values.pop("projectName")
       
   528             values["creationDateTime"] = datetime(*localtime()[:6])
       
   529             self.Controler.CreateNewProject(projectname)
       
   530             self.Controler.SetProjectProperties(values)
       
   531             self.RefreshFileMenu()
       
   532             self.RefreshEditMenu()
       
   533             self.RefreshProjectTree()
       
   534         event.Skip()
       
   535 
       
   536     def OnOpenProjectMenu(self, event):
       
   537         filepath = self.Controler.GetFilePath()
       
   538         if filepath != "":
       
   539             directory = os.path.dirname(filepath)
       
   540         else:
       
   541             directory = os.getcwd()
       
   542         dialog = wxFileDialog(self, "Choose a file", directory, "",  "PLCOpen files (*.xml)|*.xml|All files|*.*", wxOPEN)
       
   543         if dialog.ShowModal() == wxID_OK:
       
   544             filepath = dialog.GetPath()
       
   545             if os.path.isfile(filepath):
       
   546                 self.Controler.OpenXMLFile(filepath)
       
   547                 self.TabsOpened.DeleteAllPages()
       
   548                 self.RefreshProjectTree()
       
   549             self.RefreshFileMenu()
       
   550             self.RefreshEditMenu()
       
   551             self.RefreshToolBar()
       
   552         dialog.Destroy()
       
   553         event.Skip()
       
   554 
       
   555     def OnCloseTabMenu(self, event):
       
   556         selected = self.TabsOpened.GetSelection()
       
   557         if selected >= 0:
       
   558             self.Controler.CloseElementEditing()
       
   559             self.TabsOpened.DeletePage(selected)
       
   560             if self.TabsOpened.GetPageCount() > 0:
       
   561                 self.TabsOpened.SetSelection(min(selected, self.TabsOpened.GetPageCount() - 1))
       
   562             self.RefreshFileMenu()
       
   563             self.RefreshEditMenu()
       
   564             self.RefreshToolBar()
       
   565         event.Skip()
       
   566     
       
   567     def OnCloseProjectMenu(self, event):
       
   568         self.Controler.Reset()
       
   569         self.TabsOpened.DeleteAllPages()
       
   570         self.ProjectTree.DeleteAllItems()
       
   571         self.RefreshFileMenu()
       
   572         self.RefreshEditMenu()
       
   573         self.RefreshToolBar()
       
   574         event.Skip()
       
   575 
       
   576     def OnSaveProjectMenu(self, event):
       
   577         self.SaveProject()
       
   578         event.Skip()
       
   579 
       
   580     def OnSaveProjectAsMenu(self, event):
       
   581         self.SaveProjectAs()
       
   582         event.Skip()
       
   583 
       
   584     def OnGenerateProgramMenu(self, event):
       
   585         self.Controler.GenerateProgram()
       
   586         event.Skip()
       
   587 
       
   588     def SaveProject(self):
       
   589         result = self.Controler.SaveXMLFile()
       
   590         if not result:
       
   591             self.SaveProjectAs()
       
   592     
       
   593     def SaveProjectAs(self):
       
   594         filepath = self.Controler.GetFilePath()
       
   595         if filepath != "":
       
   596             directory, filename = os.path.split(filepath)
       
   597         else:
       
   598             directory, filename = os.getcwd(), "%s.od"%self.Controler.GetProjectName()
       
   599         dialog = wxFileDialog(self, "Choose a file", directory, filename,  "PLCOpen files (*.xml)|*.xml|All files|*.*", wxSAVE|wxOVERWRITE_PROMPT)
       
   600         if dialog.ShowModal() == wxID_OK:
       
   601             filepath = dialog.GetPath()
       
   602             if os.path.isdir(os.path.dirname(filepath)):
       
   603                 result = self.Controler.SaveXMLFile(filepath)
       
   604                 if not result:
       
   605                     message = wxMessageDialog(self, "Can't save project to file %s!"%filepath, "Error", wxOK|wxICON_ERROR)
       
   606                     message.ShowModal()
       
   607                     message.Destroy()
       
   608             else:
       
   609                 message = wxMessageDialog(self, "%s is not a valid folder!"%os.path.dirname(filepath), "Error", wxOK|wxICON_ERROR)
       
   610                 message.ShowModal()
       
   611                 message.Destroy()
       
   612         dialog.Destroy()
       
   613 
       
   614     def OnQuitMenu(self, event):
       
   615         self.Close()
       
   616         event.Skip()
       
   617 
       
   618     def OnSelectionTool(self, event):
       
   619         selected = self.TabsOpened.GetSelection()
       
   620         if selected != -1:
       
   621             self.TabsOpened.GetPage(selected).SetMode(MODE_SELECTION)
       
   622         event.Skip()
       
   623     
       
   624     def OnCommentTool(self, event):
       
   625         selected = self.TabsOpened.GetSelection()
       
   626         if selected != -1:
       
   627             self.TabsOpened.GetPage(selected).SetMode(MODE_COMMENT)
       
   628         event.Skip()
       
   629 
       
   630     def OnWireTool(self, event):
       
   631         selected = self.TabsOpened.GetSelection()
       
   632         if selected != -1:
       
   633             self.TabsOpened.GetPage(selected).SetMode(MODE_WIRE)
       
   634         event.Skip()
       
   635     
       
   636     def OnSFCInitialStepTool(self, event):
       
   637         selected = self.TabsOpened.GetSelection()
       
   638         if selected != -1:
       
   639             self.TabsOpened.GetPage(selected).SetMode(MODE_INITIAL_STEP)
       
   640         event.Skip()
       
   641     
       
   642     def OnSFCStepTool(self, event):
       
   643         selected = self.TabsOpened.GetSelection()
       
   644         if selected != -1:
       
   645             self.TabsOpened.GetPage(selected).AddStep()
       
   646         event.Skip()
       
   647 
       
   648     def OnSFCActionBlockTool(self, event):
       
   649         selected = self.TabsOpened.GetSelection()
       
   650         if selected != -1:
       
   651             self.TabsOpened.GetPage(selected).AddStepAction()
       
   652         event.Skip()
       
   653 
       
   654     def OnSFCDivergenceTool(self, event):
       
   655         selected = self.TabsOpened.GetSelection()
       
   656         if selected != -1:
       
   657             self.TabsOpened.GetPage(selected).AddDivergence()
       
   658         event.Skip()
       
   659     
       
   660     def OnSFCJumpTool(self, event):
       
   661         selected = self.TabsOpened.GetSelection()
       
   662         if selected != -1:
       
   663             self.TabsOpened.GetPage(selected).AddJump()
       
   664         event.Skip()
       
   665     
       
   666     def OnFBDVariableTool(self, event):
       
   667         selected = self.TabsOpened.GetSelection()
       
   668         if selected != -1:
       
   669             self.TabsOpened.GetPage(selected).SetMode(MODE_VARIABLE)
       
   670         event.Skip()
       
   671     
       
   672     def OnFBDBlockTool(self, event):
       
   673         selected = self.TabsOpened.GetSelection()
       
   674         if selected != -1:
       
   675             self.TabsOpened.GetPage(selected).SetMode(MODE_BLOCK)
       
   676         event.Skip()
       
   677         
       
   678     def OnFBDConnectionTool(self, event):
       
   679         selected = self.TabsOpened.GetSelection()
       
   680         if selected != -1:
       
   681             self.TabsOpened.GetPage(selected).SetMode(MODE_CONNECTION)
       
   682         event.Skip()
       
   683 
       
   684     def OnLDCoilTool(self, event):
       
   685         selected = self.TabsOpened.GetSelection()
       
   686         if selected != -1:
       
   687             self.TabsOpened.GetPage(selected).AddRung()
       
   688         event.Skip()
       
   689     
       
   690     def OnLDContactTool(self, event):
       
   691         selected = self.TabsOpened.GetSelection()
       
   692         if selected != -1:
       
   693             self.TabsOpened.GetPage(selected).AddContact()
       
   694         event.Skip()
       
   695     
       
   696     def OnLDBlockTool(self, event):
       
   697         selected = self.TabsOpened.GetSelection()
       
   698         if selected != -1:
       
   699             pass
       
   700         event.Skip()
       
   701     
       
   702     def OnLDBranchTool(self, event): 
       
   703         selected = self.TabsOpened.GetSelection()
       
   704         if selected != -1:
       
   705             self.TabsOpened.GetPage(selected).AddBranch()
       
   706         event.Skip()
       
   707         
       
   708     def OnPouSelectedChanged(self, event):
       
   709         selected = event.GetSelection()
       
   710         if selected >= 0:
       
   711             self.Controler.RefreshCurrentElementEditing(selected)
       
   712             found = False
       
   713             name = self.TabsOpened.GetPageText(selected)
       
   714             root = self.ProjectTree.GetRootItem()
       
   715             item, root_cookie = self.ProjectTree.GetFirstChild(root)
       
   716             while item.IsOk() and not found:
       
   717                 if self.ProjectTree.GetItemText(item) == name:
       
   718                     self.ProjectTree.SelectItem(item)
       
   719                 item, root_cookie = self.ProjectTree.GetNextChild(root, root_cookie)
       
   720             self.RefreshFileMenu()
       
   721             self.RefreshEditMenu()
       
   722             self.RefreshToolBar()
       
   723         event.Skip()
       
   724 
       
   725     def OnProjectTreeItemEndEdit(self, event):
       
   726         new_name = event.GetLabel()
       
   727         if new_name != "":
       
   728             if TestIdentifier(new_name):
       
   729                 item = event.GetItem()
       
   730                 itemtype = self.ProjectTree.GetPyData(item)
       
   731                 if itemtype == ITEM_PROJECT:
       
   732                     self.Controler.SetProjectName(new_name)
       
   733                 elif itemtype == ITEM_POU:
       
   734                     old_name = self.ProjectTree.GetItemText(item)
       
   735                     self.Controler.ChangePouName(old_name, new_name)
       
   736                     self.RefreshTabsOpenedTitles()
       
   737                 elif itemtype == ITEM_TRANSITION:
       
   738                     old_name = self.ProjectTree.GetItemText(item)
       
   739                     parent = self.ProjectTree.GetItemParent(item)
       
   740                     grandparent = self.ProjectTree.GetItemParent(parent)
       
   741                     grandparent_name = self.ProjectTree.GetItemText(grandparent)
       
   742                     self.Controler.ChangePouTransitionName(grandparent_name, old_name, new_name)
       
   743                     self.RefreshTabsOpenedTitles()
       
   744                 elif itemtype == ITEM_ACTION:
       
   745                     old_name = self.ProjectTree.GetItemText(item)
       
   746                     parent = self.ProjectTree.GetItemParent(item)
       
   747                     grandparent = self.ProjectTree.GetItemParent(parent)
       
   748                     grandparent_name = self.ProjectTree.GetItemText(grandparent)
       
   749                     self.Controler.ChangePouActionName(grandparent_name, old_name, new_name)
       
   750                     self.RefreshTabsOpenedTitles()
       
   751                 wxCallAfter(self.RefreshProjectTree)
       
   752                 event.Skip()
       
   753             else:
       
   754                 message = wxMessageDialog(self, "\"%s\" is not a valid identifier!"%new_name, "Error", wxOK|wxICON_ERROR)
       
   755                 message.ShowModal()
       
   756                 message.Destroy()
       
   757                 item = event.GetItem()
       
   758                 wxCallAfter(self.ProjectTree.EditLabel, item)
       
   759                 event.Veto()
       
   760 
       
   761     def OnProjectTreeItemBeginEdit(self, event):
       
   762         selected = event.GetItem()
       
   763         if self.ProjectTree.GetPyData(selected) == ITEM_UNEDITABLE:
       
   764             event.Veto()
       
   765         else:
       
   766             event.Skip()
       
   767     
       
   768     def OnProjectTreeItemActivated(self, event):
       
   769         selected = event.GetItem()
       
   770         if self.ProjectTree.IsExpanded(selected):
       
   771             self.ProjectTree.Collapse(selected)
       
   772         else:
       
   773             self.ProjectTree.Expand(selected)
       
   774         name = self.ProjectTree.GetItemText(selected)
       
   775         data = self.ProjectTree.GetPyData(selected)
       
   776         if name == "Properties":
       
   777             old_values = self.Controler.GetProjectProperties()
       
   778             old_values["projectName"] = self.Controler.GetProjectName()
       
   779             dialog = ProjectDialog(self)
       
   780             dialog.SetValues(old_values)
       
   781             if dialog.ShowModal() == wxID_OK:
       
   782                 new_values = dialog.GetValues()
       
   783                 projectname = new_values.pop("projectName")
       
   784                 new_values["creationDateTime"] = old_values["creationDateTime"]
       
   785                 self.Controler.SetProjectName(projectname)
       
   786                 self.Controler.SetProjectProperties(new_values)
       
   787                 self.RefreshProjectTree()
       
   788             dialog.Destroy()
       
   789         elif data == ITEM_CLASS:
       
   790             item = self.ProjectTree.GetItemParent(selected)
       
   791             item_type = self.ProjectTree.GetPyData(item)
       
   792             while item_type != ITEM_POU:
       
   793                 item = self.ProjectTree.GetItemParent(item)
       
   794                 item_type = self.ProjectTree.GetPyData(item)
       
   795             pou_name = self.ProjectTree.GetItemText(item)
       
   796             dialog = EditVariableDialog(self, pou_name, self.Controler.GetPouType(pou_name), name)
       
   797             values = {}
       
   798             values["returnType"] = self.Controler.GetPouInterfaceReturnTypeByName(pou_name)
       
   799             values["data"] = self.Controler.GetPouInterfaceVarsByName(pou_name)
       
   800             dialog.SetValues(values)
       
   801             if dialog.ShowModal() == wxID_OK:
       
   802                 if not self.Controler.PouIsUsed(pou_name):
       
   803                     new_values = dialog.GetValues()
       
   804                     if "returnType" in new_values:
       
   805                         self.Controler.SetPouInterfaceReturnType(pou_name, new_values["returnType"])
       
   806                     self.Controler.SetPouInterfaceVars(pou_name, new_values["data"])
       
   807                     pou_names = self.Controler.GetElementsOpenedNames()
       
   808                     if pou_name in pou_names:
       
   809                         window = self.TabsOpened.GetPage(pou_names.index(pou_name))
       
   810                         if isinstance(window, TextViewer):
       
   811                             varlist = []
       
   812                             if "returnType" in new_values:
       
   813                                 varlist.append(name)
       
   814                             for var in new_values["data"]:
       
   815                                 varlist.append(var["Name"])
       
   816                             window.SetVariables(varlist)
       
   817                 else:
       
   818                     message = wxMessageDialog(self, "\"%s\" is used by one or more POUs. Its interface can't be changed!"%pou_name, "Error", wxOK|wxICON_ERROR)
       
   819                     message.ShowModal()
       
   820                     message.Destroy()
       
   821             dialog.Destroy()
       
   822         elif name == "Global Vars":
       
   823             parent = self.ProjectTree.GetItemParent(selected)
       
   824             parent_name = self.ProjectTree.GetItemText(parent)
       
   825             dialog = EditVariableDialog(self, parent_name, None)
       
   826             if self.ProjectTree.GetPyData(parent) == ITEM_CONFIGURATION:
       
   827                 values = {"data" : self.Controler.GetConfigurationGlobalVars(parent_name)}
       
   828                 dialog.SetValues(values)
       
   829                 if dialog.ShowModal() == wxID_OK:
       
   830                     new_values = dialog.GetValues()
       
   831                     self.Controler.SetConfigurationGlobalVars(parent_name, new_values["data"])
       
   832             else:
       
   833                 config = self.ProjectTree.GetItemParent(parent)
       
   834                 config_name = self.ProjectTree.GetItemText(config)
       
   835                 values = {"data" : self.Controler.GetConfigurationResourceGlobalVars(config_name, parent_name)}
       
   836                 dialog.SetValues(values)
       
   837                 if dialog.ShowModal() == wxID_OK:
       
   838                     new_values = dialog.GetValues()
       
   839                     self.Controler.SetConfigurationResourceGlobalVars(config_name, parent_name, new_values["data"])
       
   840         elif data in [ITEM_POU, ITEM_TRANSITION, ITEM_ACTION]:
       
   841             if data == ITEM_POU:
       
   842                 idx = self.Controler.OpenElementEditing(name)
       
   843                 language = self.Controler.GetPouBodyType(name)
       
   844                 varlist = []
       
   845                 returnType = self.Controler.GetPouInterfaceReturnTypeByName(name)
       
   846                 if returnType:
       
   847                     varlist.append(name)
       
   848                 vars = self.Controler.GetPouInterfaceVarsByName(name)
       
   849                 if vars:
       
   850                     for var in vars:
       
   851                         varlist.append(var["Name"])
       
   852             else:
       
   853                 parent = self.ProjectTree.GetItemParent(selected)
       
   854                 parent_name = self.ProjectTree.GetItemText(parent)
       
   855                 grandparent = self.ProjectTree.GetItemParent(parent)
       
   856                 grandparent_name = self.ProjectTree.GetItemText(grandparent)
       
   857                 if data == ITEM_TRANSITION:
       
   858                     idx = self.Controler.OpenPouTransitionEditing(grandparent_name, name)
       
   859                     language = self.Controler.GetTransitionBodyType(grandparent_name, name)
       
   860                 elif data == ITEM_ACTION:
       
   861                     idx = self.Controler.OpenPouActionEditing(grandparent_name, name)
       
   862                     language = self.Controler.GetActionBodyType(grandparent_name, name)
       
   863                 varlist = [name]
       
   864                 vars = self.Controler.GetPouInterfaceVarsByName(grandparent_name)
       
   865                 if vars:
       
   866                     for var in vars:
       
   867                         varlist.append(var["Name"])
       
   868             if idx != None:
       
   869                 if language == "FBD":
       
   870                     new_window = FBD_Viewer(self.TabsOpened, self, self.Controler)
       
   871                 elif language == "LD":
       
   872                     new_window = LD_Viewer(self.TabsOpened, self, self.Controler)
       
   873                 elif language == "SFC":
       
   874                     new_window = SFC_Viewer(self.TabsOpened, self, self.Controler)
       
   875                 elif language in ["IL", "ST"]:
       
   876                     new_window = TextViewer(self.TabsOpened, self, self.Controler)
       
   877                     if language == "IL":
       
   878                         new_window.SetKeywords(IL_KEYWORDS)
       
   879                     else:
       
   880                         new_window.SetKeywords(ST_KEYWORDS)
       
   881                     new_window.SetVariables(varlist)
       
   882                     new_window.SetFunctions(self.Controler.GetBlockTypes())
       
   883                 else:
       
   884                     return
       
   885                 new_window.RefreshView()
       
   886                 self.TabsOpened.AddPage(new_window, "")
       
   887                 self.TabsOpened.SetSelection(idx)
       
   888                 self.RefreshTabsOpenedTitles()
       
   889                 self.RefreshFileMenu()
       
   890                 self.RefreshEditMenu()
       
   891                 self.RefreshToolBar()
       
   892             else:
       
   893                 if data == ITEM_POU:
       
   894                     idx = self.Controler.ChangeElementEditing(name)
       
   895                 elif data == ITEM_TRANSITION:
       
   896                     idx = self.Controler.ChangePouTransitionEditing(grandparent_name, name)
       
   897                 elif data == ITEM_ACTION:
       
   898                     idx = self.Controler.ChangePouActionEditing(grandparent_name, name)
       
   899                 if idx != None:
       
   900                     self.TabsOpened.SetSelection(idx)
       
   901                     self.RefreshFileMenu()
       
   902                     self.RefreshEditMenu()
       
   903                     self.RefreshToolBar()
       
   904         elif data == ITEM_RESOURCE:
       
   905             item = self.ProjectTree.GetItemParent(selected)
       
   906             item_type = self.ProjectTree.GetPyData(item)
       
   907             while item_type != ITEM_CONFIGURATION:
       
   908                 item = self.ProjectTree.GetItemParent(item)
       
   909                 item_type = self.ProjectTree.GetPyData(item)
       
   910             config_name = self.ProjectTree.GetItemText(item)
       
   911             idx = self.Controler.OpenConfigurationResourceEditing(config_name, name)
       
   912             if idx != None:
       
   913                 new_window = ResourceEditor(self.TabsOpened, self, self.Controler)
       
   914                 new_window.RefreshView()
       
   915                 self.TabsOpened.AddPage(new_window, "")
       
   916                 self.TabsOpened.SetSelection(idx)
       
   917                 self.RefreshTabsOpenedTitles()
       
   918                 self.RefreshFileMenu()
       
   919                 self.RefreshEditMenu()
       
   920                 self.RefreshToolBar()
       
   921             else:
       
   922                 idx = self.Controler.ChangeConfigurationResourceEditing(parent_name, name)
       
   923                 if idx != None:
       
   924                     self.TabsOpened.SetSelection(idx)
       
   925                     self.RefreshFileMenu()
       
   926                     self.RefreshEditMenu()
       
   927                     self.RefreshToolBar()
       
   928     
       
   929     def OnProjectTreeRightUp(self, event):
       
   930         selected = self.ProjectTree.GetSelection()
       
   931         if self.ProjectTree.GetPyData(selected) == ITEM_POU:
       
   932             name = self.ProjectTree.GetItemText(selected)
       
   933             if self.Controler.GetPouBodyType(name) == "SFC":
       
   934                 self.PopupMenu(self.SFCMenu)
       
   935         elif self.ProjectTree.GetPyData(selected) == ITEM_CONFIGURATION:
       
   936             self.PopupMenu(self.ConfigMenu)
       
   937         event.Skip()
       
   938     
       
   939     def OnProjectTreeItemSelected(self, event):
       
   940         selected = event.GetItem()
       
   941         name = self.ProjectTree.GetItemText(selected)
       
   942         if self.ProjectTree.GetItemParent(selected) == self.ProjectTree.GetRootItem() and name != "Properties":
       
   943             if self.Controler.IsElementEditing(name):
       
   944                 idx = self.Controler.ChangeElementEditing(name)
       
   945                 if idx != None:
       
   946                     self.TabsOpened.SetSelection(idx)
       
   947                     self.RefreshFileMenu()
       
   948                     self.RefreshEditMenu()
       
   949                     self.RefreshToolBar()
       
   950         else:
       
   951             name = self.ProjectTree.GetItemText(selected)
       
   952             parent = self.ProjectTree.GetItemParent(selected)
       
   953             parent_name = self.ProjectTree.GetItemText(parent)
       
   954             grandparent = self.ProjectTree.GetItemParent(parent)
       
   955             grandparent_name = self.ProjectTree.GetItemText(grandparent)
       
   956             if parent_name == "Transitions":
       
   957                 idx = self.Controler.ChangePouTransitionEditing(grandparent_name, name)
       
   958                 if idx != None:
       
   959                     self.TabsOpened.SetSelection(idx)
       
   960                     self.RefreshFileMenu()
       
   961                     self.RefreshEditMenu()
       
   962                     self.RefreshToolBar()
       
   963             elif parent_name == "Action":
       
   964                 idx = self.Controler.ChangePouActionEditing(grandparent_name, name)
       
   965                 if idx != None:
       
   966                     self.TabsOpened.SetSelection(idx)
       
   967                     self.RefreshFileMenu()
       
   968                     self.RefreshEditMenu()
       
   969                     self.RefreshToolBar()
       
   970         event.Skip()
       
   971 
       
   972     def RefreshProjectTree(self):
       
   973         infos = self.Controler.GetProjectInfos()
       
   974         root = self.ProjectTree.GetRootItem()
       
   975         self.GenerateTreeBranch(root, infos)
       
   976         self.ProjectTree.Expand(self.ProjectTree.GetRootItem())
       
   977 
       
   978     def GenerateTreeBranch(self, root, infos):
       
   979         to_delete = []
       
   980         if root.IsOk():
       
   981             self.ProjectTree.SetItemText(root, infos["name"])
       
   982         else:
       
   983             root = self.ProjectTree.AddRoot(infos["name"])
       
   984         self.ProjectTree.SetPyData(root, infos["type"])
       
   985         item, root_cookie = self.ProjectTree.GetFirstChild(root)
       
   986         if len(infos["values"]) > 0:
       
   987             for values in infos["values"]:
       
   988                 if not item.IsOk():
       
   989                     item = self.ProjectTree.AppendItem(root, "")
       
   990                     item, root_cookie = self.ProjectTree.GetNextChild(root, root_cookie)
       
   991                 self.GenerateTreeBranch(item, values)
       
   992                 item, root_cookie = self.ProjectTree.GetNextChild(root, root_cookie)
       
   993         while item.IsOk():
       
   994             to_delete.append(item)
       
   995             item, root_cookie = self.ProjectTree.GetNextChild(item, root_cookie)
       
   996         for item in to_delete:
       
   997             self.ProjectTree.Delete(item)
       
   998 
       
   999     def RefreshToolBar(self):
       
  1000         language = self.Controler.GetCurrentElementEditingBodyType()
       
  1001         if language == "SFC":
       
  1002             self.SFCToolBar.ToggleTool(0, True)
       
  1003             self.SFCToolBar.Show()
       
  1004             self.SetToolBar(self.SFCToolBar)
       
  1005             self.DefaultToolBar.Hide()
       
  1006             self.FBDToolBar.Hide()
       
  1007             self.LDToolBar.Hide()
       
  1008         elif language == "FBD":
       
  1009             self.FBDToolBar.ToggleTool(0, True)
       
  1010             self.FBDToolBar.Show()
       
  1011             self.SetToolBar(self.FBDToolBar)
       
  1012             self.DefaultToolBar.Hide()
       
  1013             self.SFCToolBar.Hide()
       
  1014             self.LDToolBar.Hide()
       
  1015         elif language == "LD":
       
  1016             self.LDToolBar.ToggleTool(0, True)
       
  1017             self.LDToolBar.Show()
       
  1018             self.SetToolBar(self.LDToolBar)
       
  1019             self.DefaultToolBar.Hide()
       
  1020             self.SFCToolBar.Hide()
       
  1021             self.FBDToolBar.Hide()
       
  1022         else:
       
  1023             self.DefaultToolBar.ToggleTool(0, True)
       
  1024             self.DefaultToolBar.Show()
       
  1025             self.SetToolBar(self.DefaultToolBar)
       
  1026             self.SFCToolBar.Hide()
       
  1027             self.FBDToolBar.Hide()
       
  1028             self.LDToolBar.Hide()
       
  1029 
       
  1030     def RefreshTabsOpenedTitles(self):
       
  1031         pous = self.Controler.GetElementsOpenedNames()
       
  1032         for i, pou in enumerate(pous):
       
  1033             self.TabsOpened.SetPageText(i, pou)
       
  1034     
       
  1035     def OnRefreshMenu(self, event):
       
  1036         selected = self.TabsOpened.GetSelection()
       
  1037         if selected != -1:
       
  1038             self.TabsOpened.GetPage(selected).Refresh()
       
  1039         event.Skip()
       
  1040     
       
  1041     def OnCutMenu(self, event):
       
  1042         selected = self.TabsOpened.GetSelection()
       
  1043         if selected != -1:
       
  1044             self.TabsOpened.GetPage(selected).Cut()
       
  1045         event.Skip()
       
  1046     
       
  1047     def OnCopyMenu(self, event):
       
  1048         selected = self.TabsOpened.GetSelection()
       
  1049         if selected != -1:
       
  1050             self.TabsOpened.GetPage(selected).Copy()
       
  1051         event.Skip()
       
  1052     
       
  1053     def OnPasteMenu(self, event):
       
  1054         selected = self.TabsOpened.GetSelection()
       
  1055         if selected != -1:
       
  1056             self.TabsOpened.GetPage(selected).Paste()
       
  1057         event.Skip()
       
  1058     
       
  1059     def OnAddPouMenu(self, event):
       
  1060         dialog = PouDialog(self)
       
  1061         dialog.SetPouNames(self.Controler.GetProjectPouNames())
       
  1062         if dialog.ShowModal() == wxID_OK:
       
  1063             values = dialog.GetValues()
       
  1064             self.Controler.ProjectAddPou(values["pouName"], values["pouType"], values["language"])
       
  1065             self.RefreshProjectTree()
       
  1066         dialog.Destroy()
       
  1067         event.Skip()
       
  1068 
       
  1069     def OnRemovePouMenu(self, event):
       
  1070         pous = self.Controler.GetProjectPouNames()
       
  1071         dialog = wxSingleChoiceDialog(self, "Select POU to remove:", "POU Remove", pous, wxOK|wxCANCEL)
       
  1072         if dialog.ShowModal() == wxID_OK:
       
  1073             selected = dialog.GetStringSelection()
       
  1074             if not self.Controler.PouIsUsed(selected):
       
  1075                 self.Controler.ProjectRemovePou(selected)
       
  1076                 for i in xrange(self.TabsOpened.GetPageCount()):
       
  1077                     if self.TabsOpened.GetPageText(i) == selected:
       
  1078                         self.TabsOpened.DeletePage(i)
       
  1079                 self.RefreshProjectTree()
       
  1080                 self.RefreshToolBar()
       
  1081             else:
       
  1082                 message = wxMessageDialog(self, "%s is used by one or more POUs. It can't be removed!"%selected, "Error", wxOK|wxICON_ERROR)
       
  1083                 message.ShowModal()
       
  1084                 message.Destroy()
       
  1085         event.Skip()
       
  1086 
       
  1087     def OnAddConfigurationMenu(self, event):
       
  1088         dialog = wxTextEntryDialog(self, "Enter configuration name:", "Create new configuration", "", wxOK|wxCANCEL)
       
  1089         if dialog.ShowModal() == wxID_OK:
       
  1090             value = dialog.GetValue()
       
  1091             self.Controler.ProjectAddConfiguration(value)
       
  1092             self.RefreshProjectTree()
       
  1093         dialog.Destroy()
       
  1094         event.Skip()
       
  1095 
       
  1096     def OnRemoveConfigurationMenu(self, event):
       
  1097         configs = self.Controler.GetProjectConfigNames()
       
  1098         dialog = wxSingleChoiceDialog(self, "Select Configuration to remove:", "Configuration Remove", configs, wxOK|wxCANCEL)
       
  1099         if dialog.ShowModal() == wxID_OK:
       
  1100             selected = dialog.GetStringSelection()
       
  1101             self.Controler.ProjectRemoveConfiguration(selected)
       
  1102             self.RefreshProjectTree()
       
  1103         event.Skip()
       
  1104 
       
  1105     def OnAddPouTransitionMenu(self, event):
       
  1106         dialog = PouTransitionDialog(self)
       
  1107         dialog.SetPous(self.Controler.GetSFCPous())
       
  1108         if dialog.ShowModal() == wxID_OK: 
       
  1109             values = dialog.GetValues()
       
  1110             self.Controler.ProjectAddPouTransition(values["pouName"], values["transitionName"], values["language"])
       
  1111             self.RefreshProjectTree()
       
  1112         dialog.Destroy()
       
  1113         event.Skip()
       
  1114 
       
  1115     def OnRemovePouTransitionMenu(self, event):
       
  1116         event.Skip()
       
  1117 
       
  1118     def OnAddPouActionMenu(self, event):
       
  1119         dialog = PouActionDialog(self)
       
  1120         dialog.SetPous(self.Controler.GetSFCPous())
       
  1121         if dialog.ShowModal() == wxID_OK:
       
  1122             values = dialog.GetValues()
       
  1123             self.Controler.ProjectAddPouAction(values["pouName"], values["actionName"], values["language"])
       
  1124             self.RefreshProjectTree()
       
  1125         dialog.Destroy()
       
  1126         event.Skip()
       
  1127 
       
  1128     def OnRemovePouActionMenu(self, event):
       
  1129         event.Skip()
       
  1130 
       
  1131     def OnAddResourceMenu(self, event):
       
  1132         selected = self.ProjectTree.GetSelection()
       
  1133         if self.ProjectTree.GetPyData(selected) == ITEM_CONFIGURATION:
       
  1134             config_name = self.ProjectTree.GetItemText(selected)
       
  1135             dialog = wxTextEntryDialog(self, "Enter Resource name:", "Create new Resource", "", wxOK|wxCANCEL)
       
  1136             if dialog.ShowModal() == wxID_OK:
       
  1137                 value = dialog.GetValue()
       
  1138                 self.Controler.ProjectAddConfigurationResource(config_name, value)
       
  1139                 self.RefreshProjectTree()
       
  1140             dialog.Destroy()
       
  1141         event.Skip()
       
  1142 
       
  1143     def OnRemoveResourceMenu(self, event):
       
  1144         selected = self.ProjectTree.GetSelection()
       
  1145         if self.ProjectTree.GetPyData(selected) == ITEM_CONFIGURATION:
       
  1146             config_name = self.ProjectTree.GetItemText(selected)
       
  1147             infos = self.Controler.GetProjectInfos()
       
  1148             resources = []
       
  1149             for config in infos["configs"]:
       
  1150                 if config["name"] == config_name:
       
  1151                     resources = config["resources"]
       
  1152             dialog = wxSingleChoiceDialog(self, "Select Resource to remove:", "Resource Remove", resources, wxOK|wxCANCEL)
       
  1153             if dialog.ShowModal() == wxID_OK:
       
  1154                 resource = dialog.GetStringSelection()
       
  1155                 self.Controler.ProjectRemoveConfigurationResource(config_name, resource)
       
  1156                 self.RefreshProjectTree()
       
  1157             dialog.Destroy()
       
  1158         event.Skip()
       
  1159 
       
  1160     def OnPLCOpenMenu(self, event):
       
  1161         result = OpenPDFDoc()
       
  1162         if type(result) == StringType:
       
  1163             message = wxMessageDialog(self, result, "ERROR", wxOK|wxICON_ERROR)
       
  1164             message.ShowModal()
       
  1165             message.Destroy()
       
  1166         event.Skip()
       
  1167 
       
  1168 current_num = 0
       
  1169 def GetNewNum():
       
  1170     global current_num
       
  1171     current_num += 1
       
  1172     return current_num
       
  1173 
       
  1174 #-------------------------------------------------------------------------------
       
  1175 #                            Create Project Dialog
       
  1176 #-------------------------------------------------------------------------------
       
  1177 
       
  1178 [wxID_PROJECTDIALOG, wxID_PROJECTDIALOGMAINPANEL, 
       
  1179  wxID_PROJECTDIALOGPROJECTNAME, wxID_PROJECTDIALOGCOMPANYNAME, 
       
  1180  wxID_PROJECTDIALOGCOMPANYURL, wxID_PROJECTDIALOGPRODUCTNAME, 
       
  1181  wxID_PROJECTDIALOGPRODUCTVERSION, wxID_PROJECTDIALOGPRODUCTRELEASE, 
       
  1182  wxID_PROJECTDIALOGCONTENTDESCRIPTION, wxID_PROJECTDIALOGSTATICTEXT1,
       
  1183  wxID_PROJECTDIALOGSTATICTEXT2, wxID_PROJECTDIALOGSTATICTEXT3, 
       
  1184  wxID_PROJECTDIALOGSTATICTEXT4, wxID_PROJECTDIALOGSTATICTEXT5, 
       
  1185  wxID_PROJECTDIALOGSTATICTEXT6, wxID_PROJECTDIALOGSTATICTEXT7, 
       
  1186 ] = [wx.NewId() for _init_ctrls in range(16)]
       
  1187         
       
  1188 class ProjectDialog(wx.Dialog):
       
  1189     def _init_coll_flexGridSizer1_Items(self, parent):
       
  1190         # generated method, don't edit
       
  1191 
       
  1192         parent.AddWindow(self.MainPanel, 0, border=0, flag=0)
       
  1193 
       
  1194     def _init_sizers(self):
       
  1195         # generated method, don't edit
       
  1196         self.flexGridSizer1 = wx.FlexGridSizer(cols=1, hgap=0, rows=2, vgap=0)
       
  1197 
       
  1198         self._init_coll_flexGridSizer1_Items(self.flexGridSizer1)
       
  1199 
       
  1200         self.SetSizer(self.flexGridSizer1)
       
  1201 
       
  1202     def _init_ctrls(self, prnt):
       
  1203         # generated method, don't edit
       
  1204         wx.Dialog.__init__(self, id=wxID_PROJECTDIALOG,
       
  1205               name='ProjectDialog', parent=prnt, pos=wx.Point(376, 223),
       
  1206               size=wx.Size(550, 450), style=wx.DEFAULT_DIALOG_STYLE,
       
  1207               title='Create a new project')
       
  1208         self.SetClientSize(wx.Size(550, 450))
       
  1209 
       
  1210         self.MainPanel = wx.Panel(id=wxID_PROJECTDIALOGMAINPANEL,
       
  1211               name='MainPanel', parent=self, pos=wx.Point(0, 0),
       
  1212               size=wx.Size(450, 400), style=wx.TAB_TRAVERSAL)
       
  1213         self.MainPanel.SetAutoLayout(True)
       
  1214 
       
  1215         self.staticText1 = wx.StaticText(id=wxID_PROJECTDIALOGSTATICTEXT1,
       
  1216               label='Project Name (required):', name='staticText1', parent=self.MainPanel,
       
  1217               pos=wx.Point(24, 24), size=wx.Size(215, 17), style=0)
       
  1218 
       
  1219         self.ProjectName = wx.TextCtrl(id=wxID_PROJECTDIALOGPROJECTNAME,
       
  1220               name='ProjectName', parent=self.MainPanel, pos=wx.Point(224, 24), 
       
  1221               size=wx.Size(295, 24), style=0)
       
  1222 
       
  1223         self.staticText2 = wx.StaticText(id=wxID_PROJECTDIALOGSTATICTEXT2,
       
  1224               label='Company Name (required):', name='staticText2', parent=self.MainPanel,
       
  1225               pos=wx.Point(24, 64), size=wx.Size(215, 17), style=0)
       
  1226 
       
  1227         self.CompanyName = wx.TextCtrl(id=wxID_PROJECTDIALOGCOMPANYNAME,
       
  1228               name='CompanyName', parent=self.MainPanel, pos=wx.Point(224, 64),
       
  1229               size=wx.Size(295, 24), style=0)
       
  1230 
       
  1231         self.staticText3 = wx.StaticText(id=wxID_PROJECTDIALOGSTATICTEXT3,
       
  1232               label='Company URL (optional):', name='staticText3', parent=self.MainPanel,
       
  1233               pos=wx.Point(24, 104), size=wx.Size(215, 17), style=0)
       
  1234 
       
  1235         self.CompanyURL = wx.TextCtrl(id=wxID_PROJECTDIALOGCOMPANYURL,
       
  1236               name='CompanyURL', parent=self.MainPanel, pos=wx.Point(224, 104),
       
  1237               size=wx.Size(295, 24), style=0)
       
  1238 
       
  1239         self.staticText4 = wx.StaticText(id=wxID_PROJECTDIALOGSTATICTEXT4,
       
  1240               label='Product Name (required):', name='staticText4', parent=self.MainPanel,
       
  1241               pos=wx.Point(24, 144), size=wx.Size(215, 17), style=0)
       
  1242 
       
  1243         self.ProductName = wx.TextCtrl(id=wxID_PROJECTDIALOGPRODUCTNAME,
       
  1244               name='ProductName', parent=self.MainPanel, pos=wx.Point(224, 144),
       
  1245               size=wx.Size(295, 24), style=0)
       
  1246 
       
  1247         self.staticText5 = wx.StaticText(id=wxID_PROJECTDIALOGSTATICTEXT5,
       
  1248               label='Product Version (required):', name='staticText5', parent=self.MainPanel,
       
  1249               pos=wx.Point(24, 184), size=wx.Size(215, 17), style=0)
       
  1250 
       
  1251         self.ProductVersion = wx.TextCtrl(id=wxID_PROJECTDIALOGPRODUCTVERSION,
       
  1252               name='ProductVersion', parent=self.MainPanel, pos=wx.Point(224, 184),
       
  1253               size=wx.Size(295, 24), style=0)
       
  1254 
       
  1255         self.staticText6 = wx.StaticText(id=wxID_PROJECTDIALOGSTATICTEXT6,
       
  1256               label='Product Release (optional):', name='staticText6', parent=self.MainPanel,
       
  1257               pos=wx.Point(24, 224), size=wx.Size(215, 17), style=0)
       
  1258 
       
  1259         self.ProductRelease = wx.TextCtrl(id=wxID_PROJECTDIALOGPRODUCTRELEASE,
       
  1260               name='ProductRelease', parent=self.MainPanel, pos=wx.Point(224, 224),
       
  1261               size=wx.Size(295, 24), style=0)
       
  1262 
       
  1263         self.staticText7 = wx.StaticText(id=wxID_PROJECTDIALOGSTATICTEXT7,
       
  1264               label='Content Description (optional):', name='staticText7', parent=self.MainPanel,
       
  1265               pos=wx.Point(24, 264), size=wx.Size(215, 17), style=0)
       
  1266 
       
  1267         self.ContentDescription = wx.TextCtrl(id=wxID_PROJECTDIALOGCONTENTDESCRIPTION,
       
  1268               name='ProductRelease', parent=self.MainPanel, pos=wx.Point(224, 264),
       
  1269               size=wx.Size(295, 120), style=wxTE_MULTILINE)
       
  1270 
       
  1271         self._init_sizers()
       
  1272 
       
  1273     def __init__(self, parent):
       
  1274         self._init_ctrls(parent)
       
  1275         self.ButtonSizer = self.CreateButtonSizer(wxOK|wxCANCEL)
       
  1276         self.flexGridSizer1.Add(self.ButtonSizer, 1, wxALIGN_RIGHT)
       
  1277         
       
  1278         EVT_BUTTON(self, self.ButtonSizer.GetAffirmativeButton().GetId(), self.OnOK)
       
  1279     
       
  1280     def OnOK(self, event):
       
  1281         error = []
       
  1282         if self.ProjectName.GetValue() == "":
       
  1283             error.append("Project Name")
       
  1284         if self.CompanyName.GetValue() == "":
       
  1285             error.append("Company Name")
       
  1286         if self.ProductName.GetValue() == "":
       
  1287             error.append("Product Name")
       
  1288         if self.ProductVersion.GetValue() == "":
       
  1289             error.append("Product Version")
       
  1290         if len(error) > 0:
       
  1291             text = ""
       
  1292             for i, item in enumerate(error):
       
  1293                 if i == 0:
       
  1294                     text += item
       
  1295                 elif i == len(error) - 1:
       
  1296                     text += " and %s"%item
       
  1297                 else:
       
  1298                     text += ", %s"%item 
       
  1299             message = wxMessageDialog(self, "Form isn't complete. %s must be filled!"%text, "Error", wxOK|wxICON_ERROR)
       
  1300             message.ShowModal()
       
  1301             message.Destroy()
       
  1302         else:
       
  1303             self.EndModal(wxID_OK)
       
  1304 
       
  1305     def SetValues(self, values):
       
  1306         for item, value in values.items():
       
  1307             if item == "projectName":
       
  1308                 self.ProjectName.SetValue(value)
       
  1309             elif item == "companyName":
       
  1310                 self.CompanyName.SetValue(value)
       
  1311             elif item == "companyURL":
       
  1312                 self.CompanyURL.SetValue(value)
       
  1313             elif item == "productName":
       
  1314                 self.ProductName.SetValue(value)
       
  1315             elif item == "productVersion":
       
  1316                 self.ProductVersion.SetValue(value)
       
  1317             elif item == "productRelease":
       
  1318                 self.ProductRelease.SetValue(value)
       
  1319             elif item == "contentDescription":
       
  1320                 self.ContentDescription.SetValue(value)
       
  1321 
       
  1322     def GetValues(self):
       
  1323         values = {}
       
  1324         values["projectName"] = self.ProjectName.GetValue()
       
  1325         values["companyName"] = self.CompanyName.GetValue()
       
  1326         if self.CompanyURL.GetValue() != None:
       
  1327             values["companyURL"] = self.CompanyURL.GetValue()
       
  1328         values["productName"] = self.ProductName.GetValue()
       
  1329         values["productVersion"] = self.ProductVersion.GetValue()
       
  1330         if self.ProductRelease.GetValue() != None:
       
  1331             values["productRelease"] = self.ProductRelease.GetValue()
       
  1332         if self.ProductRelease.GetValue() != None:
       
  1333             values["contentDescription"] = self.ContentDescription.GetValue()
       
  1334         return values
       
  1335 
       
  1336 #-------------------------------------------------------------------------------
       
  1337 #                            Create Pou Dialog
       
  1338 #-------------------------------------------------------------------------------
       
  1339 
       
  1340 [wxID_POUDIALOG, wxID_POUDIALOGMAINPANEL, wxID_POUDIALOGPOUNAME, 
       
  1341  wxID_POUDIALOGPOUTYPE, wxID_POUDIALOGLANGUAGE, wxID_POUDIALOGSTATICTEXT1,
       
  1342  wxID_POUDIALOGSTATICTEXT2, wxID_POUDIALOGSTATICTEXT3, 
       
  1343 ] = [wx.NewId() for _init_ctrls in range(8)]
       
  1344 
       
  1345 class PouDialog(wx.Dialog):
       
  1346     def _init_coll_flexGridSizer1_Items(self, parent):
       
  1347         # generated method, don't edit
       
  1348 
       
  1349         parent.AddWindow(self.MainPanel, 0, border=0, flag=0)
       
  1350 
       
  1351     def _init_sizers(self):
       
  1352         # generated method, don't edit
       
  1353         self.flexGridSizer1 = wx.FlexGridSizer(cols=1, hgap=0, rows=2, vgap=0)
       
  1354 
       
  1355         self._init_coll_flexGridSizer1_Items(self.flexGridSizer1)
       
  1356 
       
  1357         self.SetSizer(self.flexGridSizer1)
       
  1358 
       
  1359     def _init_ctrls(self, prnt):
       
  1360         # generated method, don't edit
       
  1361         wx.Dialog.__init__(self, id=wxID_POUDIALOG,
       
  1362               name='ProjectDialog', parent=prnt, pos=wx.Point(376, 223),
       
  1363               size=wx.Size(300, 200), style=wx.DEFAULT_DIALOG_STYLE,
       
  1364               title='Create a new project')
       
  1365         self.SetClientSize(wx.Size(300, 200))
       
  1366 
       
  1367         self.MainPanel = wx.Panel(id=wxID_POUDIALOGMAINPANEL,
       
  1368               name='MainPanel', parent=self, pos=wx.Point(0, 0),
       
  1369               size=wx.Size(300, 200), style=wx.TAB_TRAVERSAL)
       
  1370         self.MainPanel.SetAutoLayout(True)
       
  1371 
       
  1372         self.staticText1 = wx.StaticText(id=wxID_POUDIALOGSTATICTEXT1,
       
  1373               label='POU Name:', name='staticText1', parent=self.MainPanel,
       
  1374               pos=wx.Point(24, 24), size=wx.Size(95, 17), style=0)
       
  1375 
       
  1376         self.PouName = wx.TextCtrl(id=wxID_POUDIALOGPOUNAME,
       
  1377               name='POUName', parent=self.MainPanel, pos=wx.Point(104, 24), 
       
  1378               size=wx.Size(150, 24), style=0)
       
  1379 
       
  1380         self.staticText2 = wx.StaticText(id=wxID_POUDIALOGSTATICTEXT2,
       
  1381               label='POU Type:', name='staticText2', parent=self.MainPanel,
       
  1382               pos=wx.Point(24, 64), size=wx.Size(95, 17), style=0)
       
  1383 
       
  1384         self.PouType = wx.Choice(id=wxID_POUDIALOGPOUTYPE,
       
  1385               name='POUType', parent=self.MainPanel, pos=wx.Point(104, 64),
       
  1386               size=wx.Size(150, 24), style=0)
       
  1387         EVT_CHOICE(self, wxID_POUDIALOGPOUTYPE, self.OnTypeChanged)
       
  1388 
       
  1389         self.staticText3 = wx.StaticText(id=wxID_POUDIALOGSTATICTEXT3,
       
  1390               label='Language:', name='staticText3', parent=self.MainPanel,
       
  1391               pos=wx.Point(24, 104), size=wx.Size(95, 17), style=0)
       
  1392 
       
  1393         self.Language = wx.Choice(id=wxID_POUDIALOGLANGUAGE,
       
  1394               name='Language', parent=self.MainPanel, pos=wx.Point(104, 104),
       
  1395               size=wx.Size(150, 24), style=0)
       
  1396 
       
  1397         self._init_sizers()
       
  1398 
       
  1399     def __init__(self, parent):
       
  1400         self._init_ctrls(parent)
       
  1401         self.ButtonSizer = self.CreateButtonSizer(wxOK|wxCANCEL)
       
  1402         self.flexGridSizer1.Add(self.ButtonSizer, 1, wxALIGN_RIGHT)
       
  1403         
       
  1404         for option in ["function","functionBlock","program"]:
       
  1405             self.PouType.Append(option)
       
  1406         self.RefreshLanguage()
       
  1407 
       
  1408         EVT_BUTTON(self, self.ButtonSizer.GetAffirmativeButton().GetId(), self.OnOK)
       
  1409     
       
  1410     def OnOK(self, event):
       
  1411         error = []
       
  1412         pou_name = self.PouName.GetValue()
       
  1413         if pou_name == "":
       
  1414             error.append("POU Name")
       
  1415         if self.PouType.GetStringSelection() == "":
       
  1416             error.append("POU Type")
       
  1417         if self.Language.GetStringSelection() == "":
       
  1418             error.append("Language")
       
  1419         if len(error) > 0:
       
  1420             text = ""
       
  1421             for i, item in enumerate(error):
       
  1422                 if i == 0:
       
  1423                     text += item
       
  1424                 elif i == len(error) - 1:
       
  1425                     text += " and %s"%item
       
  1426                 else:
       
  1427                     text += ", %s"%item 
       
  1428             message = wxMessageDialog(self, "Form isn't complete. %s must be filled!"%text, "Error", wxOK|wxICON_ERROR)
       
  1429             message.ShowModal()
       
  1430             message.Destroy()
       
  1431         elif not TestIdentifier(pou_name):
       
  1432             message = wxMessageDialog(self, "\"%s\" is not a valid identifier!"%pou_name, "Error", wxOK|wxICON_ERROR)
       
  1433             message.ShowModal()
       
  1434             message.Destroy()
       
  1435         elif pou_name.upper() in IEC_KEYWORDS:
       
  1436             message = wxMessageDialog(self, "\"%s\" is a keyword. It can't be used!"%pou_name, "Error", wxOK|wxICON_ERROR)
       
  1437             message.ShowModal()
       
  1438             message.Destroy()
       
  1439         elif pou_name.upper() in self.PouNames:
       
  1440             message = wxMessageDialog(self, "\"%s\" pou already exists!"%pou_name, "Error", wxOK|wxICON_ERROR)
       
  1441             message.ShowModal()
       
  1442             message.Destroy()
       
  1443         else:
       
  1444             self.EndModal(wxID_OK)
       
  1445 
       
  1446     def RefreshLanguage(self):
       
  1447         selection = self.Language.GetStringSelection()
       
  1448         self.Language.Clear()
       
  1449         for option in ["IL","ST","LD","FBD","SFC"]:
       
  1450             if option != "SFC" or self.PouType.GetStringSelection() == "program":
       
  1451                 self.Language.Append(option)
       
  1452         if self.Language.FindString(selection) != wxNOT_FOUND:
       
  1453             self.Language.SetStringSelection(selection)
       
  1454 
       
  1455     def OnTypeChanged(self, event):
       
  1456         self.RefreshLanguage()
       
  1457         event.Skip()
       
  1458 
       
  1459     def SetPouNames(self, pou_names):
       
  1460         self.PouNames = [pou_name.upper() for pou_name in pou_names]
       
  1461 
       
  1462     def SetValues(self, values):
       
  1463         for item, value in values.items():
       
  1464             if item == "pouName":
       
  1465                 self.PouName.SetValue(value)
       
  1466             elif item == "pouType":
       
  1467                 self.PouType.SetStringSelection(value)
       
  1468             elif item == "language":
       
  1469                 self.Language.SetStringSelection(value)
       
  1470                 
       
  1471     def GetValues(self):
       
  1472         values = {}
       
  1473         values["pouName"] = self.PouName.GetValue()
       
  1474         values["pouType"] = self.PouType.GetStringSelection()
       
  1475         values["language"] = self.Language.GetStringSelection()
       
  1476         return values
       
  1477 
       
  1478 
       
  1479 #-------------------------------------------------------------------------------
       
  1480 #                          Create Pou Transition Dialog
       
  1481 #-------------------------------------------------------------------------------
       
  1482 
       
  1483 [wxID_POUTRANSITIONDIALOG, wxID_POUTRANSITIONDIALOGMAINPANEL, 
       
  1484  wxID_POUTRANSITIONDIALOGPOUNAME, wxID_POUTRANSITIONDIALOGTRANSITIONNAME, 
       
  1485  wxID_POUTRANSITIONDIALOGLANGUAGE, wxID_POUTRANSITIONDIALOGSTATICTEXT1,
       
  1486  wxID_POUTRANSITIONDIALOGSTATICTEXT2, wxID_POUTRANSITIONDIALOGSTATICTEXT3, 
       
  1487 ] = [wx.NewId() for _init_ctrls in range(8)]
       
  1488 
       
  1489 class PouTransitionDialog(wx.Dialog):
       
  1490     def _init_coll_flexGridSizer1_Items(self, parent):
       
  1491         # generated method, don't edit
       
  1492 
       
  1493         parent.AddWindow(self.MainPanel, 0, border=0, flag=0)
       
  1494 
       
  1495     def _init_sizers(self):
       
  1496         # generated method, don't edit
       
  1497         self.flexGridSizer1 = wx.FlexGridSizer(cols=1, hgap=0, rows=2, vgap=0)
       
  1498 
       
  1499         self._init_coll_flexGridSizer1_Items(self.flexGridSizer1)
       
  1500 
       
  1501         self.SetSizer(self.flexGridSizer1)
       
  1502 
       
  1503     def _init_ctrls(self, prnt):
       
  1504         # generated method, don't edit
       
  1505         wx.Dialog.__init__(self, id=wxID_POUTRANSITIONDIALOG,
       
  1506               name='ProjectDialog', parent=prnt, pos=wx.Point(376, 223),
       
  1507               size=wx.Size(350, 200), style=wx.DEFAULT_DIALOG_STYLE,
       
  1508               title='Create a new project')
       
  1509         self.SetClientSize(wx.Size(350, 200))
       
  1510 
       
  1511         self.MainPanel = wx.Panel(id=wxID_POUTRANSITIONDIALOGMAINPANEL,
       
  1512               name='MainPanel', parent=self, pos=wx.Point(0, 0),
       
  1513               size=wx.Size(350, 200), style=wx.TAB_TRAVERSAL)
       
  1514         self.MainPanel.SetAutoLayout(True)
       
  1515 
       
  1516         self.staticText1 = wx.StaticText(id=wxID_POUTRANSITIONDIALOGSTATICTEXT1,
       
  1517               label='POU Name:', name='staticText1', parent=self.MainPanel,
       
  1518               pos=wx.Point(24, 24), size=wx.Size(145, 17), style=0)
       
  1519 
       
  1520         self.PouName = wx.Choice(id=wxID_POUTRANSITIONDIALOGPOUNAME,
       
  1521               name='POUName', parent=self.MainPanel, pos=wx.Point(154, 24), 
       
  1522               size=wx.Size(150, 24), style=0)
       
  1523 
       
  1524         self.staticText2 = wx.StaticText(id=wxID_POUTRANSITIONDIALOGSTATICTEXT2,
       
  1525               label='Transition Name:', name='staticText2', parent=self.MainPanel,
       
  1526               pos=wx.Point(24, 64), size=wx.Size(145, 17), style=0)
       
  1527 
       
  1528         self.TransitionName = wx.TextCtrl(id=wxID_POUTRANSITIONDIALOGTRANSITIONNAME,
       
  1529               name='TransitionName', parent=self.MainPanel, pos=wx.Point(154, 64),
       
  1530               size=wx.Size(150, 24), style=0)
       
  1531 
       
  1532         self.staticText3 = wx.StaticText(id=wxID_POUTRANSITIONDIALOGSTATICTEXT3,
       
  1533               label='Language:', name='staticText3', parent=self.MainPanel,
       
  1534               pos=wx.Point(24, 104), size=wx.Size(145, 17), style=0)
       
  1535 
       
  1536         self.Language = wx.Choice(id=wxID_POUTRANSITIONDIALOGLANGUAGE,
       
  1537               name='Language', parent=self.MainPanel, pos=wx.Point(154, 104),
       
  1538               size=wx.Size(150, 24), style=0)
       
  1539 
       
  1540         self._init_sizers()
       
  1541 
       
  1542     def __init__(self, parent):
       
  1543         self._init_ctrls(parent)
       
  1544         self.ButtonSizer = self.CreateButtonSizer(wxOK|wxCANCEL)
       
  1545         self.flexGridSizer1.Add(self.ButtonSizer, 1, wxALIGN_RIGHT)
       
  1546 
       
  1547         for option in ["IL","ST","LD","FBD"]:
       
  1548             self.Language.Append(option)
       
  1549         
       
  1550         EVT_BUTTON(self, self.ButtonSizer.GetAffirmativeButton().GetId(), self.OnOK)
       
  1551     
       
  1552     def OnOK(self, event):
       
  1553         error = []
       
  1554         if self.PouName.GetStringSelection() == "":
       
  1555             error.append("POU Name")
       
  1556         if self.TransitionName.GetValue() == "":
       
  1557             error.append("Transition Name")
       
  1558         if self.Language.GetStringSelection() == "":
       
  1559             error.append("Language")
       
  1560         if len(error) > 0:
       
  1561             text = ""
       
  1562             for i, item in enumerate(error):
       
  1563                 if i == 0:
       
  1564                     text += item
       
  1565                 elif i == len(error) - 1:
       
  1566                     text += " and %s"%item
       
  1567                 else:
       
  1568                     text += ", %s"%item 
       
  1569             message = wxMessageDialog(self, "Form isn't complete. %s must be filled!"%text, "Error", wxOK|wxICON_ERROR)
       
  1570             message.ShowModal()
       
  1571             message.Destroy()
       
  1572         else:
       
  1573             self.EndModal(wxID_OK)
       
  1574 
       
  1575     def SetPous(self, pous):
       
  1576         for pou in pous:
       
  1577             self.PouName.Append(pou)
       
  1578 
       
  1579     def SetValues(self, values):
       
  1580         for item, value in values.items():
       
  1581             if item == "pouName":
       
  1582                 self.PouName.SetStringSelection(value)
       
  1583             elif item == "transitionName":
       
  1584                 self.TransitionName.SetValue(value)
       
  1585             elif item == "language":
       
  1586                 self.Language.SetStringSelection(value)
       
  1587                 
       
  1588     def GetValues(self):
       
  1589         values = {}
       
  1590         values["pouName"] = self.PouName.GetStringSelection()
       
  1591         values["transitionName"] = self.TransitionName.GetValue()
       
  1592         values["language"] = self.Language.GetStringSelection()
       
  1593         return values
       
  1594 
       
  1595 #-------------------------------------------------------------------------------
       
  1596 #                          Create Pou Action Dialog
       
  1597 #-------------------------------------------------------------------------------
       
  1598 
       
  1599 [wxID_POUACTIONDIALOG, wxID_POUACTIONDIALOGMAINPANEL, 
       
  1600  wxID_POUACTIONDIALOGPOUNAME, wxID_POUACTIONDIALOGACTIONNAME, 
       
  1601  wxID_POUACTIONDIALOGLANGUAGE, wxID_POUACTIONDIALOGSTATICTEXT1,
       
  1602  wxID_POUACTIONDIALOGSTATICTEXT2, wxID_POUACTIONDIALOGSTATICTEXT3, 
       
  1603 ] = [wx.NewId() for _init_ctrls in range(8)]
       
  1604 
       
  1605 class PouActionDialog(wx.Dialog):
       
  1606     def _init_coll_flexGridSizer1_Items(self, parent):
       
  1607         # generated method, don't edit
       
  1608 
       
  1609         parent.AddWindow(self.MainPanel, 0, border=0, flag=0)
       
  1610 
       
  1611     def _init_sizers(self):
       
  1612         # generated method, don't edit
       
  1613         self.flexGridSizer1 = wx.FlexGridSizer(cols=1, hgap=0, rows=2, vgap=0)
       
  1614 
       
  1615         self._init_coll_flexGridSizer1_Items(self.flexGridSizer1)
       
  1616 
       
  1617         self.SetSizer(self.flexGridSizer1)
       
  1618 
       
  1619     def _init_ctrls(self, prnt):
       
  1620         # generated method, don't edit
       
  1621         wx.Dialog.__init__(self, id=wxID_POUACTIONDIALOG,
       
  1622               name='ProjectDialog', parent=prnt, pos=wx.Point(376, 223),
       
  1623               size=wx.Size(320, 200), style=wx.DEFAULT_DIALOG_STYLE,
       
  1624               title='Create a new project')
       
  1625         self.SetClientSize(wx.Size(320, 200))
       
  1626 
       
  1627         self.MainPanel = wx.Panel(id=wxID_POUACTIONDIALOGMAINPANEL,
       
  1628               name='MainPanel', parent=self, pos=wx.Point(0, 0),
       
  1629               size=wx.Size(350, 200), style=wx.TAB_TRAVERSAL)
       
  1630         self.MainPanel.SetAutoLayout(True)
       
  1631 
       
  1632         self.staticText1 = wx.StaticText(id=wxID_POUACTIONDIALOGSTATICTEXT1,
       
  1633               label='POU Name:', name='staticText1', parent=self.MainPanel,
       
  1634               pos=wx.Point(24, 24), size=wx.Size(145, 17), style=0)
       
  1635 
       
  1636         self.PouName = wx.Choice(id=wxID_POUACTIONDIALOGPOUNAME,
       
  1637               name='POUName', parent=self.MainPanel, pos=wx.Point(124, 24), 
       
  1638               size=wx.Size(150, 24), style=0)
       
  1639 
       
  1640         self.staticText2 = wx.StaticText(id=wxID_POUACTIONDIALOGSTATICTEXT2,
       
  1641               label='Action Name:', name='staticText2', parent=self.MainPanel,
       
  1642               pos=wx.Point(24, 64), size=wx.Size(145, 17), style=0)
       
  1643 
       
  1644         self.ActionName = wx.TextCtrl(id=wxID_POUACTIONDIALOGACTIONNAME,
       
  1645               name='ActionName', parent=self.MainPanel, pos=wx.Point(124, 64),
       
  1646               size=wx.Size(150, 24), style=0)
       
  1647 
       
  1648         self.staticText3 = wx.StaticText(id=wxID_POUACTIONDIALOGSTATICTEXT3,
       
  1649               label='Language:', name='staticText3', parent=self.MainPanel,
       
  1650               pos=wx.Point(24, 104), size=wx.Size(145, 17), style=0)
       
  1651 
       
  1652         self.Language = wx.Choice(id=wxID_POUACTIONDIALOGLANGUAGE,
       
  1653               name='Language', parent=self.MainPanel, pos=wx.Point(124, 104),
       
  1654               size=wx.Size(150, 24), style=0)
       
  1655 
       
  1656         self._init_sizers()
       
  1657 
       
  1658     def __init__(self, parent):
       
  1659         self._init_ctrls(parent)
       
  1660         self.ButtonSizer = self.CreateButtonSizer(wxOK|wxCANCEL)
       
  1661         self.flexGridSizer1.Add(self.ButtonSizer, 1, wxALIGN_RIGHT)
       
  1662 
       
  1663         for option in ["IL","ST","LD","FBD"]:
       
  1664             self.Language.Append(option)
       
  1665         
       
  1666         EVT_BUTTON(self, self.ButtonSizer.GetAffirmativeButton().GetId(), self.OnOK)
       
  1667     
       
  1668     def OnOK(self, event):
       
  1669         error = []
       
  1670         if self.PouName.GetStringSelection() == "":
       
  1671             error.append("POU Name")
       
  1672         if self.ActionName.GetValue() == "":
       
  1673             error.append("Action Name")
       
  1674         if self.Language.GetStringSelection() == "":
       
  1675             error.append("Language")
       
  1676         if len(error) > 0:
       
  1677             text = ""
       
  1678             for i, item in enumerate(error):
       
  1679                 if i == 0:
       
  1680                     text += item
       
  1681                 elif i == len(error) - 1:
       
  1682                     text += " and %s"%item
       
  1683                 else:
       
  1684                     text += ", %s"%item 
       
  1685             message = wxMessageDialog(self, "Form isn't complete. %s must be filled!"%text, "Error", wxOK|wxICON_ERROR)
       
  1686             message.ShowModal()
       
  1687             message.Destroy()
       
  1688         else:
       
  1689             self.EndModal(wxID_OK)
       
  1690 
       
  1691     def SetPous(self, pous):
       
  1692         for pou in pous:
       
  1693             self.PouName.Append(pou)
       
  1694 
       
  1695     def SetValues(self, values):
       
  1696         for item, value in values.items():
       
  1697             if item == "pouName":
       
  1698                 self.PouName.SetStringSelection(value)
       
  1699             elif item == "actionName":
       
  1700                 self.ActionName.SetValue(value)
       
  1701             elif item == "language":
       
  1702                 self.Language.SetStringSelection(value)
       
  1703                 
       
  1704     def GetValues(self):
       
  1705         values = {}
       
  1706         values["pouName"] = self.PouName.GetStringSelection()
       
  1707         values["actionName"] = self.ActionName.GetValue()
       
  1708         values["language"] = self.Language.GetStringSelection()
       
  1709         return values
       
  1710 
       
  1711 #-------------------------------------------------------------------------------
       
  1712 #                            Pou Interface Dialog
       
  1713 #-------------------------------------------------------------------------------
       
  1714 
       
  1715 class VariableTable(wxPyGridTableBase):
       
  1716     
       
  1717     """
       
  1718     A custom wxGrid Table using user supplied data
       
  1719     """
       
  1720     def __init__(self, parent, data, colnames):
       
  1721         # The base class must be initialized *first*
       
  1722         wxPyGridTableBase.__init__(self)
       
  1723         self.data = data
       
  1724         self.colnames = colnames
       
  1725         self.Parent = parent
       
  1726         # XXX
       
  1727         # we need to store the row length and collength to
       
  1728         # see if the table has changed size
       
  1729         self._rows = self.GetNumberRows()
       
  1730         self._cols = self.GetNumberCols()
       
  1731     
       
  1732     def GetNumberCols(self):
       
  1733         return len(self.colnames)
       
  1734         
       
  1735     def GetNumberRows(self):
       
  1736         return len(self.data)
       
  1737 
       
  1738     def GetColLabelValue(self, col):
       
  1739         if col < len(self.colnames):
       
  1740             return self.colnames[col]
       
  1741 
       
  1742     def GetRowLabelValues(self, row):
       
  1743         return row
       
  1744 
       
  1745     def GetValue(self, row, col):
       
  1746         if row < self.GetNumberRows():
       
  1747             name = str(self.data[row].get(self.GetColLabelValue(col), ""))
       
  1748             return name
       
  1749     
       
  1750     def GetValueByName(self, row, colname):
       
  1751         return self.data[row].get(colname)
       
  1752 
       
  1753     def SetValue(self, row, col, value):
       
  1754         if col < len(self.colnames):
       
  1755             self.data[row][self.GetColLabelValue(col)] = value
       
  1756         
       
  1757     def ResetView(self, grid):
       
  1758         """
       
  1759         (wxGrid) -> Reset the grid view.   Call this to
       
  1760         update the grid if rows and columns have been added or deleted
       
  1761         """
       
  1762         grid.BeginBatch()
       
  1763         for current, new, delmsg, addmsg in [
       
  1764             (self._rows, self.GetNumberRows(), wxGRIDTABLE_NOTIFY_ROWS_DELETED, wxGRIDTABLE_NOTIFY_ROWS_APPENDED),
       
  1765             (self._cols, self.GetNumberCols(), wxGRIDTABLE_NOTIFY_COLS_DELETED, wxGRIDTABLE_NOTIFY_COLS_APPENDED),
       
  1766         ]:
       
  1767             if new < current:
       
  1768                 msg = wxGridTableMessage(self,delmsg,new,current-new)
       
  1769                 grid.ProcessTableMessage(msg)
       
  1770             elif new > current:
       
  1771                 msg = wxGridTableMessage(self,addmsg,new-current)
       
  1772                 grid.ProcessTableMessage(msg)
       
  1773                 self.UpdateValues(grid)
       
  1774         grid.EndBatch()
       
  1775 
       
  1776         self._rows = self.GetNumberRows()
       
  1777         self._cols = self.GetNumberCols()
       
  1778         # update the column rendering scheme
       
  1779         self._updateColAttrs(grid)
       
  1780 
       
  1781         # update the scrollbars and the displayed part of the grid
       
  1782         grid.AdjustScrollbars()
       
  1783         grid.ForceRefresh()
       
  1784 
       
  1785     def UpdateValues(self, grid):
       
  1786         """Update all displayed values"""
       
  1787         # This sends an event to the grid table to update all of the values
       
  1788         msg = wxGridTableMessage(self, wxGRIDTABLE_REQUEST_VIEW_GET_VALUES)
       
  1789         grid.ProcessTableMessage(msg)
       
  1790 
       
  1791     def _updateColAttrs(self, grid):
       
  1792         """
       
  1793         wxGrid -> update the column attributes to add the
       
  1794         appropriate renderer given the column name.
       
  1795 
       
  1796         Otherwise default to the default renderer.
       
  1797         """
       
  1798         
       
  1799         for col in range(self.GetNumberCols()):
       
  1800             attr = wxGridCellAttr()
       
  1801             attr.SetAlignment(self.Parent.ColAlignements[col], wxALIGN_CENTRE)
       
  1802             grid.SetColAttr(col, attr)
       
  1803             grid.SetColSize(col, self.Parent.ColSizes[col])
       
  1804         
       
  1805         typelist = None
       
  1806         accesslist = None
       
  1807         for row in range(self.GetNumberRows()):
       
  1808             for col in range(self.GetNumberCols()):
       
  1809                 editor = None
       
  1810                 renderer = None
       
  1811                 colname = self.GetColLabelValue(col)
       
  1812                 grid.SetReadOnly(row, col, False)
       
  1813                 if colname in ["Name","Initial Value","Location"]:
       
  1814                     editor = wxGridCellTextEditor()
       
  1815                     renderer = wxGridCellStringRenderer()    
       
  1816                 elif colname == "Class":
       
  1817                     if len(self.Parent.ClassList) == 1:
       
  1818                         grid.SetReadOnly(row, col, True)
       
  1819                     else:
       
  1820                         editor = wxGridCellChoiceEditor()    
       
  1821                         editor.SetParameters(",".join(self.Parent.ClassList))
       
  1822                 elif colname == "Type":
       
  1823                     editor = wxGridCellChoiceEditor()
       
  1824                     editor.SetParameters(self.Parent.TypeList)
       
  1825                 elif colname in ["Retain", "Constant"]:
       
  1826                     editor = wxGridCellChoiceEditor()
       
  1827                     editor.SetParameters(self.Parent.OptionList)
       
  1828                     
       
  1829                 grid.SetCellEditor(row, col, editor)
       
  1830                 grid.SetCellRenderer(row, col, renderer)
       
  1831                 
       
  1832                 grid.SetCellBackgroundColour(row, col, wxWHITE)
       
  1833     
       
  1834     def SetData(self, data):
       
  1835         self.data = data
       
  1836     
       
  1837     def GetData(self):
       
  1838         return self.data
       
  1839     
       
  1840     def GetCurrentIndex(self):
       
  1841         return self.CurrentIndex
       
  1842     
       
  1843     def SetCurrentIndex(self, index):
       
  1844         self.CurrentIndex = index
       
  1845     
       
  1846     def AppendRow(self, row_content):
       
  1847         self.data.append(row_content)
       
  1848 
       
  1849     def RemoveRow(self, row_index):
       
  1850         self.data.pop(row_index)
       
  1851         
       
  1852     def MoveRow(self, row_index, move, grid):
       
  1853         new_index = max(0, min(row_index + move, len(self.data) - 1))
       
  1854         if new_index != row_index:
       
  1855             self.data.insert(new_index, self.data.pop(row_index))
       
  1856             grid.SetGridCursor(new_index, grid.GetGridCursorCol())
       
  1857 
       
  1858     def Empty(self):
       
  1859         self.data = []
       
  1860         self.editors = []
       
  1861 
       
  1862 [wxID_EDITVARIABLEDIALOG, wxID_EDITVARIABLEDIALOGMAINPANEL, 
       
  1863  wxID_EDITVARIABLEDIALOGVARIABLESGRID, wxID_EDITVARIABLEDIALOGRETURNTYPE, 
       
  1864  wxID_EDITVARIABLEDIALOGCLASSFILTER, wxID_EDITVARIABLEDIALOGADDBUTTON,
       
  1865  wxID_EDITVARIABLEDIALOGDELETEBUTTON, wxID_EDITVARIABLEDIALOGUPBUTTON, 
       
  1866  wxID_EDITVARIABLEDIALOGDOWNBUTTON, wxID_EDITVARIABLEDIALOGSTATICTEXT1, 
       
  1867  wxID_EDITVARIABLEDIALOGSTATICTEXT2, wxID_EDITVARIABLEDIALOGSTATICTEXT3,
       
  1868 ] = [wx.NewId() for _init_ctrls in range(12)]
       
  1869 
       
  1870 class EditVariableDialog(wx.Dialog):
       
  1871     def _init_coll_flexGridSizer1_Items(self, parent):
       
  1872         # generated method, don't edit
       
  1873 
       
  1874         parent.AddWindow(self.MainPanel, 0, border=0, flag=0)
       
  1875 
       
  1876     def _init_sizers(self):
       
  1877         # generated method, don't edit
       
  1878         self.flexGridSizer1 = wx.FlexGridSizer(cols=1, hgap=0, rows=2, vgap=0)
       
  1879 
       
  1880         self._init_coll_flexGridSizer1_Items(self.flexGridSizer1)
       
  1881 
       
  1882         self.SetSizer(self.flexGridSizer1)
       
  1883 
       
  1884     def _init_ctrls(self, prnt, name):
       
  1885         # generated method, don't edit
       
  1886         wx.Dialog.__init__(self, id=wxID_EDITVARIABLEDIALOG,
       
  1887               name='EditVariableDialog', parent=prnt, pos=wx.Point(376, 223),
       
  1888               size=wx.Size(600, 440), style=wx.DEFAULT_DIALOG_STYLE,
       
  1889               title='Edit variables of %s'%name)
       
  1890         self.SetClientSize(wx.Size(600, 440))
       
  1891 
       
  1892         self.MainPanel = wx.Panel(id=wxID_EDITVARIABLEDIALOGMAINPANEL,
       
  1893               name='MainPanel', parent=self, pos=wx.Point(0, 0),
       
  1894               size=wx.Size(600, 440), style=wx.TAB_TRAVERSAL)
       
  1895         self.MainPanel.SetAutoLayout(True)
       
  1896 
       
  1897         self.staticText1 = wx.StaticText(id=wxID_EDITVARIABLEDIALOGSTATICTEXT1,
       
  1898               label='Return Type:', name='staticText1', parent=self.MainPanel,
       
  1899               pos=wx.Point(24, 29), size=wx.Size(95, 17), style=0)
       
  1900 
       
  1901         self.ReturnType = wx.Choice(id=wxID_EDITVARIABLEDIALOGRETURNTYPE,
       
  1902               name='ReturnType', parent=self.MainPanel, pos=wx.Point(124, 24),
       
  1903               size=wx.Size(145, 24), style=0)
       
  1904 
       
  1905         self.staticText2 = wx.StaticText(id=wxID_EDITVARIABLEDIALOGSTATICTEXT2,
       
  1906               label='Class Filter:', name='staticText2', parent=self.MainPanel,
       
  1907               pos=wx.Point(324, 29), size=wx.Size(95, 17), style=0)
       
  1908 
       
  1909         self.ClassFilter = wx.Choice(id=wxID_EDITVARIABLEDIALOGCLASSFILTER,
       
  1910               name='ClassFilter', parent=self.MainPanel, pos=wx.Point(424, 24),
       
  1911               size=wx.Size(145, 24), style=0)
       
  1912         EVT_CHOICE(self, wxID_EDITVARIABLEDIALOGCLASSFILTER, self.OnClassFilter)
       
  1913 
       
  1914         self.staticText3 = wx.StaticText(id=wxID_EDITVARIABLEDIALOGSTATICTEXT3,
       
  1915               label='Variables:', name='staticText3', parent=self.MainPanel,
       
  1916               pos=wx.Point(24, 60), size=wx.Size(95, 17), style=0)
       
  1917 
       
  1918         self.VariablesGrid = wx.grid.Grid(id=wxID_EDITVARIABLEDIALOGVARIABLESGRID,
       
  1919               name='VariablesGrid', parent=self.MainPanel, pos=wx.Point(24, 80), 
       
  1920               size=wx.Size(550, 250), style=wxVSCROLL)
       
  1921         self.VariablesGrid.SetFont(wx.Font(12, 77, wx.NORMAL, wx.NORMAL, False,
       
  1922               'Sans'))
       
  1923         self.VariablesGrid.SetLabelFont(wx.Font(10, 77, wx.NORMAL, wx.NORMAL,
       
  1924               False, 'Sans'))
       
  1925         self.VariablesGrid.DisableDragGridSize()
       
  1926         self.VariablesGrid.EnableScrolling(False, True)
       
  1927 
       
  1928         self.AddButton = wx.Button(id=wxID_EDITVARIABLEDIALOGADDBUTTON, label='Add',
       
  1929               name='AddButton', parent=self.MainPanel, pos=wx.Point(345, 340),
       
  1930               size=wx.Size(72, 32), style=0)
       
  1931         EVT_BUTTON(self, wxID_EDITVARIABLEDIALOGADDBUTTON, self.OnAddButton)
       
  1932 
       
  1933         self.DeleteButton = wx.Button(id=wxID_EDITVARIABLEDIALOGDELETEBUTTON, label='Delete',
       
  1934               name='DeleteButton', parent=self.MainPanel, pos=wx.Point(425, 340),
       
  1935               size=wx.Size(72, 32), style=0)
       
  1936         EVT_BUTTON(self, wxID_EDITVARIABLEDIALOGDELETEBUTTON, self.OnDeleteButton)
       
  1937 
       
  1938         self.UpButton = wx.Button(id=wxID_EDITVARIABLEDIALOGUPBUTTON, label='^',
       
  1939               name='UpButton', parent=self.MainPanel, pos=wx.Point(505, 340),
       
  1940               size=wx.Size(32, 32), style=0)
       
  1941         EVT_BUTTON(self, wxID_EDITVARIABLEDIALOGUPBUTTON, self.OnUpButton)
       
  1942 
       
  1943         self.DownButton = wx.Button(id=wxID_EDITVARIABLEDIALOGDOWNBUTTON, label='v',
       
  1944               name='DownButton', parent=self.MainPanel, pos=wx.Point(545, 340),
       
  1945               size=wx.Size(32, 32), style=0)
       
  1946         EVT_BUTTON(self, wxID_EDITVARIABLEDIALOGDOWNBUTTON, self.OnDownButton)
       
  1947 
       
  1948         self._init_sizers()
       
  1949 
       
  1950     def __init__(self, parent, name, pou_type, filter = "All"):
       
  1951         self._init_ctrls(parent, name)
       
  1952         self.ButtonSizer = self.CreateButtonSizer(wxOK|wxCANCEL)
       
  1953         self.flexGridSizer1.Add(self.ButtonSizer, 1, wxALIGN_RIGHT)
       
  1954         self.Filter = filter
       
  1955         self.FilterChoices = []
       
  1956         self.FilterChoiceTransfer = {"All" : "All", "Interface" : "Interface", 
       
  1957             "Input" : "   Input", "Output" : "   Output", "InOut" : "   InOut", 
       
  1958             "External" : "   External", "Variables" : "Variables", "Local" : "   Local",
       
  1959             "Temp" : "   Temp", "Global" : "Global", "Access" : "Access"}
       
  1960         
       
  1961         if pou_type:
       
  1962             self.DefaultValue = {"Name" : "", "Class" : "Input", "Type" : "INT", "Location" : "", "Initial Value" : "", "Retain" : "No", "Constant" : "No"}
       
  1963         else:
       
  1964             self.DefaultValue = {"Name" : "", "Class" : "Global", "Type" : "INT", "Location" : "", "Initial Value" : "", "Retain" : "No", "Constant" : "No"}
       
  1965         if not pou_type or pou_type == "program":
       
  1966             self.Table = VariableTable(self, [], ["Name", "Class", "Type", "Location", "Initial Value", "Retain", "Constant"])
       
  1967             if pou_type:
       
  1968                 self.FilterChoices = ["All","Interface","   Input","   Output","   InOut","   External","Variables","   Local","   Temp","Global","Access"]
       
  1969             else:
       
  1970                 self.FilterChoices = ["All","Global","Access"]
       
  1971             self.ColSizes = [80, 70, 80, 80, 80, 60, 70]
       
  1972             self.ColAlignements = [wxALIGN_LEFT, wxALIGN_LEFT, wxALIGN_LEFT, wxALIGN_LEFT, wxALIGN_LEFT, wxALIGN_CENTER, wxALIGN_CENTER]
       
  1973         else:
       
  1974             self.Table = VariableTable(self, [], ["Name", "Class", "Type", "Initial Value", "Retain", "Constant"])
       
  1975             self.FilterChoices = ["All","Interface","   Input","   Output","   InOut","   External","Variables","   Local","   Temp"]
       
  1976             self.ColSizes = [120, 70, 80, 120, 60, 70]
       
  1977             self.ColAlignements = [wxALIGN_LEFT, wxALIGN_LEFT, wxALIGN_LEFT, wxALIGN_LEFT, wxALIGN_CENTER, wxALIGN_CENTER]
       
  1978         for choice in self.FilterChoices:
       
  1979             self.ClassFilter.Append(choice)
       
  1980         self.ClassFilter.SetStringSelection(self.FilterChoiceTransfer[self.Filter])
       
  1981         self.RefreshTypeList()
       
  1982         self.RefreshUpDownButtons()
       
  1983 
       
  1984         self.OptionList = "Yes,No"
       
  1985         self.TypeList = ""
       
  1986         for value in TypeHierarchy.keys():
       
  1987             if not value.startswith("ANY"):
       
  1988                 self.TypeList += "%s,"%value
       
  1989         self.TypeList = self.TypeList[:-1]
       
  1990         
       
  1991         if pou_type == "function":
       
  1992             for value in TypeHierarchy.keys():
       
  1993                 if not value.startswith("ANY"):
       
  1994                     self.ReturnType.Append(value)
       
  1995             self.ReturnType.Enable(True)
       
  1996         else:
       
  1997             self.ReturnType.Enable(False)
       
  1998             self.staticText2.Hide()
       
  1999             self.ReturnType.Hide()
       
  2000         
       
  2001         self.VariablesGrid.SetTable(self.Table)
       
  2002         self.VariablesGrid.SetRowLabelSize(0)
       
  2003         
       
  2004         self.Table.ResetView(self.VariablesGrid)
       
  2005 
       
  2006         EVT_BUTTON(self, self.ButtonSizer.GetAffirmativeButton().GetId(), self.OnOK)
       
  2007     
       
  2008     def OnOK(self, event):
       
  2009         self.VariablesGrid.SetGridCursor(0, 0)
       
  2010         error = []
       
  2011         if self.ReturnType.IsEnabled() and self.ReturnType.GetStringSelection() == "":
       
  2012             error.append("Return Type")
       
  2013         if len(error) > 0:
       
  2014             text = ""
       
  2015             for i, item in enumerate(error):
       
  2016                 if i == 0:
       
  2017                     text += item
       
  2018                 elif i == len(error) - 1:
       
  2019                     text += " and %s"%item
       
  2020                 else:
       
  2021                     text += ", %s"%item 
       
  2022             message = wxMessageDialog(self, "Form isn't complete. %s must be filled!"%text, "Error", wxOK|wxICON_ERROR)
       
  2023             message.ShowModal()
       
  2024             message.Destroy()
       
  2025         else:
       
  2026             self.EndModal(wxID_OK)
       
  2027 
       
  2028     def OnClassFilter(self, event):
       
  2029         reverse_transfer = {}
       
  2030         for filter, choice in self.FilterChoiceTransfer.items():
       
  2031             reverse_transfer[choice] = filter
       
  2032         self.Filter = reverse_transfer[self.ClassFilter.GetStringSelection()]
       
  2033         self.RefreshTypeList()
       
  2034         self.RefreshValues()
       
  2035         self.RefreshUpDownButtons()
       
  2036         event.Skip()
       
  2037 
       
  2038     def RefreshTypeList(self):
       
  2039         if self.Filter == "All":
       
  2040             self.ClassList = [choice for choice in self.FilterChoices if choice not in ["All","Interface","Variables"]]
       
  2041         elif self.Filter == "Interface":
       
  2042             self.ClassList = ["Input","Output","InOut","External"]
       
  2043         elif self.Filter == "Variables":
       
  2044             self.ClassList = ["Local","Temp"]
       
  2045         else:
       
  2046             self.ClassList = [self.Filter]
       
  2047 
       
  2048     def RefreshUpDownButtons(self):
       
  2049         if self.Filter == "All":
       
  2050             self.UpButton.Enable(True)
       
  2051             self.DownButton.Enable(True)
       
  2052         else:
       
  2053             self.UpButton.Enable(False)
       
  2054             self.DownButton.Enable(False)
       
  2055 
       
  2056     def OnAddButton(self, event):
       
  2057         self.Table.AppendRow(self.DefaultValue.copy())
       
  2058         self.Table.ResetView(self.VariablesGrid)
       
  2059         event.Skip()
       
  2060 
       
  2061     def OnDeleteButton(self, event):
       
  2062         row = self.VariablesGrid.GetGridCursorRow()
       
  2063         self.Table.RemoveRow(row)
       
  2064         self.Table.ResetView(self.VariablesGrid)
       
  2065         event.Skip()
       
  2066 
       
  2067     def OnUpButton(self, event):
       
  2068         row = self.VariablesGrid.GetGridCursorRow()
       
  2069         self.Table.MoveRow(row, -1, self.VariablesGrid)
       
  2070         self.Table.ResetView(self.VariablesGrid)
       
  2071         event.Skip()
       
  2072 
       
  2073     def OnDownButton(self, event):
       
  2074         row = self.VariablesGrid.GetGridCursorRow()
       
  2075         self.Table.MoveRow(row, 1, self.VariablesGrid)
       
  2076         self.Table.ResetView(self.VariablesGrid)
       
  2077         event.Skip()
       
  2078 
       
  2079     def SetValues(self, values):
       
  2080         for item, value in values.items():
       
  2081             if item == "returnType" and value and self.ReturnType.IsEnabled():
       
  2082                 self.ReturnType.SetStringSelection(value)
       
  2083             if item == "data":
       
  2084                 self.Values = value
       
  2085         self.RefreshValues()
       
  2086                 
       
  2087     def RefreshValues(self):
       
  2088         data = []
       
  2089         for variable in self.Values:
       
  2090             if variable["Class"] in self.ClassList:
       
  2091                 data.append(variable)
       
  2092         self.Table.SetData(data)
       
  2093         self.Table.ResetView(self.VariablesGrid)
       
  2094                 
       
  2095     def GetValues(self):
       
  2096         values = {}
       
  2097         if self.ReturnType.IsEnabled():
       
  2098             values["returnType"] = self.ReturnType.GetStringSelection()
       
  2099         values["data"] = self.Table.GetData()
       
  2100         return values
       
  2101 
       
  2102 #-------------------------------------------------------------------------------
       
  2103 #                               Exception Handler
       
  2104 #-------------------------------------------------------------------------------
       
  2105 
       
  2106 Max_Traceback_List_Size = 20
       
  2107 
       
  2108 def Display_Exception_Dialog(e_type,e_value,e_tb):
       
  2109     trcbck_lst = []
       
  2110     for i,line in enumerate(traceback.extract_tb(e_tb)):
       
  2111         trcbck = " " + str(i+1) + ". "
       
  2112         if line[0].find(os.getcwd()) == -1:
       
  2113             trcbck += "file : " + str(line[0]) + ",   "
       
  2114         else:
       
  2115             trcbck += "file : " + str(line[0][len(os.getcwd()):]) + ",   "
       
  2116         trcbck += "line : " + str(line[1]) + ",   " + "function : " + str(line[2])
       
  2117         trcbck_lst.append(trcbck)
       
  2118         
       
  2119     # Allow clicking....
       
  2120     cap = wx.Window_GetCapture()
       
  2121     if cap:
       
  2122         cap.ReleaseMouse()
       
  2123 
       
  2124     dlg = wx.SingleChoiceDialog(None, 
       
  2125         """
       
  2126 An error happens.
       
  2127 
       
  2128 Click on OK for saving an error report.
       
  2129 
       
  2130 Please contact LOLITech at:
       
  2131 +33 (0)3 29 52 95 67
       
  2132 bugs_PLCOpenEditor@lolitech.fr
       
  2133 
       
  2134 
       
  2135 Error:
       
  2136 """ +
       
  2137         str(e_type) + " : " + str(e_value), 
       
  2138         "Error",
       
  2139         trcbck_lst)
       
  2140     try:
       
  2141         res = (dlg.ShowModal() == wx.ID_OK)
       
  2142     finally:
       
  2143         dlg.Destroy()
       
  2144 
       
  2145     return res
       
  2146 
       
  2147 def Display_Error_Dialog(e_value):
       
  2148     message = wxMessageDialog(None, str(e_value), "Error", wxOK|wxICON_ERROR)
       
  2149     message.ShowModal()
       
  2150     message.Destroy()
       
  2151 
       
  2152 def get_last_traceback(tb):
       
  2153     while tb.tb_next:
       
  2154         tb = tb.tb_next
       
  2155     return tb
       
  2156 
       
  2157 
       
  2158 def format_namespace(d, indent='    '):
       
  2159     return '\n'.join(['%s%s: %s' % (indent, k, repr(v)[:10000]) for k, v in d.iteritems()])
       
  2160 
       
  2161 
       
  2162 ignored_exceptions = [] # a problem with a line in a module is only reported once per session
       
  2163 
       
  2164 def wxAddExceptHook(path, app_version='[No version]'):#, ignored_exceptions=[]):
       
  2165     
       
  2166     def handle_exception(e_type, e_value, e_traceback):
       
  2167         traceback.print_exception(e_type, e_value, e_traceback) # this is very helpful when there's an exception in the rest of this func
       
  2168         last_tb = get_last_traceback(e_traceback)
       
  2169         ex = (last_tb.tb_frame.f_code.co_filename, last_tb.tb_frame.f_lineno)
       
  2170         if str(e_value).startswith("!!!"):
       
  2171             Display_Error_Dialog(e_value)
       
  2172         elif ex not in ignored_exceptions:
       
  2173             result = Display_Exception_Dialog(e_type,e_value,e_traceback)
       
  2174             if result:
       
  2175                 ignored_exceptions.append(ex)
       
  2176                 info = {
       
  2177                     'app-title' : wx.GetApp().GetAppName(), # app_title
       
  2178                     'app-version' : app_version,
       
  2179                     'wx-version' : wx.VERSION_STRING,
       
  2180                     'wx-platform' : wx.Platform,
       
  2181                     'python-version' : platform.python_version(), #sys.version.split()[0],
       
  2182                     'platform' : platform.platform(),
       
  2183                     'e-type' : e_type,
       
  2184                     'e-value' : e_value,
       
  2185                     'date' : time.ctime(),
       
  2186                     'cwd' : os.getcwd(),
       
  2187                     }
       
  2188                 if e_traceback:
       
  2189                     info['traceback'] = ''.join(traceback.format_tb(e_traceback)) + '%s: %s' % (e_type, e_value)
       
  2190                     last_tb = get_last_traceback(e_traceback)
       
  2191                     exception_locals = last_tb.tb_frame.f_locals # the locals at the level of the stack trace where the exception actually occurred
       
  2192                     info['locals'] = format_namespace(exception_locals)
       
  2193                     if 'self' in exception_locals:
       
  2194                         info['self'] = format_namespace(exception_locals['self'].__dict__)
       
  2195                 
       
  2196                 output = open(path+os.sep+"bug_report_"+info['date'].replace(':','-').replace(' ','_')+".txt",'w')
       
  2197                 lst = info.keys()
       
  2198                 lst.sort()
       
  2199                 for a in lst:
       
  2200                     output.write(a+":\n"+str(info[a])+"\n\n")
       
  2201 
       
  2202     #sys.excepthook = lambda *args: wx.CallAfter(handle_exception, *args)
       
  2203     sys.excepthook = handle_exception
       
  2204 
       
  2205 if __name__ == '__main__':
       
  2206     app = wxPySimpleApp()
       
  2207     wxInitAllImageHandlers()
       
  2208     
       
  2209     # Install a exception handle for bug reports
       
  2210     wxAddExceptHook(os.getcwd(),__version__)
       
  2211     
       
  2212     frame = PLCOpenEditor(None)
       
  2213 
       
  2214     frame.Show()
       
  2215     app.MainLoop()
       
  2216