Dialogs.py
changeset 27 dae55dd9ee14
child 28 fc23e1f415d8
equal deleted inserted replaced
26:36d378bd852e 27:dae55dd9ee14
       
     1 #!/usr/bin/env python
       
     2 # -*- coding: utf-8 -*-
       
     3 
       
     4 #This file is part of PLCOpenEditor, a library implementing an IEC 61131-3 editor
       
     5 #based on the plcopen standard. 
       
     6 #
       
     7 #Copyright (C): Edouard TISSERANT and Laurent BESSARD
       
     8 #
       
     9 #See COPYING file for copyrights details.
       
    10 #
       
    11 #This library is free software; you can redistribute it and/or
       
    12 #modify it under the terms of the GNU General Public
       
    13 #License as published by the Free Software Foundation; either
       
    14 #version 2.1 of the License, or (at your option) any later version.
       
    15 #
       
    16 #This library is distributed in the hope that it will be useful,
       
    17 #but WITHOUT ANY WARRANTY; without even the implied warranty of
       
    18 #MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
       
    19 #Lesser General Public License for more details.
       
    20 #
       
    21 #You should have received a copy of the GNU General Public
       
    22 #License along with this library; if not, write to the Free Software
       
    23 #Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
       
    24 
       
    25 from wxPython.wx import *
       
    26 from wxPython.grid import *
       
    27 import wx
       
    28 
       
    29 from graphics.FBD_Objects import *
       
    30 from graphics.LD_Objects import *
       
    31 from graphics.SFC_Objects import *
       
    32 
       
    33 #-------------------------------------------------------------------------------
       
    34 #                          Create New Block Dialog
       
    35 #-------------------------------------------------------------------------------
       
    36 
       
    37 [wxID_BLOCKPROPERTIESDIALOG, wxID_BLOCKPROPERTIESDIALOGMAINPANEL, 
       
    38  wxID_BLOCKPROPERTIESDIALOGNAME, wxID_BLOCKPROPERTIESDIALOGTYPETREE, 
       
    39  wxID_BLOCKPROPERTIESDIALOGTYPEDESC, wxID_BLOCKPROPERTIESDIALOGINPUTS, 
       
    40  wxID_BLOCKPROPERTIESDIALOGPREVIEW, wxID_BLOCKPROPERTIESDIALOGSTATICTEXT1, 
       
    41  wxID_BLOCKPROPERTIESDIALOGSTATICTEXT2, wxID_BLOCKPROPERTIESDIALOGSTATICTEXT3, 
       
    42  wxID_BLOCKPROPERTIESDIALOGSTATICTEXT4, 
       
    43 ] = [wx.NewId() for _init_ctrls in range(11)]
       
    44 
       
    45 [CATEGORY, BLOCK] = range(2)
       
    46 
       
    47 class BlockPropertiesDialog(wx.Dialog):
       
    48     def _init_coll_flexGridSizer1_Items(self, parent):
       
    49         # generated method, don't edit
       
    50 
       
    51         parent.AddWindow(self.MainPanel, 0, border=0, flag=0)
       
    52 
       
    53     def _init_sizers(self):
       
    54         # generated method, don't edit
       
    55         self.flexGridSizer1 = wx.FlexGridSizer(cols=1, hgap=0, rows=2, vgap=0)
       
    56 
       
    57         self._init_coll_flexGridSizer1_Items(self.flexGridSizer1)
       
    58 
       
    59         self.SetSizer(self.flexGridSizer1)
       
    60 
       
    61     def _init_ctrls(self, prnt):
       
    62         # generated method, don't edit
       
    63         wx.Dialog.__init__(self, id=wxID_BLOCKPROPERTIESDIALOG,
       
    64               name='BlockPropertiesDialog', parent=prnt, pos=wx.Point(376, 223),
       
    65               size=wx.Size(600, 360), style=wx.DEFAULT_DIALOG_STYLE,
       
    66               title='Block Properties')
       
    67         self.SetClientSize(wx.Size(600, 360))
       
    68 
       
    69         self.MainPanel = wx.Panel(id=wxID_BLOCKPROPERTIESDIALOGMAINPANEL,
       
    70               name='MainPanel', parent=self, pos=wx.Point(0, 0),
       
    71               size=wx.Size(600, 320), style=wx.TAB_TRAVERSAL)
       
    72         self.MainPanel.SetAutoLayout(True)
       
    73 
       
    74         self.staticbox1 = wx.StaticBox(id=wxID_BLOCKPROPERTIESDIALOGSTATICTEXT1,
       
    75               label='Type:', name='staticBox1', parent=self.MainPanel,
       
    76               pos=wx.Point(24, 24), size=wx.Size(245, 280), style=0)
       
    77 
       
    78         self.staticText2 = wx.StaticText(id=wxID_BLOCKPROPERTIESDIALOGSTATICTEXT2,
       
    79               label='Name:', name='staticText2', parent=self.MainPanel,
       
    80               pos=wx.Point(274, 24), size=wx.Size(70, 17), style=0)
       
    81 
       
    82         self.staticText3 = wx.StaticText(id=wxID_BLOCKPROPERTIESDIALOGSTATICTEXT2,
       
    83               label='Inputs:', name='staticText4', parent=self.MainPanel,
       
    84               pos=wx.Point(424, 24), size=wx.Size(70, 17), style=0)
       
    85 
       
    86         self.staticText4 = wx.StaticText(id=wxID_BLOCKPROPERTIESDIALOGSTATICTEXT4,
       
    87               label='Preview:', name='staticText4', parent=self.MainPanel,
       
    88               pos=wx.Point(274, 80), size=wx.Size(100, 17), style=0)
       
    89 
       
    90         self.TypeTree = wx.TreeCtrl(id=wxID_BLOCKPROPERTIESDIALOGTYPETREE,
       
    91               name='TypeTree', parent=self.MainPanel, pos=wx.Point(34, 44),
       
    92               size=wx.Size(225, 180), style=wx.TR_HAS_BUTTONS|wx.TR_HIDE_ROOT|wx.TR_SINGLE|wx.SUNKEN_BORDER)
       
    93         EVT_TREE_SEL_CHANGED(self, wxID_BLOCKPROPERTIESDIALOGTYPETREE, self.OnTypeTreeItemSelected)
       
    94 
       
    95         self.TypeDesc = wx.TextCtrl(id=wxID_BLOCKPROPERTIESDIALOGTYPEDESC,
       
    96               name='TypeDesc', parent=self.MainPanel, pos=wx.Point(34, 230),
       
    97               size=wx.Size(225, 65), style=wx.TE_READONLY|wx.TE_MULTILINE)
       
    98 
       
    99         self.Name = wx.TextCtrl(id=wxID_BLOCKPROPERTIESDIALOGNAME, value='',
       
   100               name='Name', parent=self.MainPanel, pos=wx.Point(274, 48),
       
   101               size=wx.Size(145, 24), style=0)
       
   102         EVT_TEXT(self, wxID_BLOCKPROPERTIESDIALOGNAME, self.OnNameChanged)
       
   103 
       
   104         self.Inputs = wx.SpinCtrl(id=wxID_BLOCKPROPERTIESDIALOGINPUTS,
       
   105               name='Inputs', parent=self.MainPanel, pos=wx.Point(424, 48),
       
   106               size=wx.Size(145, 24), style=wxSP_ARROW_KEYS, min=2, max=20)
       
   107         EVT_SPINCTRL(self, wxID_BLOCKPROPERTIESDIALOGINPUTS, self.OnInputsChanged)
       
   108 
       
   109         self.Preview = wx.Panel(id=wxID_BLOCKPROPERTIESDIALOGPREVIEW,
       
   110               name='Preview', parent=self.MainPanel, pos=wx.Point(274, 104),
       
   111               size=wx.Size(300, 200), style=wx.TAB_TRAVERSAL|wx.SIMPLE_BORDER)
       
   112         self.Preview.SetBackgroundColour(wxColour(255,255,255))
       
   113 
       
   114         self._init_sizers()
       
   115 
       
   116     def __init__(self, parent):
       
   117         self._init_ctrls(parent)
       
   118         self.ButtonSizer = self.CreateButtonSizer(wxOK|wxCANCEL|wxCENTRE)
       
   119         self.flexGridSizer1.Add(self.ButtonSizer, 1, wxALIGN_RIGHT)
       
   120         self.Name.SetValue("")
       
   121         self.Name.Enable(False)
       
   122         self.Inputs.Enable(False)
       
   123         self.Block = None
       
   124         self.MinBlockSize = None
       
   125         
       
   126         EVT_PAINT(self, self.OnPaint)
       
   127         EVT_BUTTON(self, self.ButtonSizer.GetAffirmativeButton().GetId(), self.OnOK)
       
   128     
       
   129     def FindTreeItem(self, root, name):
       
   130         if root.IsOk():
       
   131             if self.TypeTree.GetItemText(root) == name:
       
   132                 return root
       
   133             else:
       
   134                 item, root_cookie = self.TypeTree.GetFirstChild(root)
       
   135                 while item.IsOk():
       
   136                     result = self.FindTreeItem(item, name)
       
   137                     if result:
       
   138                         return result
       
   139                     item, root_cookie = self.TypeTree.GetNextChild(root, root_cookie)
       
   140         return None
       
   141     
       
   142     def OnOK(self, event):
       
   143         error = []
       
   144         selected = self.TypeTree.GetSelection()
       
   145         if not selected.IsOk() or self.TypeTree.GetItemParent(selected) == self.TypeTree.GetRootItem() or selected == self.TypeTree.GetRootItem():
       
   146             message = wxMessageDialog(self, "Form isn't complete. Valid block type must be selected!", "Error", wxOK|wxICON_ERROR)
       
   147             message.ShowModal()
       
   148             message.Destroy()
       
   149         elif self.Name.IsEnabled() and self.Name.GetValue() == "":
       
   150             message = wxMessageDialog(self, "Form isn't complete. Name must be filled!", "Error", wxOK|wxICON_ERROR)
       
   151             message.ShowModal()
       
   152             message.Destroy()
       
   153         else:
       
   154             self.EndModal(wxID_OK)
       
   155 
       
   156     def SetBlockList(self, blocktypes):
       
   157         root = self.TypeTree.AddRoot("")
       
   158         self.TypeTree.SetPyData(root, CATEGORY)
       
   159         for category in blocktypes:
       
   160             category_item = self.TypeTree.AppendItem(root, category["name"])
       
   161             self.TypeTree.SetPyData(category_item, CATEGORY)
       
   162             for blocktype in category["list"]:
       
   163                 blocktype_item = self.TypeTree.AppendItem(category_item, blocktype["name"])
       
   164                 self.TypeTree.SetPyData(blocktype_item, BLOCK)
       
   165 
       
   166     def SetMinBlockSize(self, size):
       
   167         self.MinBlockSize = size
       
   168 
       
   169     def SetValues(self, values):
       
   170         for name, value in values.items():
       
   171             if name == "type":
       
   172                 item = self.FindTreeItem(self.TypeTree.GetRootItem(), value)
       
   173                 if item:
       
   174                     self.TypeTree.SelectItem(item)
       
   175             elif name == "name":
       
   176                 self.Name.SetValue(value)
       
   177             elif name == "extension":
       
   178                 self.Inputs.SetValue(value)
       
   179         self.RefreshPreview()
       
   180 
       
   181     def GetValues(self):
       
   182         values = {}
       
   183         values["type"] = self.TypeTree.GetItemText(self.TypeTree.GetSelection())
       
   184         if self.Name.GetValue() != "":
       
   185             values["name"] = self.Name.GetValue()
       
   186         values["width"], values["height"] = self.Block.GetSize()
       
   187         values["extension"] = self.Inputs.GetValue()
       
   188         return values
       
   189 
       
   190     def OnTypeTreeItemSelected(self, event):
       
   191         self.Name.SetValue("")
       
   192         selected = event.GetItem()
       
   193         if self.TypeTree.GetPyData(selected) != CATEGORY:
       
   194             blocktype = GetBlockType(self.TypeTree.GetItemText(selected))
       
   195             if blocktype:
       
   196                 self.Inputs.SetValue(len(blocktype["inputs"]))
       
   197                 self.Inputs.Enable(blocktype["extensible"])
       
   198                 self.Name.Enable(blocktype["type"] != "function")
       
   199                 self.TypeDesc.SetValue(blocktype["comment"])
       
   200                 wxCallAfter(self.RefreshPreview)
       
   201             else:
       
   202                 self.Name.Enable(False)
       
   203                 self.Inputs.Enable(False)
       
   204                 self.Inputs.SetValue(2)
       
   205                 self.TypeDesc.SetValue("")
       
   206                 wxCallAfter(self.ErasePreview)
       
   207         else:
       
   208             self.Name.Enable(False)
       
   209             self.Inputs.Enable(False)
       
   210             self.Inputs.SetValue(2)
       
   211             self.TypeDesc.SetValue("")
       
   212             wxCallAfter(self.ErasePreview)
       
   213         event.Skip()
       
   214 
       
   215     def OnNameChanged(self, event):
       
   216         if self.Name.IsEnabled():
       
   217             self.RefreshPreview()
       
   218         event.Skip()
       
   219     
       
   220     def OnInputsChanged(self, event):
       
   221         if self.Inputs.IsEnabled():
       
   222             self.RefreshPreview()
       
   223         event.Skip()
       
   224     
       
   225     def ErasePreview(self):
       
   226         dc = wxClientDC(self.Preview)
       
   227         dc.Clear()
       
   228         self.Block = None
       
   229         
       
   230     def RefreshPreview(self):
       
   231         dc = wxClientDC(self.Preview)
       
   232         dc.Clear()
       
   233         item = self.TypeTree.GetSelection()
       
   234         if self.TypeTree.GetPyData(item) == CATEGORY:
       
   235             self.Block = None
       
   236         else:
       
   237             blocktype = self.TypeTree.GetItemText(item)
       
   238             if blocktype:
       
   239                 self.Block = FBD_Block(self.Preview, blocktype, self.Name.GetValue(), extension = self.Inputs.GetValue())
       
   240                 width, height = self.MinBlockSize
       
   241                 min_width, min_height = self.Block.GetMinSize()
       
   242                 width, height = max(min_width, width), max(min_height, height)
       
   243                 self.Block.SetSize(width, height)
       
   244                 clientsize = self.Preview.GetClientSize()
       
   245                 x = (clientsize.width - width) / 2
       
   246                 y = (clientsize.height - height) / 2
       
   247                 self.Block.SetPosition(x, y)
       
   248                 self.Block.Draw(dc)
       
   249             else:
       
   250                 self.Block = None
       
   251 
       
   252     def OnPaint(self, event):
       
   253         if self.Block:
       
   254             self.RefreshPreview()
       
   255 
       
   256 
       
   257 #-------------------------------------------------------------------------------
       
   258 #                          Create New Variable Dialog
       
   259 #-------------------------------------------------------------------------------
       
   260 
       
   261 [wxID_VARIABLEPROPERTIESDIALOG, wxID_VARIABLEPROPERTIESDIALOGMAINPANEL, 
       
   262  wxID_VARIABLEPROPERTIESDIALOGNAME, wxID_VARIABLEPROPERTIESDIALOGCLASS, 
       
   263  wxID_VARIABLEPROPERTIESDIALOGPREVIEW, wxID_VARIABLEPROPERTIESDIALOGSTATICTEXT1,
       
   264  wxID_VARIABLEPROPERTIESDIALOGSTATICTEXT2, wxID_VARIABLEPROPERTIESDIALOGSTATICTEXT3, 
       
   265 ] = [wx.NewId() for _init_ctrls in range(8)]
       
   266 
       
   267 class VariablePropertiesDialog(wx.Dialog):
       
   268     def _init_coll_flexGridSizer1_Items(self, parent):
       
   269         # generated method, don't edit
       
   270 
       
   271         parent.AddWindow(self.MainPanel, 0, border=0, flag=0)
       
   272 
       
   273     def _init_sizers(self):
       
   274         # generated method, don't edit
       
   275         self.flexGridSizer1 = wx.FlexGridSizer(cols=1, hgap=0, rows=2, vgap=0)
       
   276 
       
   277         self._init_coll_flexGridSizer1_Items(self.flexGridSizer1)
       
   278 
       
   279         self.SetSizer(self.flexGridSizer1)
       
   280 
       
   281     def _init_ctrls(self, prnt):
       
   282         # generated method, don't edit
       
   283         wx.Dialog.__init__(self, id=wxID_VARIABLEPROPERTIESDIALOG,
       
   284               name='VariablePropertiesDialog', parent=prnt, pos=wx.Point(376, 223),
       
   285               size=wx.Size(400, 320), style=wx.DEFAULT_DIALOG_STYLE,
       
   286               title='Variable Properties')
       
   287         self.SetClientSize(wx.Size(400, 320))
       
   288 
       
   289         self.MainPanel = wx.Panel(id=wxID_VARIABLEPROPERTIESDIALOGMAINPANEL,
       
   290               name='MainPanel', parent=self, pos=wx.Point(0, 0),
       
   291               size=wx.Size(400, 280), style=wx.TAB_TRAVERSAL)
       
   292         self.MainPanel.SetAutoLayout(True)
       
   293 
       
   294         self.staticText1 = wx.StaticText(id=wxID_VARIABLEPROPERTIESDIALOGSTATICTEXT1,
       
   295               label='Class:', name='staticText1', parent=self.MainPanel,
       
   296               pos=wx.Point(24, 24), size=wx.Size(70, 17), style=0)
       
   297 
       
   298         self.staticText2 = wx.StaticText(id=wxID_VARIABLEPROPERTIESDIALOGSTATICTEXT2,
       
   299               label='Name:', name='staticText2', parent=self.MainPanel,
       
   300               pos=wx.Point(204, 24), size=wx.Size(70, 17), style=0)
       
   301 
       
   302         self.staticText3 = wx.StaticText(id=wxID_VARIABLEPROPERTIESDIALOGSTATICTEXT3,
       
   303               label='Preview:', name='staticText3', parent=self.MainPanel,
       
   304               pos=wx.Point(24, 78), size=wx.Size(100, 17), style=0)
       
   305 
       
   306         self.Class = wx.Choice(id=wxID_VARIABLEPROPERTIESDIALOGCLASS,
       
   307               name='Class', parent=self.MainPanel, pos=wx.Point(24, 48),
       
   308               size=wx.Size(145, 24), style=0)
       
   309         EVT_CHOICE(self, wxID_VARIABLEPROPERTIESDIALOGCLASS, self.OnClassChanged)
       
   310         
       
   311         self.Name = wx.Choice(id=wxID_VARIABLEPROPERTIESDIALOGNAME,
       
   312               name='Name', parent=self.MainPanel, pos=wx.Point(204, 48),
       
   313               size=wx.Size(145, 24), style=0)
       
   314         EVT_CHOICE(self, wxID_VARIABLEPROPERTIESDIALOGNAME, self.OnNameChanged)
       
   315 
       
   316         self.Preview = wx.Panel(id=wxID_VARIABLEPROPERTIESDIALOGPREVIEW,
       
   317               name='Preview', parent=self.MainPanel, pos=wx.Point(24, 104),
       
   318               size=wx.Size(350, 150), style=wx.TAB_TRAVERSAL|wx.SIMPLE_BORDER)
       
   319         self.Preview.SetBackgroundColour(wxColour(255,255,255))
       
   320 
       
   321         self._init_sizers()
       
   322 
       
   323     def __init__(self, parent):
       
   324         self._init_ctrls(parent)
       
   325         self.ButtonSizer = self.CreateButtonSizer(wxOK|wxCANCEL|wxCENTRE)
       
   326         self.flexGridSizer1.Add(self.ButtonSizer, 1, wxALIGN_RIGHT)
       
   327         self.Variable = None
       
   328         self.VarList = []
       
   329         self.MinVariableSize = None
       
   330         self.RefreshNameList()
       
   331         
       
   332         for choice in ["Input", "Output", "InOut"]:
       
   333             self.Class.Append(choice)
       
   334         self.Class.SetStringSelection("Input")
       
   335         
       
   336         EVT_PAINT(self, self.OnPaint)
       
   337 
       
   338     def RefreshNameList(self):
       
   339         selected = self.Name.GetStringSelection()
       
   340         self.Name.Clear()
       
   341         for name, var_type, value_type in self.VarList:
       
   342             if var_type in ["Local","Temp"]:
       
   343                 self.Name.Append(name)
       
   344             elif var_type == "Input" and self.Class.GetStringSelection() == "Input":
       
   345                 self.Name.Append(name)
       
   346             elif var_type == "Output" and self.Class.GetStringSelection() == "Output":
       
   347                 self.Name.Append(name)
       
   348             elif var_type == "InOut" and self.Class.GetStringSelection() == "InOut":
       
   349                 self.Name.Append(name)
       
   350         if self.Name.FindString(selected) != wxNOT_FOUND:
       
   351             self.Name.SetStringSelection(selected)
       
   352         self.Name.Enable(self.Name.GetCount() > 0)
       
   353             
       
   354     def SetMinVariableSize(self, size):
       
   355         self.MinVariableSize = size
       
   356 
       
   357     def SetVariables(self, vars):
       
   358         self.VarList = vars
       
   359         self.RefreshNameList()
       
   360 
       
   361     def SetValues(self, values):
       
   362         for name, value in values.items():
       
   363             if name == "type":
       
   364                 if value == INPUT:
       
   365                     self.Class.SetStringSelection("Input")
       
   366                 if value == OUTPUT:
       
   367                     self.Class.SetStringSelection("Output")
       
   368                 if value == INOUT:
       
   369                     self.Class.SetStringSelection("InOut")
       
   370             elif name == "name":
       
   371                 self.Name.SetStringSelection(value)
       
   372         self.RefreshPreview()
       
   373         
       
   374     def GetValues(self):
       
   375         values = {}
       
   376         classtype = self.Class.GetStringSelection()
       
   377         if classtype == "Input":
       
   378             values["type"] = INPUT
       
   379         elif classtype == "Output":
       
   380             values["type"] = OUTPUT
       
   381         elif classtype == "InOut":
       
   382             values["type"] = INOUT
       
   383         values["name"] = self.Name.GetStringSelection()
       
   384         values["value_type"] = ""
       
   385         for var_name, var_type, value_type in self.VarList:
       
   386             if var_name == values["name"]:
       
   387                 values["value_type"] = value_type
       
   388         values["width"], values["height"] = self.Variable.GetSize()
       
   389         return values
       
   390 
       
   391     def OnClassChanged(self, event):
       
   392         self.RefreshNameList()
       
   393         self.RefreshPreview()
       
   394         event.Skip()
       
   395 
       
   396     def OnNameChanged(self, event):
       
   397         self.RefreshPreview()
       
   398         event.Skip()
       
   399         
       
   400     def RefreshPreview(self):
       
   401         dc = wxClientDC(self.Preview)
       
   402         dc.Clear()
       
   403         name = self.Name.GetStringSelection()
       
   404         type = ""
       
   405         for var_name, var_type, value_type in self.VarList:
       
   406             if var_name == name:
       
   407                 type = value_type
       
   408         classtype = self.Class.GetStringSelection()
       
   409         if classtype == "Input":
       
   410             self.Variable = FBD_Variable(self.Preview, INPUT, name, type)
       
   411         elif classtype == "Output":
       
   412             self.Variable = FBD_Variable(self.Preview, OUTPUT, name, type)
       
   413         elif classtype == "InOut":
       
   414             self.Variable = FBD_Variable(self.Preview, INOUT, name, type)
       
   415         width, height = self.MinVariableSize
       
   416         min_width, min_height = self.Variable.GetMinSize()
       
   417         width, height = max(min_width, width), max(min_height, height)
       
   418         self.Variable.SetSize(width, height)
       
   419         clientsize = self.Preview.GetClientSize()
       
   420         x = (clientsize.width - width) / 2
       
   421         y = (clientsize.height - height) / 2
       
   422         self.Variable.SetPosition(x, y)
       
   423         self.Variable.Draw(dc)
       
   424 
       
   425     def OnPaint(self, event):
       
   426         self.RefreshPreview()
       
   427 
       
   428 #-------------------------------------------------------------------------------
       
   429 #                          Create New Connection Dialog
       
   430 #-------------------------------------------------------------------------------
       
   431 
       
   432 [wxID_CONNECTIONPROPERTIESDIALOG, wxID_CONNECTIONPROPERTIESDIALOGMAINPANEL, 
       
   433  wxID_CONNECTIONPROPERTIESDIALOGNAME, wxID_CONNECTIONPROPERTIESDIALOGRADIOBUTTON1, 
       
   434  wxID_CONNECTIONPROPERTIESDIALOGRADIOBUTTON2, wxID_CONNECTIONPROPERTIESDIALOGPREVIEW,
       
   435  wxID_CONNECTIONPROPERTIESDIALOGSTATICTEXT1, wxID_CONNECTIONPROPERTIESDIALOGSTATICTEXT2, 
       
   436  wxID_CONNECTIONPROPERTIESDIALOGSTATICTEXT3, 
       
   437 ] = [wx.NewId() for _init_ctrls in range(9)]
       
   438 
       
   439 class ConnectionPropertiesDialog(wx.Dialog):
       
   440     def _init_coll_flexGridSizer1_Items(self, parent):
       
   441         # generated method, don't edit
       
   442 
       
   443         parent.AddWindow(self.MainPanel, 0, border=0, flag=0)
       
   444 
       
   445     def _init_sizers(self):
       
   446         # generated method, don't edit
       
   447         self.flexGridSizer1 = wx.FlexGridSizer(cols=1, hgap=0, rows=2, vgap=0)
       
   448 
       
   449         self._init_coll_flexGridSizer1_Items(self.flexGridSizer1)
       
   450 
       
   451         self.SetSizer(self.flexGridSizer1)
       
   452 
       
   453     def _init_ctrls(self, prnt):
       
   454         # generated method, don't edit
       
   455         wx.Dialog.__init__(self, id=wxID_CONNECTIONPROPERTIESDIALOG,
       
   456               name='ConnectionPropertiesDialog', parent=prnt, pos=wx.Point(376, 223),
       
   457               size=wx.Size(350, 220), style=wx.DEFAULT_DIALOG_STYLE,
       
   458               title='Connection Properties')
       
   459         self.SetClientSize(wx.Size(350, 220))
       
   460 
       
   461         self.MainPanel = wx.Panel(id=wxID_CONNECTIONPROPERTIESDIALOGMAINPANEL,
       
   462               name='MainPanel', parent=self, pos=wx.Point(0, 0),
       
   463               size=wx.Size(340, 360), style=wx.TAB_TRAVERSAL)
       
   464         self.MainPanel.SetAutoLayout(True)
       
   465 
       
   466         self.staticText1 = wx.StaticText(id=wxID_CONNECTIONPROPERTIESDIALOGSTATICTEXT1,
       
   467               label='Type:', name='staticText1', parent=self.MainPanel,
       
   468               pos=wx.Point(24, 24), size=wx.Size(70, 17), style=0)
       
   469 
       
   470         self.staticText2 = wx.StaticText(id=wxID_CONNECTIONPROPERTIESDIALOGSTATICTEXT2,
       
   471               label='Name:', name='staticText2', parent=self.MainPanel,
       
   472               pos=wx.Point(24, 104), size=wx.Size(70, 17), style=0)
       
   473 
       
   474         self.staticText3 = wx.StaticText(id=wxID_CONNECTIONPROPERTIESDIALOGSTATICTEXT3,
       
   475               label='Preview:', name='staticText3', parent=self.MainPanel,
       
   476               pos=wx.Point(174, 24), size=wx.Size(100, 17), style=0)
       
   477 
       
   478         self.radioButton1 = wx.RadioButton(id=wxID_CONNECTIONPROPERTIESDIALOGRADIOBUTTON1,
       
   479               label='Connector', name='radioButton1', parent=self.MainPanel,
       
   480               pos=wx.Point(24, 48), size=wx.Size(114, 24), style=0)
       
   481         EVT_RADIOBUTTON(self, wxID_CONNECTIONPROPERTIESDIALOGRADIOBUTTON1, self.OnTypeChanged)
       
   482         self.radioButton1.SetValue(True)
       
   483 
       
   484         self.radioButton2 = wx.RadioButton(id=wxID_CONNECTIONPROPERTIESDIALOGRADIOBUTTON2,
       
   485               label='Continuation', name='radioButton2', parent=self.MainPanel, 
       
   486               pos=wx.Point(24, 72), size=wx.Size(128, 24), style=0)
       
   487         EVT_RADIOBUTTON(self, wxID_CONNECTIONPROPERTIESDIALOGRADIOBUTTON2, self.OnTypeChanged)
       
   488         self.radioButton2.SetValue(False)
       
   489         
       
   490         self.Name = wx.TextCtrl(id=wxID_CONNECTIONPROPERTIESDIALOGNAME,
       
   491               name='Name', parent=self.MainPanel, pos=wx.Point(24, 130),
       
   492               size=wx.Size(145, 24), style=0)
       
   493         EVT_TEXT(self, wxID_CONNECTIONPROPERTIESDIALOGNAME, self.OnNameChanged)
       
   494 
       
   495         self.Preview = wx.Panel(id=wxID_CONNECTIONPROPERTIESDIALOGPREVIEW,
       
   496               name='Preview', parent=self.MainPanel, pos=wx.Point(174, 48),
       
   497               size=wx.Size(150, 100), style=wx.TAB_TRAVERSAL|wx.SIMPLE_BORDER)
       
   498         self.Preview.SetBackgroundColour(wxColour(255,255,255))
       
   499 
       
   500         self._init_sizers()
       
   501 
       
   502     def __init__(self, parent):
       
   503         self._init_ctrls(parent)
       
   504         self.ButtonSizer = self.CreateButtonSizer(wxOK|wxCANCEL|wxCENTRE)
       
   505         self.flexGridSizer1.Add(self.ButtonSizer, 1, wxALIGN_RIGHT)
       
   506         self.Connection = None
       
   507         self.MinConnectionSize = None
       
   508         
       
   509         EVT_PAINT(self, self.OnPaint)
       
   510             
       
   511     def SetMinConnectionSize(self, size):
       
   512         self.MinConnectionSize = size
       
   513         
       
   514     def GetValues(self):
       
   515         values = {}
       
   516         if self.radioButton1.GetValue():
       
   517             values["type"] = CONNECTOR
       
   518         else:
       
   519             values["type"] = CONTINUATION
       
   520         values["name"] = self.Name.GetValue()
       
   521         values["width"], values["height"] = self.Connection.GetSize()
       
   522         return values
       
   523 
       
   524     def OnTypeChanged(self, event):
       
   525         self.RefreshPreview()
       
   526         event.Skip()
       
   527 
       
   528     def OnNameChanged(self, event):
       
   529         self.RefreshPreview()
       
   530         event.Skip()
       
   531         
       
   532     def RefreshPreview(self):
       
   533         dc = wxClientDC(self.Preview)
       
   534         dc.Clear()
       
   535         if self.radioButton1.GetValue():
       
   536             self.Connection = FBD_Connector(self.Preview, CONNECTOR, self.Name.GetValue())
       
   537         else:
       
   538             self.Connection = FBD_Connector(self.Preview, CONTINUATION, self.Name.GetValue())
       
   539         width, height = self.MinConnectionSize
       
   540         min_width, min_height = self.Connection.GetMinSize()
       
   541         width, height = max(min_width, width), max(min_height, height)
       
   542         self.Connection.SetSize(width, height)
       
   543         clientsize = self.Preview.GetClientSize()
       
   544         x = (clientsize.width - width) / 2
       
   545         y = (clientsize.height - height) / 2
       
   546         self.Connection.SetPosition(x, y)
       
   547         self.Connection.Draw(dc)
       
   548 
       
   549     def OnPaint(self, event):
       
   550         self.RefreshPreview()
       
   551 
       
   552 
       
   553 #-------------------------------------------------------------------------------
       
   554 #                        Edit Ladder Element Properties Dialog
       
   555 #-------------------------------------------------------------------------------
       
   556 
       
   557 
       
   558 [wxID_LDELEMENTDIALOG, wxID_LDELEMENTDIALOGMAINPANEL, 
       
   559  wxID_LDELEMENTDIALOGNAME, wxID_LDELEMENTDIALOGRADIOBUTTON1, 
       
   560  wxID_LDELEMENTDIALOGRADIOBUTTON2, wxID_LDELEMENTDIALOGRADIOBUTTON3,
       
   561  wxID_LDELEMENTDIALOGRADIOBUTTON4, wxID_LDELEMENTDIALOGPREVIEW,
       
   562  wxID_LDELEMENTDIALOGSTATICTEXT1, wxID_LDELEMENTDIALOGSTATICTEXT2, 
       
   563  wxID_LDELEMENTDIALOGSTATICTEXT3, 
       
   564 ] = [wx.NewId() for _init_ctrls in range(11)]
       
   565 
       
   566 class LDElementDialog(wx.Dialog):
       
   567     def _init_coll_flexGridSizer1_Items(self, parent):
       
   568         # generated method, don't edit
       
   569 
       
   570         parent.AddWindow(self.MainPanel, 0, border=0, flag=0)
       
   571 
       
   572     def _init_sizers(self):
       
   573         # generated method, don't edit
       
   574         self.flexGridSizer1 = wx.FlexGridSizer(cols=1, hgap=0, rows=2, vgap=0)
       
   575 
       
   576         self._init_coll_flexGridSizer1_Items(self.flexGridSizer1)
       
   577 
       
   578         self.SetSizer(self.flexGridSizer1)
       
   579 
       
   580     def _init_ctrls(self, prnt, title, labels):
       
   581         # generated method, don't edit
       
   582         wx.Dialog.__init__(self, id=wxID_LDELEMENTDIALOG,
       
   583               name='VariablePropertiesDialog', parent=prnt, pos=wx.Point(376, 223),
       
   584               size=wx.Size(350, 260), style=wx.DEFAULT_DIALOG_STYLE,
       
   585               title=title)
       
   586         self.SetClientSize(wx.Size(350, 260))
       
   587 
       
   588         self.MainPanel = wx.Panel(id=wxID_LDELEMENTDIALOGMAINPANEL,
       
   589               name='MainPanel', parent=self, pos=wx.Point(0, 0),
       
   590               size=wx.Size(340, 200), style=wx.TAB_TRAVERSAL)
       
   591         self.MainPanel.SetAutoLayout(True)
       
   592 
       
   593         self.staticText1 = wx.StaticText(id=wxID_LDELEMENTDIALOGSTATICTEXT1,
       
   594               label='Modifier:', name='staticText1', parent=self.MainPanel,
       
   595               pos=wx.Point(24, 24), size=wx.Size(70, 17), style=0)
       
   596 
       
   597         self.staticText2 = wx.StaticText(id=wxID_LDELEMENTDIALOGSTATICTEXT2,
       
   598               label='Name:', name='staticText2', parent=self.MainPanel,
       
   599               pos=wx.Point(24, 150), size=wx.Size(70, 17), style=0)
       
   600 
       
   601         self.staticText3 = wx.StaticText(id=wxID_LDELEMENTDIALOGSTATICTEXT3,
       
   602               label='Preview:', name='staticText3', parent=self.MainPanel,
       
   603               pos=wx.Point(174, 24), size=wx.Size(100, 17), style=0)
       
   604 
       
   605         self.radioButton1 = wx.RadioButton(id=wxID_LDELEMENTDIALOGRADIOBUTTON1,
       
   606               label=labels[0], name='radioButton1', parent=self.MainPanel,
       
   607               pos=wx.Point(24, 48), size=wx.Size(114, 24), style=0)
       
   608         EVT_RADIOBUTTON(self, wxID_LDELEMENTDIALOGRADIOBUTTON1, self.OnTypeChanged)
       
   609         self.radioButton1.SetValue(True)
       
   610 
       
   611         self.radioButton2 = wx.RadioButton(id=wxID_LDELEMENTDIALOGRADIOBUTTON2,
       
   612               label=labels[1], name='radioButton2', parent=self.MainPanel, 
       
   613               pos=wx.Point(24, 72), size=wx.Size(128, 24), style=0)
       
   614         EVT_RADIOBUTTON(self, wxID_LDELEMENTDIALOGRADIOBUTTON2, self.OnTypeChanged)
       
   615 
       
   616         self.radioButton3 = wx.RadioButton(id=wxID_LDELEMENTDIALOGRADIOBUTTON3,
       
   617               label=labels[2], name='radioButton3', parent=self.MainPanel,
       
   618               pos=wx.Point(24, 96), size=wx.Size(114, 24), style=0)
       
   619         EVT_RADIOBUTTON(self, wxID_LDELEMENTDIALOGRADIOBUTTON3, self.OnTypeChanged)
       
   620 
       
   621         self.radioButton4 = wx.RadioButton(id=wxID_LDELEMENTDIALOGRADIOBUTTON4,
       
   622               label=labels[3], name='radioButton4', parent=self.MainPanel, 
       
   623               pos=wx.Point(24, 120), size=wx.Size(128, 24), style=0)
       
   624         EVT_RADIOBUTTON(self, wxID_LDELEMENTDIALOGRADIOBUTTON4, self.OnTypeChanged)
       
   625 
       
   626         self.Name = wx.Choice(id=wxID_LDELEMENTDIALOGNAME,
       
   627               name='Name', parent=self.MainPanel, pos=wx.Point(24, 174),
       
   628               size=wx.Size(145, 24), style=0)
       
   629         EVT_CHOICE(self, wxID_LDELEMENTDIALOGNAME, self.OnNameChanged)
       
   630 
       
   631         self.Preview = wx.Panel(id=wxID_LDELEMENTDIALOGPREVIEW,
       
   632               name='Preview', parent=self.MainPanel, pos=wx.Point(174, 48),
       
   633               size=wx.Size(150, 150), style=wx.TAB_TRAVERSAL|wx.SIMPLE_BORDER)
       
   634         self.Preview.SetBackgroundColour(wxColour(255,255,255))
       
   635 
       
   636         self._init_sizers()
       
   637 
       
   638     def __init__(self, parent, type):
       
   639         self.Type = type
       
   640         if type == "contact":
       
   641             self._init_ctrls(parent, "Edit Contact Values", ['Normal','Negate','Rising Edge','Falling Edge'])
       
   642             self.Element = LD_Contact(self.Preview, CONTACT_NORMAL, "")
       
   643         elif type == "coil":
       
   644             self._init_ctrls(parent, "Edit Coil Values", ['Normal','Negate','Set','Reset'])
       
   645             self.Element = LD_Coil(self.Preview, COIL_NORMAL, "")
       
   646         self.Element.SetPosition((150 - LD_ELEMENT_SIZE[0]) / 2, (150 - LD_ELEMENT_SIZE[1]) / 2)
       
   647 
       
   648         self.ButtonSizer = self.CreateButtonSizer(wxOK|wxCANCEL|wxCENTRE)
       
   649         self.flexGridSizer1.Add(self.ButtonSizer, 1, wxALIGN_RIGHT)
       
   650 
       
   651         EVT_PAINT(self, self.OnPaint)
       
   652 
       
   653     def SetElementSize(self, width, height):
       
   654         min_width, min_height = self.Element.GetMinSize()
       
   655         width, height = max(min_width, width), max(min_height, height)
       
   656         self.Element.SetSize(width, height)
       
   657         self.Element.SetPosition((150 - width) / 2, (150 - height) / 2)
       
   658 
       
   659     def SetVariables(self, vars):
       
   660         self.Name.Clear()
       
   661         for name in vars:
       
   662             self.Name.Append(name)
       
   663         self.Name.Enable(self.Name.GetCount() > 0)
       
   664 
       
   665     def SetValues(self, values):
       
   666         for name, value in values.items():
       
   667             if name == "name":
       
   668                 self.Element.SetName(value)
       
   669                 self.Name.SetStringSelection(value)
       
   670             elif name == "type":
       
   671                 self.Element.SetType(value)
       
   672                 if self.Type == "contact":
       
   673                     if value == CONTACT_NORMAL:
       
   674                         self.radioButton1.SetValue(True)
       
   675                     elif value == CONTACT_REVERSE:
       
   676                         self.radioButton2.SetValue(True)
       
   677                     elif value == CONTACT_RISING:
       
   678                         self.radioButton3.SetValue(True)
       
   679                     elif value == CONTACT_FALLING:
       
   680                         self.radioButton4.SetValue(True)
       
   681                 elif self.Type == "coil":
       
   682                     if value == COIL_NORMAL:
       
   683                         self.radioButton1.SetValue(True)
       
   684                     elif value == COIL_REVERSE:
       
   685                         self.radioButton2.SetValue(True)
       
   686                     elif value == COIL_SET:
       
   687                         self.radioButton3.SetValue(True)
       
   688                     elif value == COIL_RESET:
       
   689                         self.radioButton4.SetValue(True)
       
   690 
       
   691     def GetValues(self):
       
   692         values = {}
       
   693         values["name"] = self.Element.GetName()
       
   694         values["type"] = self.Element.GetType()
       
   695         values["width"], values["height"] = self.Element.GetSize()
       
   696         return values
       
   697 
       
   698     def OnTypeChanged(self, event):
       
   699         if self.Type == "contact":
       
   700             if self.radioButton1.GetValue():
       
   701                 self.Element.SetType(CONTACT_NORMAL)
       
   702             elif self.radioButton2.GetValue():
       
   703                 self.Element.SetType(CONTACT_REVERSE)
       
   704             elif self.radioButton3.GetValue():
       
   705                 self.Element.SetType(CONTACT_RISING)
       
   706             elif self.radioButton4.GetValue():
       
   707                 self.Element.SetType(CONTACT_FALLING)
       
   708         elif self.Type == "coil":
       
   709             if self.radioButton1.GetValue():
       
   710                 self.Element.SetType(COIL_NORMAL)
       
   711             elif self.radioButton2.GetValue():
       
   712                 self.Element.SetType(COIL_REVERSE)
       
   713             elif self.radioButton3.GetValue():
       
   714                 self.Element.SetType(COIL_SET)
       
   715             elif self.radioButton4.GetValue():
       
   716                 self.Element.SetType(COIL_RESET)
       
   717         self.RefreshPreview()
       
   718         event.Skip()
       
   719 
       
   720     def OnNameChanged(self, event):
       
   721         self.Element.SetName(self.Name.GetStringSelection())
       
   722         self.RefreshPreview()
       
   723         event.Skip()
       
   724 
       
   725     def RefreshPreview(self):
       
   726         dc = wxClientDC(self.Preview)
       
   727         dc.Clear()
       
   728         self.Element.Draw(dc)
       
   729 
       
   730     def OnPaint(self, event):
       
   731         self.RefreshPreview()
       
   732         event.Skip()
       
   733 
       
   734 
       
   735 #-------------------------------------------------------------------------------
       
   736 #                      Edit Ladder Power Rail Properties Dialog
       
   737 #-------------------------------------------------------------------------------
       
   738 
       
   739 
       
   740 [wxID_LDPOWERRAILDIALOG, wxID_LDPOWERRAILDIALOGMAINPANEL, 
       
   741  wxID_LDPOWERRAILDIALOGTYPE, wxID_LDPOWERRAILDIALOGRADIOBUTTON1, 
       
   742  wxID_LDPOWERRAILDIALOGRADIOBUTTON2, wxID_LDPOWERRAILDIALOGPREVIEW,
       
   743  wxID_LDPOWERRAILDIALOGSTATICTEXT1, wxID_LDPOWERRAILDIALOGSTATICTEXT2, 
       
   744  wxID_LDPOWERRAILDIALOGSTATICTEXT3, wxID_LDPOWERRAILDIALOGPINNUMBER,
       
   745 ] = [wx.NewId() for _init_ctrls in range(10)]
       
   746 
       
   747 class LDPowerRailDialog(wx.Dialog):
       
   748     def _init_coll_flexGridSizer1_Items(self, parent):
       
   749         # generated method, don't edit
       
   750 
       
   751         parent.AddWindow(self.MainPanel, 0, border=0, flag=0)
       
   752 
       
   753     def _init_sizers(self):
       
   754         # generated method, don't edit
       
   755         self.flexGridSizer1 = wx.FlexGridSizer(cols=1, hgap=0, rows=2, vgap=0)
       
   756 
       
   757         self._init_coll_flexGridSizer1_Items(self.flexGridSizer1)
       
   758 
       
   759         self.SetSizer(self.flexGridSizer1)
       
   760 
       
   761     def _init_ctrls(self, prnt):
       
   762         # generated method, don't edit
       
   763         wx.Dialog.__init__(self, id=wxID_LDPOWERRAILDIALOG,
       
   764               name='PowerRailDialog', parent=prnt, pos=wx.Point(376, 223),
       
   765               size=wx.Size(350, 260), style=wx.DEFAULT_DIALOG_STYLE,
       
   766               title='Power Rail Properties')
       
   767         self.SetClientSize(wx.Size(350, 260))
       
   768 
       
   769         self.MainPanel = wx.Panel(id=wxID_LDPOWERRAILDIALOGMAINPANEL,
       
   770               name='MainPanel', parent=self, pos=wx.Point(0, 0),
       
   771               size=wx.Size(340, 200), style=wx.TAB_TRAVERSAL)
       
   772         self.MainPanel.SetAutoLayout(True)
       
   773 
       
   774         self.staticText1 = wx.StaticText(id=wxID_LDPOWERRAILDIALOGSTATICTEXT1,
       
   775               label='Type:', name='staticText1', parent=self.MainPanel,
       
   776               pos=wx.Point(24, 24), size=wx.Size(70, 17), style=0)
       
   777 
       
   778         self.staticText2 = wx.StaticText(id=wxID_LDPOWERRAILDIALOGSTATICTEXT2,
       
   779               label='Pin number:', name='staticText2', parent=self.MainPanel,
       
   780               pos=wx.Point(24, 100), size=wx.Size(70, 17), style=0)
       
   781 
       
   782         self.staticText3 = wx.StaticText(id=wxID_LDPOWERRAILDIALOGSTATICTEXT3,
       
   783               label='Preview:', name='staticText3', parent=self.MainPanel,
       
   784               pos=wx.Point(174, 24), size=wx.Size(100, 17), style=0)
       
   785 
       
   786         self.radioButton1 = wx.RadioButton(id=wxID_LDPOWERRAILDIALOGRADIOBUTTON1,
       
   787               label='Left PowerRail', name='radioButton1', parent=self.MainPanel,
       
   788               pos=wx.Point(24, 48), size=wx.Size(114, 24), style=0)
       
   789         EVT_RADIOBUTTON(self, wxID_LDPOWERRAILDIALOGRADIOBUTTON1, self.OnTypeChanged)
       
   790         self.radioButton1.SetValue(True)
       
   791 
       
   792         self.radioButton2 = wx.RadioButton(id=wxID_LDPOWERRAILDIALOGRADIOBUTTON2,
       
   793               label='Right PowerRail', name='radioButton2', parent=self.MainPanel, 
       
   794               pos=wx.Point(24, 72), size=wx.Size(128, 24), style=0)
       
   795         EVT_RADIOBUTTON(self, wxID_LDPOWERRAILDIALOGRADIOBUTTON2, self.OnTypeChanged)
       
   796 
       
   797         self.PinNumber = wx.SpinCtrl(id=wxID_LDPOWERRAILDIALOGPINNUMBER,
       
   798               name='PinNumber', parent=self.MainPanel, pos=wx.Point(24, 124),
       
   799               size=wx.Size(145, 24), style=wxSP_ARROW_KEYS, min=1, max=20)
       
   800         EVT_SPINCTRL(self, wxID_LDPOWERRAILDIALOGPINNUMBER, self.OnPinNumberChanged)
       
   801 
       
   802         self.Preview = wx.Panel(id=wxID_LDPOWERRAILDIALOGPREVIEW,
       
   803               name='Preview', parent=self.MainPanel, pos=wx.Point(174, 48),
       
   804               size=wx.Size(150, 150), style=wx.TAB_TRAVERSAL|wx.SIMPLE_BORDER)
       
   805         self.Preview.SetBackgroundColour(wxColour(255,255,255))
       
   806 
       
   807         self._init_sizers()
       
   808 
       
   809     def __init__(self, parent, type = LEFTRAIL, number = 1):
       
   810         self._init_ctrls(parent)
       
   811         self.Type = type
       
   812         if type == LEFTRAIL:
       
   813             self.radioButton1.SetValue(True)
       
   814         elif type == RIGHTRAIL:
       
   815             self.radioButton2.SetValue(True)
       
   816         self.PinNumber.SetValue(number)
       
   817         
       
   818         self.ButtonSizer = self.CreateButtonSizer(wxOK|wxCANCEL|wxCENTRE)
       
   819         self.flexGridSizer1.Add(self.ButtonSizer, 1, wxALIGN_RIGHT)
       
   820 
       
   821         self.PowerRailMinSize = (0, 0)
       
   822         self.PowerRail = None
       
   823 
       
   824         EVT_PAINT(self, self.OnPaint)
       
   825 
       
   826     def SetMinSize(self, size):
       
   827         self.PowerRailMinSize = size
       
   828         self.RefreshPreview()
       
   829 
       
   830     def GetValues(self):
       
   831         values = {}
       
   832         values["type"] = self.Type
       
   833         values["number"] = self.PinNumber.GetValue()
       
   834         values["width"], values["height"] = self.PowerRail.GetSize()
       
   835         return values
       
   836 
       
   837     def OnTypeChanged(self, event):
       
   838         if self.radioButton1.GetValue():
       
   839             self.Type = LEFTRAIL
       
   840         elif self.radioButton2.GetValue():
       
   841             self.Type = RIGHTRAIL
       
   842         self.RefreshPreview()
       
   843         event.Skip()
       
   844 
       
   845     def OnPinNumberChanged(self, event):
       
   846         self.RefreshPreview()
       
   847         event.Skip()
       
   848 
       
   849     def RefreshPreview(self):
       
   850         dc = wxClientDC(self.Preview)
       
   851         dc.Clear()
       
   852         self.PowerRail = LD_PowerRail(self.Preview, self.Type, connectors = [True for i in xrange(self.PinNumber.GetValue())])
       
   853         min_width, min_height = self.PowerRail.GetMinSize()
       
   854         width, height = max(min_width, self.PowerRailMinSize[0]), max(min_height, self.PowerRailMinSize[1])
       
   855         self.PowerRail.SetSize(width, height)
       
   856         self.PowerRail.RefreshConnectors()
       
   857         self.PowerRail.SetPosition((150 - width) / 2, (150 - height) / 2)
       
   858         self.PowerRail.Draw(dc)
       
   859 
       
   860     def OnPaint(self, event):
       
   861         self.RefreshPreview()
       
   862         event.Skip()
       
   863 
       
   864 
       
   865 #-------------------------------------------------------------------------------
       
   866 #                          Edit Transition Content Dialog
       
   867 #-------------------------------------------------------------------------------
       
   868 
       
   869 [wxID_TRANSITIONCONTENTDIALOG, wxID_TRANSITIONCONTENTDIALOGMAINPANEL, 
       
   870  wxID_TRANSITIONCONTENTDIALOGREFERENCE, wxID_TRANSITIONCONTENTDIALOGINLINE, 
       
   871  wxID_TRANSITIONCONTENTDIALOGRADIOBUTTON1, wxID_TRANSITIONCONTENTDIALOGRADIOBUTTON2, 
       
   872 ] = [wx.NewId() for _init_ctrls in range(6)]
       
   873 
       
   874 class TransitionContentDialog(wx.Dialog):
       
   875     def _init_coll_flexGridSizer1_Items(self, parent):
       
   876         # generated method, don't edit
       
   877 
       
   878         parent.AddWindow(self.MainPanel, 0, border=0, flag=0)
       
   879 
       
   880     def _init_sizers(self):
       
   881         # generated method, don't edit
       
   882         self.flexGridSizer1 = wx.FlexGridSizer(cols=1, hgap=0, rows=2, vgap=0)
       
   883 
       
   884         self._init_coll_flexGridSizer1_Items(self.flexGridSizer1)
       
   885 
       
   886         self.SetSizer(self.flexGridSizer1)
       
   887 
       
   888     def _init_ctrls(self, prnt):
       
   889         # generated method, don't edit
       
   890         wx.Dialog.__init__(self, id=wxID_TRANSITIONCONTENTDIALOG,
       
   891               name='ProjectDialog', parent=prnt, pos=wx.Point(376, 223),
       
   892               size=wx.Size(300, 200), style=wx.DEFAULT_DIALOG_STYLE,
       
   893               title='Edit transition')
       
   894         self.SetClientSize(wx.Size(300, 200))
       
   895 
       
   896         self.MainPanel = wx.Panel(id=wxID_TRANSITIONCONTENTDIALOGMAINPANEL,
       
   897               name='MainPanel', parent=self, pos=wx.Point(0, 0),
       
   898               size=wx.Size(300, 200), style=wx.TAB_TRAVERSAL)
       
   899         self.MainPanel.SetAutoLayout(True)
       
   900 
       
   901         self.radioButton1 = wx.RadioButton(id=wxID_TRANSITIONCONTENTDIALOGRADIOBUTTON1,
       
   902               label='Reference', name='radioButton1', parent=self.MainPanel,
       
   903               pos=wx.Point(24, 24), size=wx.Size(114, 24), style=0)
       
   904         EVT_RADIOBUTTON(self, wxID_TRANSITIONCONTENTDIALOGRADIOBUTTON1, self.OnTypeChanged)
       
   905         self.radioButton1.SetValue(True)
       
   906 
       
   907         self.Reference = wx.Choice(id=wxID_TRANSITIONCONTENTDIALOGREFERENCE,
       
   908               name='Reference', parent=self.MainPanel, pos=wx.Point(48, 48), 
       
   909               size=wx.Size(200, 24), style=0)
       
   910 
       
   911         self.radioButton2 = wx.RadioButton(id=wxID_TRANSITIONCONTENTDIALOGRADIOBUTTON2,
       
   912               label='Inline', name='radioButton2', parent=self.MainPanel,
       
   913               pos=wx.Point(24, 72), size=wx.Size(114, 24), style=0)
       
   914         EVT_RADIOBUTTON(self, wxID_TRANSITIONCONTENTDIALOGRADIOBUTTON2, self.OnTypeChanged)
       
   915         self.radioButton2.SetValue(False)
       
   916 
       
   917         self.Inline = wx.TextCtrl(id=wxID_TRANSITIONCONTENTDIALOGINLINE,
       
   918               name='Inline', parent=self.MainPanel, pos=wx.Point(48, 96),
       
   919               size=wx.Size(200, 24), style=0)
       
   920 
       
   921         self._init_sizers()
       
   922 
       
   923     def __init__(self, parent):
       
   924         self._init_ctrls(parent)
       
   925         self.ButtonSizer = self.CreateButtonSizer(wxOK|wxCANCEL|wxCENTRE)
       
   926         self.flexGridSizer1.Add(self.ButtonSizer, 1, wxALIGN_RIGHT)
       
   927         
       
   928         EVT_BUTTON(self, self.ButtonSizer.GetAffirmativeButton().GetId(), self.OnOK)
       
   929     
       
   930     def OnOK(self, event):
       
   931         error = []
       
   932         if self.radioButton1.GetValue() and self.Reference.GetStringSelection() == "":
       
   933             error.append("Reference")
       
   934         if self.radioButton2.GetValue() and self.Inline.GetValue() == "":
       
   935             error.append("Inline")
       
   936         if len(error) > 0:
       
   937             text = ""
       
   938             for i, item in enumerate(error):
       
   939                 if i == 0:
       
   940                     text += item
       
   941                 elif i == len(error) - 1:
       
   942                     text += " and %s"%item
       
   943                 else:
       
   944                     text += ", %s"%item 
       
   945             message = wxMessageDialog(self, "Form isn't complete. %s must be filled!"%text, "Error", wxOK|wxICON_ERROR)
       
   946             message.ShowModal()
       
   947             message.Destroy()
       
   948         else:
       
   949             self.EndModal(wxID_OK)
       
   950 
       
   951     def OnTypeChanged(self, event):
       
   952         if self.radioButton1.GetValue():
       
   953             self.Reference.Enable(True)
       
   954             self.Inline.Enable(False)
       
   955         else:
       
   956             self.Reference.Enable(False)
       
   957             self.Inline.Enable(True)
       
   958         event.Skip()
       
   959 
       
   960     def SetTransitions(self, transitions):
       
   961         for transition in transitions:
       
   962             self.Reference.Append(transition)
       
   963 
       
   964     def SetValues(self, values):
       
   965         if values["type"] == "reference":
       
   966             self.radioButton1.SetValue(True)
       
   967             self.radioButton2.SetValue(False)
       
   968             self.Reference.Enable(True)
       
   969             self.Inline.Enable(False)
       
   970             self.Reference.SetStringSelection(values["value"])
       
   971         elif values["type"] == "inline":
       
   972             self.radioButton1.SetValue(False)
       
   973             self.radioButton2.SetValue(True)
       
   974             self.Reference.Enable(False)
       
   975             self.Inline.Enable(True)
       
   976             self.Inline.SetValue(values["value"])
       
   977                 
       
   978     def GetValues(self):
       
   979         values = {}
       
   980         if self.radioButton1.GetValue():
       
   981             values["type"] = "reference"
       
   982             values["value"] = self.Reference.GetStringSelection()
       
   983         else:
       
   984             values["type"] = "inline"
       
   985             values["value"] = self.Inline.GetValue()
       
   986         return values
       
   987 
       
   988 #-------------------------------------------------------------------------------
       
   989 #                         Create New Divergence Dialog
       
   990 #-------------------------------------------------------------------------------
       
   991 
       
   992 [wxID_DIVERGENCECREATEDIALOG, wxID_DIVERGENCECREATEDIALOGMAINPANEL, 
       
   993  wxID_DIVERGENCECREATEDIALOGRADIOBUTTON1, wxID_DIVERGENCECREATEDIALOGRADIOBUTTON2,
       
   994  wxID_DIVERGENCECREATEDIALOGRADIOBUTTON3, wxID_DIVERGENCECREATEDIALOGRADIOBUTTON4, 
       
   995  wxID_DIVERGENCECREATEDIALOGSEQUENCES, wxID_DIVERGENCECREATEDIALOGPREVIEW, 
       
   996  wxID_DIVERGENCECREATEDIALOGSTATICTEXT1, wxID_DIVERGENCECREATEDIALOGSTATICTEXT2, 
       
   997  wxID_DIVERGENCECREATEDIALOGSTATICTEXT3,  
       
   998 ] = [wx.NewId() for _init_ctrls in range(11)]
       
   999 
       
  1000 class DivergenceCreateDialog(wx.Dialog):
       
  1001     def _init_coll_flexGridSizer1_Items(self, parent):
       
  1002         # generated method, don't edit
       
  1003 
       
  1004         parent.AddWindow(self.MainPanel, 0, border=0, flag=0)
       
  1005 
       
  1006     def _init_sizers(self):
       
  1007         # generated method, don't edit
       
  1008         self.flexGridSizer1 = wx.FlexGridSizer(cols=1, hgap=0, rows=2, vgap=0)
       
  1009 
       
  1010         self._init_coll_flexGridSizer1_Items(self.flexGridSizer1)
       
  1011 
       
  1012         self.SetSizer(self.flexGridSizer1)
       
  1013 
       
  1014     def _init_ctrls(self, prnt):
       
  1015         # generated method, don't edit
       
  1016         wx.Dialog.__init__(self, id=wxID_DIVERGENCECREATEDIALOG,
       
  1017               name='DivergencePropertiesDialog', parent=prnt, pos=wx.Point(376, 223),
       
  1018               size=wx.Size(500, 300), style=wx.DEFAULT_DIALOG_STYLE,
       
  1019               title='Create a new divergence or convergence')
       
  1020         self.SetClientSize(wx.Size(500, 260))
       
  1021 
       
  1022         self.MainPanel = wx.Panel(id=wxID_DIVERGENCECREATEDIALOGMAINPANEL,
       
  1023               name='MainPanel', parent=self, pos=wx.Point(0, 0),
       
  1024               size=wx.Size(600, 220), style=wx.TAB_TRAVERSAL)
       
  1025         self.MainPanel.SetAutoLayout(True)
       
  1026 
       
  1027         self.staticText1 = wx.StaticText(id=wxID_DIVERGENCECREATEDIALOGSTATICTEXT1,
       
  1028               label='Type:', name='staticText1', parent=self.MainPanel,
       
  1029               pos=wx.Point(24, 24), size=wx.Size(200, 17), style=0)
       
  1030 
       
  1031         self.radioButton1 = wx.RadioButton(id=wxID_DIVERGENCECREATEDIALOGRADIOBUTTON1,
       
  1032               label='Selection Divergence', name='radioButton1', parent=self.MainPanel,
       
  1033               pos=wx.Point(24, 48), size=wx.Size(200, 24), style=0)
       
  1034         EVT_RADIOBUTTON(self, wxID_DIVERGENCECREATEDIALOGRADIOBUTTON1, self.OnTypeChanged)
       
  1035         self.radioButton1.SetValue(True)
       
  1036 
       
  1037         self.radioButton2 = wx.RadioButton(id=wxID_DIVERGENCECREATEDIALOGRADIOBUTTON2,
       
  1038               label='Selection Convergence', name='radioButton2', parent=self.MainPanel, 
       
  1039               pos=wx.Point(24, 72), size=wx.Size(200, 24), style=0)
       
  1040         EVT_RADIOBUTTON(self, wxID_DIVERGENCECREATEDIALOGRADIOBUTTON2, self.OnTypeChanged)
       
  1041         self.radioButton2.SetValue(False)
       
  1042 
       
  1043         self.radioButton3 = wx.RadioButton(id=wxID_DIVERGENCECREATEDIALOGRADIOBUTTON3,
       
  1044               label='Simultaneous Divergence', name='radioButton3', parent=self.MainPanel,
       
  1045               pos=wx.Point(24, 96), size=wx.Size(200, 24), style=0)
       
  1046         EVT_RADIOBUTTON(self, wxID_DIVERGENCECREATEDIALOGRADIOBUTTON3, self.OnTypeChanged)
       
  1047         self.radioButton3.SetValue(False)
       
  1048 
       
  1049         self.radioButton4 = wx.RadioButton(id=wxID_DIVERGENCECREATEDIALOGRADIOBUTTON4,
       
  1050               label='Simultaneous Convergence', name='radioButton4', parent=self.MainPanel, 
       
  1051               pos=wx.Point(24, 120), size=wx.Size(200, 24), style=0)
       
  1052         EVT_RADIOBUTTON(self, wxID_DIVERGENCECREATEDIALOGRADIOBUTTON4, self.OnTypeChanged)
       
  1053         self.radioButton4.SetValue(False)
       
  1054 
       
  1055         self.staticText2 = wx.StaticText(id=wxID_DIVERGENCECREATEDIALOGSTATICTEXT2,
       
  1056               label='Number of sequences:', name='staticText2', parent=self.MainPanel,
       
  1057               pos=wx.Point(24, 150), size=wx.Size(200, 17), style=0)
       
  1058 
       
  1059         self.Sequences = wx.SpinCtrl(id=wxID_DIVERGENCECREATEDIALOGSEQUENCES,
       
  1060               name='Sequences', parent=self.MainPanel, pos=wx.Point(24, 174),
       
  1061               size=wx.Size(200, 24), style=0, min=2, max=20)
       
  1062         EVT_SPINCTRL(self, wxID_DIVERGENCECREATEDIALOGSEQUENCES, self.OnSequencesChanged)
       
  1063 
       
  1064         self.staticText3 = wx.StaticText(id=wxID_DIVERGENCECREATEDIALOGSTATICTEXT3,
       
  1065               label='Preview:', name='staticText3', parent=self.MainPanel,
       
  1066               pos=wx.Point(250, 24), size=wx.Size(100, 17), style=0)
       
  1067 
       
  1068         self.Preview = wx.Panel(id=wxID_DIVERGENCECREATEDIALOGPREVIEW,
       
  1069               name='Preview', parent=self.MainPanel, pos=wx.Point(250, 48),
       
  1070               size=wx.Size(225, 150), style=wx.TAB_TRAVERSAL|wx.SIMPLE_BORDER)
       
  1071         self.Preview.SetBackgroundColour(wxColour(255,255,255))
       
  1072 
       
  1073         self._init_sizers()
       
  1074 
       
  1075     def __init__(self, parent):
       
  1076         self._init_ctrls(parent)
       
  1077         self.ButtonSizer = self.CreateButtonSizer(wxOK|wxCANCEL|wxCENTRE)
       
  1078         self.flexGridSizer1.Add(self.ButtonSizer, 1, wxALIGN_RIGHT)
       
  1079         
       
  1080         self.Divergence = None
       
  1081         self.MinSize = (0, 0)
       
  1082         
       
  1083         EVT_PAINT(self, self.OnPaint)
       
  1084 
       
  1085     def GetValues(self):
       
  1086         values = {}
       
  1087         if self.radioButton1.GetValue():
       
  1088             values["type"] = SELECTION_DIVERGENCE
       
  1089         elif self.radioButton2.GetValue():
       
  1090             values["type"] = SELECTION_CONVERGENCE
       
  1091         elif self.radioButton3.GetValue():
       
  1092             values["type"] = SIMULTANEOUS_DIVERGENCE
       
  1093         else:
       
  1094             values["type"] = SIMULTANEOUS_CONVERGENCE
       
  1095         values["number"] = self.Sequences.GetValue()
       
  1096         return values
       
  1097 
       
  1098     def SetMinSize(self, size):
       
  1099         self.MinSize = size
       
  1100 
       
  1101     def OnTypeChanged(self, event):
       
  1102         self.RefreshPreview()
       
  1103         event.Skip()
       
  1104 
       
  1105     def OnSequencesChanged(self, event):
       
  1106         self.RefreshPreview()
       
  1107         event.Skip()
       
  1108         
       
  1109     def RefreshPreview(self):
       
  1110         dc = wxClientDC(self.Preview)
       
  1111         dc.Clear()
       
  1112         if self.radioButton1.GetValue():
       
  1113             self.Divergence = SFC_Divergence(self.Preview, SELECTION_DIVERGENCE, self.Sequences.GetValue())
       
  1114         elif self.radioButton2.GetValue():
       
  1115             self.Divergence = SFC_Divergence(self.Preview, SELECTION_CONVERGENCE, self.Sequences.GetValue())
       
  1116         elif self.radioButton3.GetValue():
       
  1117             self.Divergence = SFC_Divergence(self.Preview, SIMULTANEOUS_DIVERGENCE, self.Sequences.GetValue())
       
  1118         else:
       
  1119             self.Divergence = SFC_Divergence(self.Preview, SIMULTANEOUS_CONVERGENCE, self.Sequences.GetValue())
       
  1120         width, height = self.Divergence.GetSize()
       
  1121         min_width, min_height = max(width, self.MinSize[0]), max(height, self.MinSize[1])
       
  1122         self.Divergence.SetSize(min_width, min_height)
       
  1123         clientsize = self.Preview.GetClientSize()
       
  1124         x = (clientsize.width - min_width) / 2
       
  1125         y = (clientsize.height - min_height) / 2
       
  1126         self.Divergence.SetPosition(x, y)
       
  1127         self.Divergence.Draw(dc)
       
  1128 
       
  1129     def OnPaint(self, event):
       
  1130         self.RefreshPreview()
       
  1131 
       
  1132 
       
  1133 #-------------------------------------------------------------------------------
       
  1134 #                            Action Block Dialog
       
  1135 #-------------------------------------------------------------------------------
       
  1136 
       
  1137 class ActionTable(wxPyGridTableBase):
       
  1138     
       
  1139     """
       
  1140     A custom wxGrid Table using user supplied data
       
  1141     """
       
  1142     def __init__(self, parent, data, colnames):
       
  1143         # The base class must be initialized *first*
       
  1144         wxPyGridTableBase.__init__(self)
       
  1145         self.data = data
       
  1146         self.colnames = colnames
       
  1147         self.Parent = parent
       
  1148         # XXX
       
  1149         # we need to store the row length and collength to
       
  1150         # see if the table has changed size
       
  1151         self._rows = self.GetNumberRows()
       
  1152         self._cols = self.GetNumberCols()
       
  1153     
       
  1154     def GetNumberCols(self):
       
  1155         return len(self.colnames)
       
  1156         
       
  1157     def GetNumberRows(self):
       
  1158         return len(self.data)
       
  1159 
       
  1160     def GetColLabelValue(self, col):
       
  1161         if col < len(self.colnames):
       
  1162             return self.colnames[col]
       
  1163 
       
  1164     def GetRowLabelValues(self, row):
       
  1165         return row
       
  1166 
       
  1167     def GetValue(self, row, col):
       
  1168         if row < self.GetNumberRows():
       
  1169             name = str(self.data[row].get(self.GetColLabelValue(col), ""))
       
  1170             return name
       
  1171     
       
  1172     def GetValueByName(self, row, colname):
       
  1173         return self.data[row].get(colname)
       
  1174 
       
  1175     def SetValue(self, row, col, value):
       
  1176         if col < len(self.colnames):
       
  1177             self.data[row][self.GetColLabelValue(col)] = value
       
  1178         
       
  1179     def ResetView(self, grid):
       
  1180         """
       
  1181         (wxGrid) -> Reset the grid view.   Call this to
       
  1182         update the grid if rows and columns have been added or deleted
       
  1183         """
       
  1184         grid.BeginBatch()
       
  1185         for current, new, delmsg, addmsg in [
       
  1186             (self._rows, self.GetNumberRows(), wxGRIDTABLE_NOTIFY_ROWS_DELETED, wxGRIDTABLE_NOTIFY_ROWS_APPENDED),
       
  1187             (self._cols, self.GetNumberCols(), wxGRIDTABLE_NOTIFY_COLS_DELETED, wxGRIDTABLE_NOTIFY_COLS_APPENDED),
       
  1188         ]:
       
  1189             if new < current:
       
  1190                 msg = wxGridTableMessage(self,delmsg,new,current-new)
       
  1191                 grid.ProcessTableMessage(msg)
       
  1192             elif new > current:
       
  1193                 msg = wxGridTableMessage(self,addmsg,new-current)
       
  1194                 grid.ProcessTableMessage(msg)
       
  1195                 self.UpdateValues(grid)
       
  1196         grid.EndBatch()
       
  1197 
       
  1198         self._rows = self.GetNumberRows()
       
  1199         self._cols = self.GetNumberCols()
       
  1200         # update the column rendering scheme
       
  1201         self._updateColAttrs(grid)
       
  1202 
       
  1203         # update the scrollbars and the displayed part of the grid
       
  1204         grid.AdjustScrollbars()
       
  1205         grid.ForceRefresh()
       
  1206 
       
  1207     def UpdateValues(self, grid):
       
  1208         """Update all displayed values"""
       
  1209         # This sends an event to the grid table to update all of the values
       
  1210         msg = wxGridTableMessage(self, wxGRIDTABLE_REQUEST_VIEW_GET_VALUES)
       
  1211         grid.ProcessTableMessage(msg)
       
  1212 
       
  1213     def _updateColAttrs(self, grid):
       
  1214         """
       
  1215         wxGrid -> update the column attributes to add the
       
  1216         appropriate renderer given the column name.
       
  1217 
       
  1218         Otherwise default to the default renderer.
       
  1219         """
       
  1220         
       
  1221         for col in range(self.GetNumberCols()):
       
  1222             attr = wxGridCellAttr()
       
  1223             attr.SetAlignment(self.Parent.ColAlignements[col], wxALIGN_CENTRE)
       
  1224             grid.SetColAttr(col, attr)
       
  1225             grid.SetColSize(col, self.Parent.ColSizes[col])
       
  1226         
       
  1227         typelist = None
       
  1228         accesslist = None
       
  1229         for row in range(self.GetNumberRows()):
       
  1230             for col in range(self.GetNumberCols()):
       
  1231                 editor = None
       
  1232                 renderer = None
       
  1233                 readonly = False
       
  1234                 colname = self.GetColLabelValue(col)
       
  1235                 if colname == "Qualifier":
       
  1236                     editor = wxGridCellChoiceEditor()
       
  1237                     editor.SetParameters(self.Parent.QualifierList)
       
  1238                 if colname == "Duration":
       
  1239                     editor = wxGridCellTextEditor()
       
  1240                     renderer = wxGridCellStringRenderer()
       
  1241                     if self.Parent.DurationList[self.data[row]["Qualifier"]]:
       
  1242                         readonly = False
       
  1243                     else:
       
  1244                         readonly = True
       
  1245                         self.data[row]["Duration"] = ""
       
  1246                 elif colname == "Type":
       
  1247                     editor = wxGridCellChoiceEditor()
       
  1248                     editor.SetParameters(self.Parent.TypeList)
       
  1249                 elif colname == "Value":
       
  1250                     type = self.data[row]["Type"]
       
  1251                     if type == "Action":
       
  1252                         editor = wxGridCellChoiceEditor()
       
  1253                         editor.SetParameters(self.Parent.ActionList)
       
  1254                     elif type == "Variable":
       
  1255                         editor = wxGridCellChoiceEditor()
       
  1256                         editor.SetParameters(self.Parent.VariableList)
       
  1257                     elif type == "Inline":
       
  1258                         editor = wxGridCellTextEditor()
       
  1259                         renderer = wxGridCellStringRenderer()
       
  1260                 elif colname == "Indicator":
       
  1261                     editor = wxGridCellChoiceEditor()
       
  1262                     editor.SetParameters(self.Parent.VariableList)
       
  1263                     
       
  1264                 grid.SetCellEditor(row, col, editor)
       
  1265                 grid.SetCellRenderer(row, col, renderer)
       
  1266                 grid.SetReadOnly(row, col, readonly)
       
  1267                 
       
  1268                 grid.SetCellBackgroundColour(row, col, wxWHITE)
       
  1269     
       
  1270     def SetData(self, data):
       
  1271         self.data = data
       
  1272     
       
  1273     def GetData(self):
       
  1274         return self.data
       
  1275     
       
  1276     def GetCurrentIndex(self):
       
  1277         return self.CurrentIndex
       
  1278     
       
  1279     def SetCurrentIndex(self, index):
       
  1280         self.CurrentIndex = index
       
  1281     
       
  1282     def AppendRow(self, row_content):
       
  1283         self.data.append(row_content)
       
  1284 
       
  1285     def RemoveRow(self, row_index):
       
  1286         self.data.pop(row_index)
       
  1287         
       
  1288     def MoveRow(self, row_index, move, grid):
       
  1289         new_index = max(0, min(row_index + move, len(self.data) - 1))
       
  1290         if new_index != row_index:
       
  1291             self.data.insert(new_index, self.data.pop(row_index))
       
  1292             grid.SetGridCursor(new_index, grid.GetGridCursorCol())
       
  1293 
       
  1294     def Empty(self):
       
  1295         self.data = []
       
  1296         self.editors = []
       
  1297 
       
  1298 [wxID_ACTIONBLOCKDIALOG, wxID_ACTIONBLOCKDIALOGMAINPANEL, 
       
  1299  wxID_ACTIONBLOCKDIALOGVARIABLESGRID, wxID_ACTIONBLOCKDIALOGSTATICTEXT1, 
       
  1300  wxID_ACTIONBLOCKDIALOGADDBUTTON,wxID_ACTIONBLOCKDIALOGDELETEBUTTON, 
       
  1301  wxID_ACTIONBLOCKDIALOGUPBUTTON, wxID_ACTIONBLOCKDIALOGDOWNBUTTON, 
       
  1302 ] = [wx.NewId() for _init_ctrls in range(8)]
       
  1303 
       
  1304 class ActionBlockDialog(wx.Dialog):
       
  1305     def _init_coll_flexGridSizer1_Items(self, parent):
       
  1306         # generated method, don't edit
       
  1307 
       
  1308         parent.AddWindow(self.MainPanel, 0, border=0, flag=0)
       
  1309 
       
  1310     def _init_sizers(self):
       
  1311         # generated method, don't edit
       
  1312         self.flexGridSizer1 = wx.FlexGridSizer(cols=1, hgap=0, rows=2, vgap=0)
       
  1313 
       
  1314         self._init_coll_flexGridSizer1_Items(self.flexGridSizer1)
       
  1315 
       
  1316         self.SetSizer(self.flexGridSizer1)
       
  1317 
       
  1318     def _init_ctrls(self, prnt):
       
  1319         # generated method, don't edit
       
  1320         wx.Dialog.__init__(self, id=wxID_ACTIONBLOCKDIALOG,
       
  1321               name='ActionBlockDialog', parent=prnt, pos=wx.Point(376, 223),
       
  1322               size=wx.Size(500, 300), style=wx.DEFAULT_DIALOG_STYLE,
       
  1323               title='Edit action block properties')
       
  1324         self.SetClientSize(wx.Size(500, 300))
       
  1325 
       
  1326         self.MainPanel = wx.Panel(id=wxID_ACTIONBLOCKDIALOGMAINPANEL,
       
  1327               name='MainPanel', parent=self, pos=wx.Point(0, 0),
       
  1328               size=wx.Size(500, 300), style=wx.TAB_TRAVERSAL)
       
  1329         self.MainPanel.SetAutoLayout(True)
       
  1330 
       
  1331         self.staticText1 = wx.StaticText(id=wxID_ACTIONBLOCKDIALOGSTATICTEXT1,
       
  1332               label='Actions:', name='staticText1', parent=self.MainPanel,
       
  1333               pos=wx.Point(24, 24), size=wx.Size(95, 17), style=0)
       
  1334 
       
  1335         self.ActionsGrid = wx.grid.Grid(id=wxID_ACTIONBLOCKDIALOGVARIABLESGRID,
       
  1336               name='ActionsGrid', parent=self.MainPanel, pos=wx.Point(24, 44), 
       
  1337               size=wx.Size(450, 150), style=wxVSCROLL)
       
  1338         self.ActionsGrid.SetFont(wx.Font(12, 77, wx.NORMAL, wx.NORMAL, False,
       
  1339               'Sans'))
       
  1340         self.ActionsGrid.SetLabelFont(wx.Font(10, 77, wx.NORMAL, wx.NORMAL,
       
  1341               False, 'Sans'))
       
  1342         self.ActionsGrid.DisableDragGridSize()
       
  1343         self.ActionsGrid.EnableScrolling(False, True)
       
  1344         EVT_GRID_CELL_CHANGE(self.ActionsGrid, self.OnActionsGridCellChange)
       
  1345 
       
  1346         self.AddButton = wx.Button(id=wxID_ACTIONBLOCKDIALOGADDBUTTON, label='Add',
       
  1347               name='AddButton', parent=self.MainPanel, pos=wx.Point(245, 204),
       
  1348               size=wx.Size(72, 32), style=0)
       
  1349         EVT_BUTTON(self, wxID_ACTIONBLOCKDIALOGADDBUTTON, self.OnAddButton)
       
  1350 
       
  1351         self.DeleteButton = wx.Button(id=wxID_ACTIONBLOCKDIALOGDELETEBUTTON, label='Delete',
       
  1352               name='DeleteButton', parent=self.MainPanel, pos=wx.Point(325, 204),
       
  1353               size=wx.Size(72, 32), style=0)
       
  1354         EVT_BUTTON(self, wxID_ACTIONBLOCKDIALOGDELETEBUTTON, self.OnDeleteButton)
       
  1355 
       
  1356         self.UpButton = wx.Button(id=wxID_ACTIONBLOCKDIALOGUPBUTTON, label='^',
       
  1357               name='UpButton', parent=self.MainPanel, pos=wx.Point(405, 204),
       
  1358               size=wx.Size(32, 32), style=0)
       
  1359         EVT_BUTTON(self, wxID_ACTIONBLOCKDIALOGUPBUTTON, self.OnUpButton)
       
  1360 
       
  1361         self.DownButton = wx.Button(id=wxID_ACTIONBLOCKDIALOGDOWNBUTTON, label='v',
       
  1362               name='DownButton', parent=self.MainPanel, pos=wx.Point(445, 204),
       
  1363               size=wx.Size(32, 32), style=0)
       
  1364         EVT_BUTTON(self, wxID_ACTIONBLOCKDIALOGDOWNBUTTON, self.OnDownButton)
       
  1365 
       
  1366         self._init_sizers()
       
  1367 
       
  1368     def __init__(self, parent):
       
  1369         self._init_ctrls(parent)
       
  1370         self.ButtonSizer = self.CreateButtonSizer(wxOK|wxCANCEL|wxCENTRE)
       
  1371         self.flexGridSizer1.Add(self.ButtonSizer, 1, wxALIGN_RIGHT)
       
  1372         
       
  1373         self.DefaultValue = {"Qualifier" : "N", "Duration" : "", "Type" : "Action", "Value" : "", "Indicator" : ""}
       
  1374         self.Table = ActionTable(self, [], ["Qualifier","Duration","Type","Value","Indicator"])
       
  1375         self.TypeList = "Action,Variable,Inline"
       
  1376         self.ColSizes = [60, 90, 80, 110, 80]
       
  1377         self.ColAlignements = [wxALIGN_LEFT, wxALIGN_LEFT, wxALIGN_LEFT, wxALIGN_LEFT, wxALIGN_LEFT]
       
  1378         
       
  1379         self.ActionsGrid.SetTable(self.Table)
       
  1380         self.ActionsGrid.SetRowLabelSize(0)
       
  1381         
       
  1382         self.Table.ResetView(self.ActionsGrid)
       
  1383 
       
  1384     def OnAddButton(self, event):
       
  1385         self.Table.AppendRow(self.DefaultValue.copy())
       
  1386         self.Table.ResetView(self.ActionsGrid)
       
  1387         event.Skip()
       
  1388 
       
  1389     def OnDeleteButton(self, event):
       
  1390         row = self.ActionsGrid.GetGridCursorRow()
       
  1391         self.Table.RemoveRow(row)
       
  1392         self.Table.ResetView(self.ActionsGrid)
       
  1393         event.Skip()
       
  1394 
       
  1395     def OnUpButton(self, event):
       
  1396         row = self.ActionsGrid.GetGridCursorRow()
       
  1397         self.Table.MoveRow(row, -1, self.ActionsGrid)
       
  1398         self.Table.ResetView(self.ActionsGrid)
       
  1399         event.Skip()
       
  1400 
       
  1401     def OnDownButton(self, event):
       
  1402         row = self.ActionsGrid.GetGridCursorRow()
       
  1403         self.Table.MoveRow(row, 1, self.ActionsGrid)
       
  1404         self.Table.ResetView(self.ActionsGrid)
       
  1405         event.Skip()
       
  1406 
       
  1407     def OnActionsGridCellChange(self, event):
       
  1408         self.Table.ResetView(self.ActionsGrid)
       
  1409         event.Skip()
       
  1410 
       
  1411     def SetQualifierList(self, list):
       
  1412         self.QualifierList = ""
       
  1413         sep = ""
       
  1414         for qualifier in list.keys():
       
  1415             self.QualifierList += "%s%s"%(sep, qualifier)
       
  1416             sep = ","
       
  1417         self.DurationList = list
       
  1418 
       
  1419     def SetVariableList(self, list):
       
  1420         self.VariableList = ""
       
  1421         sep = ""
       
  1422         for variable in list:
       
  1423             self.VariableList += "%s%s"%(sep, variable["Name"])
       
  1424             sep = ","
       
  1425 
       
  1426     def SetActionList(self, list):
       
  1427         self.ActionList = ""
       
  1428         sep = ""
       
  1429         for action in list:
       
  1430             self.ActionList += "%s%s"%(sep, action)
       
  1431             sep = ","
       
  1432 
       
  1433     def SetValues(self, actions):
       
  1434         for action in actions:
       
  1435             row = {"Qualifier" : action["qualifier"], "Value" : action["value"]}
       
  1436             if action["type"] == "reference":
       
  1437                 if action["value"] in self.ActionList:
       
  1438                     row["Type"] = "Action"
       
  1439                 elif action["value"] in self.VariableList:
       
  1440                     row["Type"] = "Variable"
       
  1441                 else:
       
  1442                     row["Type"] = "Inline"
       
  1443             else:
       
  1444                 row["Type"] = "Inline"
       
  1445             if "duration" in action:
       
  1446                 row["Duration"] = action["duration"]
       
  1447             else:
       
  1448                 row["Duration"] = ""
       
  1449             if "indicator" in action:
       
  1450                 row["Indicator"] = action["indicator"]
       
  1451             else:
       
  1452                 row["Indicator"] = ""
       
  1453             self.Table.AppendRow(row)
       
  1454         self.Table.ResetView(self.ActionsGrid)
       
  1455     
       
  1456     def GetValues(self):
       
  1457         values = []
       
  1458         for data in self.Table.GetData():
       
  1459             print data
       
  1460             action = {"qualifier" : data["Qualifier"], "value" : data["Value"]}
       
  1461             if data["Type"] in ["Action", "Variable"]:
       
  1462                 action["type"] = "reference"
       
  1463             else:
       
  1464                 action["type"] = "inline"
       
  1465             if data["Duration"] != "":
       
  1466                 action["duration"] = data["Duration"]
       
  1467             if data["Indicator"] != "":
       
  1468                 action["indicator"] = data["Indicator"]
       
  1469             values.append(action)
       
  1470         return values
       
  1471 
       
  1472 
       
  1473 #-------------------------------------------------------------------------------
       
  1474 #                          Edit Step Name Dialog
       
  1475 #-------------------------------------------------------------------------------
       
  1476 
       
  1477 class StepNameDialog(wxTextEntryDialog):
       
  1478 
       
  1479     def __init__(self, parent, message, caption = "Please enter text", defaultValue = "", 
       
  1480                        style = wxOK|wxCANCEL|wxCENTRE, pos = wxDefaultPosition):
       
  1481         wx.TextEntryDialog.__init__(self, parent, message, caption, defaultValue, style, pos)
       
  1482         
       
  1483         self.PouNames = []
       
  1484         self.Variables = []
       
  1485         self.StepNames = []
       
  1486         
       
  1487         EVT_BUTTON(self, self.GetSizer().GetItem(3).GetSizer().GetAffirmativeButton().GetId(), self.OnOK)
       
  1488         
       
  1489     def OnOK(self, event):
       
  1490         step_name = self.GetSizer().GetItem(1).GetWindow().GetValue()
       
  1491         if step_name == "":
       
  1492             message = wxMessageDialog(self, "You must type a name!", "Error", wxOK|wxICON_ERROR)
       
  1493             message.ShowModal()
       
  1494             message.Destroy()
       
  1495         elif not TestIdentifier(step_name):
       
  1496             message = wxMessageDialog(self, "\"%s\" is not a valid identifier!"%step_name, "Error", wxOK|wxICON_ERROR)
       
  1497             message.ShowModal()
       
  1498             message.Destroy()
       
  1499         elif step_name.upper() in IEC_KEYWORDS:
       
  1500             message = wxMessageDialog(self, "\"%s\" is a keyword. It can't be used!"%step_name, "Error", wxOK|wxICON_ERROR)
       
  1501             message.ShowModal()
       
  1502             message.Destroy()
       
  1503         elif step_name.upper() in self.PouNames:
       
  1504             message = wxMessageDialog(self, "A pou with \"%s\" as name exists!"%step_name, "Error", wxOK|wxICON_ERROR)
       
  1505             message.ShowModal()
       
  1506             message.Destroy()
       
  1507         elif step_name.upper() in self.Variables:
       
  1508             message = wxMessageDialog(self, "A variable with \"%s\" as name exists!"%step_name, "Error", wxOK|wxICON_ERROR)
       
  1509             message.ShowModal()
       
  1510             message.Destroy()
       
  1511         elif step_name.upper() in self.StepNames:
       
  1512             message = wxMessageDialog(self, "\"%s\" step already exists!"%step_name, "Error", wxOK|wxICON_ERROR)
       
  1513             message.ShowModal()
       
  1514             message.Destroy()
       
  1515         else:
       
  1516             self.EndModal(wxID_OK)
       
  1517 
       
  1518     def SetPouNames(self, pou_names):
       
  1519         self.PouNames = [pou_name.upper() for pou_name in pou_names]
       
  1520 
       
  1521     def SetVariables(self, variables):
       
  1522         self.Variables = [var["Name"].upper() for var in variables]
       
  1523 
       
  1524     def SetStepNames(self, step_names):
       
  1525         self.StepNames = [step_name.upper() for step_name in step_names]
       
  1526