Dialogs.py
changeset 409 34c9f624c2fe
parent 408 0e389fa5b160
child 410 e1d4e9a93186
equal deleted inserted replaced
408:0e389fa5b160 409:34c9f624c2fe
     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) 2007: 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 #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 import wx
       
    26 import wx.grid
       
    27 
       
    28 from graphics import *
       
    29 
       
    30 #-------------------------------------------------------------------------------
       
    31 #                          Create New Block Dialog
       
    32 #-------------------------------------------------------------------------------
       
    33 
       
    34 [ID_BLOCKPROPERTIESDIALOG, ID_BLOCKPROPERTIESDIALOGNAME, 
       
    35  ID_BLOCKPROPERTIESDIALOGTYPETREE, ID_BLOCKPROPERTIESDIALOGTYPEDESC, 
       
    36  ID_BLOCKPROPERTIESDIALOGINPUTS, ID_BLOCKPROPERTIESDIALOGPREVIEW, 
       
    37  ID_BLOCKPROPERTIESDIALOGEXECUTIONORDER, ID_BLOCKPROPERTIESDIALOGEXECUTIONCONTROL, 
       
    38  ID_BLOCKPROPERTIESDIALOGSTATICTEXT1, ID_BLOCKPROPERTIESDIALOGSTATICTEXT2, 
       
    39  ID_BLOCKPROPERTIESDIALOGSTATICTEXT3, ID_BLOCKPROPERTIESDIALOGSTATICTEXT4, 
       
    40  ID_BLOCKPROPERTIESDIALOGSTATICTEXT5, ID_BLOCKPROPERTIESDIALOGSTATICTEXT6, 
       
    41 ] = [wx.NewId() for _init_ctrls in range(14)]
       
    42 
       
    43 [CATEGORY, BLOCK] = range(2)
       
    44 
       
    45 class BlockPropertiesDialog(wx.Dialog):
       
    46     
       
    47     if wx.VERSION < (2, 6, 0):
       
    48         def Bind(self, event, function, id = None):
       
    49             if id is not None:
       
    50                 event(self, id, function)
       
    51             else:
       
    52                 event(self, function)
       
    53     
       
    54     def _init_coll_flexGridSizer1_Items(self, parent):
       
    55         parent.AddSizer(self.MainSizer, 0, border=20, flag=wx.GROW|wx.TOP|wx.LEFT|wx.RIGHT)
       
    56         parent.AddSizer(self.ButtonSizer, 0, border=20, flag=wx.ALIGN_RIGHT|wx.BOTTOM|wx.LEFT|wx.RIGHT)
       
    57 
       
    58     def _init_coll_flexGridSizer1_Growables(self, parent):
       
    59         parent.AddGrowableCol(0)
       
    60         parent.AddGrowableRow(0)
       
    61 
       
    62     def _init_coll_MainSizer_Items(self, parent):
       
    63         parent.AddSizer(self.LeftBoxSizer, 1, border=5, flag=wx.GROW|wx.RIGHT)
       
    64         parent.AddSizer(self.RightGridSizer, 1, border=5, flag=wx.GROW|wx.LEFT)
       
    65 
       
    66     def _init_coll_LeftBoxSizer_Items(self, parent):
       
    67         parent.AddWindow(self.TypeTree, 3, border=5, flag=wx.GROW|wx.BOTTOM)
       
    68         parent.AddWindow(self.TypeDesc, 1, border=0, flag=wx.GROW)
       
    69 
       
    70     def _init_coll_RightGridSizer_Items(self, parent):
       
    71         parent.AddSizer(self.RightUpGridSizer, 0, border=0, flag=wx.GROW)
       
    72         parent.AddWindow(self.staticText6, 0, border=0, flag=wx.GROW)
       
    73         parent.AddWindow(self.Preview, 0, border=0, flag=wx.GROW)
       
    74 
       
    75     def _init_coll_RightGridSizer_Growables(self, parent):
       
    76         parent.AddGrowableCol(0)
       
    77         parent.AddGrowableRow(2)
       
    78 
       
    79     def _init_coll_RightUpGridSizer_Items(self, parent):
       
    80         parent.AddWindow(self.staticText2, 0, border=4, flag=wx.ALIGN_CENTER_VERTICAL|wx.TOP)
       
    81         parent.AddWindow(self.BlockName, 0, border=0, flag=wx.GROW)
       
    82         parent.AddWindow(self.staticText3, 0, border=4, flag=wx.ALIGN_CENTER_VERTICAL|wx.TOP)
       
    83         parent.AddWindow(self.Inputs, 0, border=0, flag=wx.GROW)
       
    84         parent.AddWindow(self.staticText4, 0, border=4, flag=wx.ALIGN_CENTER_VERTICAL|wx.TOP)
       
    85         parent.AddWindow(self.ExecutionOrder, 0, border=0, flag=wx.GROW)
       
    86         parent.AddWindow(self.staticText5, 0, border=4, flag=wx.ALIGN_CENTER_VERTICAL|wx.TOP)
       
    87         parent.AddWindow(self.ExecutionControl, 0, border=0, flag=wx.GROW)
       
    88     
       
    89     def _init_coll_RightUpGridSizer_Growables(self, parent):
       
    90         parent.AddGrowableCol(1)
       
    91     
       
    92     def _init_sizers(self):
       
    93         self.flexGridSizer1 = wx.FlexGridSizer(cols=1, hgap=0, rows=2, vgap=10)
       
    94         self.MainSizer = wx.BoxSizer(wx.HORIZONTAL)
       
    95         self.LeftBoxSizer = wx.StaticBoxSizer(self.staticbox1, wx.VERTICAL)
       
    96         self.RightGridSizer = wx.FlexGridSizer(cols=1, hgap=0, rows=3, vgap=5)
       
    97         self.RightUpGridSizer = wx.FlexGridSizer(cols=2, hgap=5, rows=4, vgap=5)
       
    98         
       
    99         self._init_coll_flexGridSizer1_Items(self.flexGridSizer1)
       
   100         self._init_coll_flexGridSizer1_Growables(self.flexGridSizer1)
       
   101         self._init_coll_MainSizer_Items(self.MainSizer)
       
   102         self._init_coll_LeftBoxSizer_Items(self.LeftBoxSizer)
       
   103         self._init_coll_RightGridSizer_Items(self.RightGridSizer)
       
   104         self._init_coll_RightGridSizer_Growables(self.RightGridSizer)
       
   105         self._init_coll_RightUpGridSizer_Items(self.RightUpGridSizer)
       
   106         self._init_coll_RightUpGridSizer_Growables(self.RightUpGridSizer)
       
   107         
       
   108         self.SetSizer(self.flexGridSizer1)
       
   109 
       
   110     def _init_ctrls(self, prnt):
       
   111         wx.Dialog.__init__(self, id=ID_BLOCKPROPERTIESDIALOG,
       
   112               name='BlockPropertiesDialog', parent=prnt, pos=wx.Point(376, 223),
       
   113               size=wx.Size(600, 400), style=wx.DEFAULT_DIALOG_STYLE|wx.RESIZE_BORDER,
       
   114               title=_('Block Properties'))
       
   115         self.SetClientSize(wx.Size(600, 400))
       
   116 
       
   117         self.staticbox1 = wx.StaticBox(id=ID_BLOCKPROPERTIESDIALOGSTATICTEXT1,
       
   118               label=_('Type:'), name='staticBox1', parent=self,
       
   119               pos=wx.Point(0, 0), size=wx.Size(0, 0), style=0)
       
   120 
       
   121         self.staticText2 = wx.StaticText(id=ID_BLOCKPROPERTIESDIALOGSTATICTEXT2,
       
   122               label=_('Name:'), name='staticText2', parent=self,
       
   123               pos=wx.Point(0, 0), size=wx.DefaultSize, style=0)
       
   124 
       
   125         self.staticText3 = wx.StaticText(id=ID_BLOCKPROPERTIESDIALOGSTATICTEXT2,
       
   126               label=_('Inputs:'), name='staticText4', parent=self,
       
   127               pos=wx.Point(0, 0), size=wx.DefaultSize, style=0)
       
   128 
       
   129         self.staticText4 = wx.StaticText(id=ID_BLOCKPROPERTIESDIALOGSTATICTEXT4,
       
   130               label=_('Execution Order:'), name='staticText4', parent=self,
       
   131               pos=wx.Point(0, 0), size=wx.DefaultSize, style=0)
       
   132 
       
   133         self.staticText5 = wx.StaticText(id=ID_BLOCKPROPERTIESDIALOGSTATICTEXT5,
       
   134               label=_('Execution Control:'), name='staticText5', parent=self,
       
   135               pos=wx.Point(0, 0), size=wx.DefaultSize, style=0)
       
   136 
       
   137         self.staticText6 = wx.StaticText(id=ID_BLOCKPROPERTIESDIALOGSTATICTEXT6,
       
   138               label=_('Preview:'), name='staticText6', parent=self,
       
   139               pos=wx.Point(0, 0), size=wx.DefaultSize, style=0)
       
   140 
       
   141         if wx.Platform == '__WXMSW__':
       
   142             treestyle = wx.TR_HAS_BUTTONS|wx.TR_SINGLE|wx.SUNKEN_BORDER
       
   143         else:
       
   144             treestyle = wx.TR_HAS_BUTTONS|wx.TR_HIDE_ROOT|wx.TR_SINGLE|wx.SUNKEN_BORDER
       
   145         self.TypeTree = wx.TreeCtrl(id=ID_BLOCKPROPERTIESDIALOGTYPETREE,
       
   146               name='TypeTree', parent=self, pos=wx.Point(0, 0),
       
   147               size=wx.Size(0, 0), style=treestyle)
       
   148         self.Bind(wx.EVT_TREE_SEL_CHANGED, self.OnTypeTreeItemSelected,
       
   149               id=ID_BLOCKPROPERTIESDIALOGTYPETREE)
       
   150 
       
   151         self.TypeDesc = wx.TextCtrl(id=ID_BLOCKPROPERTIESDIALOGTYPEDESC,
       
   152               name='TypeDesc', parent=self, pos=wx.Point(0, 0),
       
   153               size=wx.Size(0, 0), style=wx.TE_READONLY|wx.TE_MULTILINE)
       
   154 
       
   155         self.BlockName = wx.TextCtrl(id=ID_BLOCKPROPERTIESDIALOGNAME, value='',
       
   156               name='BlockName', parent=self, pos=wx.Point(0, 0),
       
   157               size=wx.Size(0, 24), style=0)
       
   158         self.Bind(wx.EVT_TEXT, self.OnNameChanged, id=ID_BLOCKPROPERTIESDIALOGNAME)
       
   159 
       
   160         self.Inputs = wx.SpinCtrl(id=ID_BLOCKPROPERTIESDIALOGINPUTS,
       
   161               name='Inputs', parent=self, pos=wx.Point(0, 0),
       
   162               size=wx.Size(0, 24), style=wx.SP_ARROW_KEYS, min=2, max=20)
       
   163         self.Bind(wx.EVT_SPINCTRL, self.OnInputsChanged, id=ID_BLOCKPROPERTIESDIALOGINPUTS)
       
   164 
       
   165         self.ExecutionOrder = wx.SpinCtrl(id=ID_BLOCKPROPERTIESDIALOGEXECUTIONORDER,
       
   166               name='ExecutionOrder', parent=self, pos=wx.Point(0, 0),
       
   167               size=wx.Size(0, 24), style=wx.SP_ARROW_KEYS, min=0)
       
   168         self.Bind(wx.EVT_SPINCTRL, self.OnExecutionOrderChanged, id=ID_BLOCKPROPERTIESDIALOGEXECUTIONORDER)
       
   169 
       
   170         self.ExecutionControl = wx.CheckBox(id=ID_BLOCKPROPERTIESDIALOGEXECUTIONCONTROL,
       
   171               name='ExecutionControl', parent=self, pos=wx.Point(0, 0),
       
   172               size=wx.Size(0, 24), style=0)
       
   173         self.Bind(wx.EVT_CHECKBOX, self.OnExecutionOrderChanged, id=ID_BLOCKPROPERTIESDIALOGEXECUTIONCONTROL)
       
   174 
       
   175         self.Preview = wx.Panel(id=ID_BLOCKPROPERTIESDIALOGPREVIEW,
       
   176               name='Preview', parent=self, pos=wx.Point(0, 0),
       
   177               size=wx.Size(0, 0), style=wx.TAB_TRAVERSAL|wx.SIMPLE_BORDER)
       
   178         self.Preview.SetBackgroundColour(wx.Colour(255,255,255))
       
   179         setattr(self.Preview, "GetDrawingMode", lambda:FREEDRAWING_MODE)
       
   180         setattr(self.Preview, "GetScaling", lambda:None)
       
   181         setattr(self.Preview, "GetBlockType", self.Controler.GetBlockType)
       
   182         setattr(self.Preview, "IsOfType", self.Controler.IsOfType)
       
   183 
       
   184         self.ButtonSizer = self.CreateButtonSizer(wx.OK|wx.CANCEL|wx.CENTRE)
       
   185         if wx.VERSION >= (2, 5, 0):
       
   186             self.Bind(wx.EVT_BUTTON, self.OnOK, id=self.ButtonSizer.GetAffirmativeButton().GetId())
       
   187             self.Preview.Bind(wx.EVT_PAINT, self.OnPaint)
       
   188         else:
       
   189             self.Bind(wx.EVT_BUTTON, self.OnOK, id=self.ButtonSizer.GetChildren()[0].GetSizer().GetChildren()[0].GetWindow().GetId())
       
   190             wx.EVT_PAINT(self.Preview, self.OnPaint)
       
   191         
       
   192         self._init_sizers()
       
   193 
       
   194     def __init__(self, parent, controler):
       
   195         self.Controler = controler
       
   196         self._init_ctrls(parent)
       
   197         self.BlockName.SetValue("")
       
   198         self.BlockName.Enable(False)
       
   199         self.Inputs.Enable(False)
       
   200         self.Block = None
       
   201         self.MinBlockSize = None
       
   202         self.First = True
       
   203         
       
   204         self.PouNames = []
       
   205         self.PouElementNames = []
       
   206     
       
   207     def SetPreviewFont(self, font):
       
   208         self.Preview.SetFont(font)
       
   209     
       
   210     def FindTreeItem(self, root, name, inputs = None):
       
   211         if root.IsOk():
       
   212             pydata = self.TypeTree.GetPyData(root)
       
   213             type_inputs = pydata.get("inputs", None)
       
   214             type_extension = pydata.get("extension", None)
       
   215             if inputs is not None and type_inputs is not None:
       
   216                 if type_extension is not None:
       
   217                     same_inputs = type_inputs == inputs[:type_extension]
       
   218                 else:
       
   219                     same_inputs = type_inputs == inputs
       
   220             else:
       
   221                 same_inputs = True
       
   222             if self.TypeTree.GetItemText(root) == name and same_inputs:
       
   223                 return root
       
   224             else:
       
   225                 if wx.VERSION < (2, 6, 0):
       
   226                     item, root_cookie = self.TypeTree.GetFirstChild(root, 0)
       
   227                 else:
       
   228                     item, root_cookie = self.TypeTree.GetFirstChild(root)
       
   229                 while item.IsOk():
       
   230                     result = self.FindTreeItem(item, name, inputs)
       
   231                     if result:
       
   232                         return result
       
   233                     item, root_cookie = self.TypeTree.GetNextChild(root, root_cookie)
       
   234         return None
       
   235     
       
   236     def OnOK(self, event):
       
   237         selected = self.TypeTree.GetSelection()
       
   238         block_name = self.BlockName.GetValue()
       
   239         name_enabled = self.BlockName.IsEnabled()
       
   240         if not selected.IsOk() or self.TypeTree.GetItemParent(selected) == self.TypeTree.GetRootItem() or selected == self.TypeTree.GetRootItem():
       
   241             message = wx.MessageDialog(self, _("Form isn't complete. Valid block type must be selected!"), _("Error"), wx.OK|wx.ICON_ERROR)
       
   242             message.ShowModal()
       
   243             message.Destroy()
       
   244         elif name_enabled and block_name == "":
       
   245             message = wx.MessageDialog(self, _("Form isn't complete. Name must be filled!"), _("Error"), wx.OK|wx.ICON_ERROR)
       
   246             message.ShowModal()
       
   247             message.Destroy()
       
   248         elif name_enabled and not TestIdentifier(block_name):
       
   249             message = wx.MessageDialog(self, _("\"%s\" is not a valid identifier!")%block_name, _("Error"), wx.OK|wx.ICON_ERROR)
       
   250             message.ShowModal()
       
   251             message.Destroy()
       
   252         elif name_enabled and block_name.upper() in IEC_KEYWORDS:
       
   253             message = wx.MessageDialog(self, _("\"%s\" is a keyword. It can't be used!")%block_name, _("Error"), wx.OK|wx.ICON_ERROR)
       
   254             message.ShowModal()
       
   255             message.Destroy()
       
   256         elif name_enabled and block_name.upper() in self.PouNames:
       
   257             message = wx.MessageDialog(self, _("\"%s\" pou already exists!")%block_name, _("Error"), wx.OK|wx.ICON_ERROR)
       
   258             message.ShowModal()
       
   259             message.Destroy()
       
   260         elif name_enabled and block_name.upper() in self.PouElementNames:
       
   261             message = wx.MessageDialog(self, _("\"%s\" element for this pou already exists!")%block_name, _("Error"), wx.OK|wx.ICON_ERROR)
       
   262             message.ShowModal()
       
   263             message.Destroy()
       
   264         else:
       
   265             self.EndModal(wx.ID_OK)
       
   266 
       
   267     def SetBlockList(self, blocktypes):
       
   268         if wx.Platform == '__WXMSW__':
       
   269             root = self.TypeTree.AddRoot(_("Block Types"))
       
   270         else:
       
   271             root = self.TypeTree.AddRoot("")
       
   272         self.TypeTree.SetPyData(root, {"type" : CATEGORY})
       
   273         for category in blocktypes:
       
   274             category_name = category["name"]
       
   275             category_item = self.TypeTree.AppendItem(root, _(category_name))
       
   276             self.TypeTree.SetPyData(category_item, {"type" : CATEGORY})
       
   277             for blocktype in category["list"]:
       
   278                 blocktype_item = self.TypeTree.AppendItem(category_item, blocktype["name"])
       
   279                 block_data = {"type" : BLOCK, 
       
   280                               "inputs" : tuple([type for name, type, modifier in blocktype["inputs"]]),
       
   281                               "extension" : None}
       
   282                 if blocktype["extensible"]:
       
   283                     block_data["extension"] = len(blocktype["inputs"])
       
   284                 self.TypeTree.SetPyData(blocktype_item, block_data)
       
   285         if wx.Platform == '__WXMSW__':
       
   286             self.TypeTree.Expand(root)
       
   287 
       
   288     def SetMinBlockSize(self, size):
       
   289         self.MinBlockSize = size
       
   290 
       
   291     def SetPouNames(self, pou_names):
       
   292         self.PouNames = [pou_name.upper() for pou_name in pou_names]
       
   293         
       
   294     def SetPouElementNames(self, element_names):
       
   295         self.PouElementNames = [element_name.upper() for element_name in element_names]
       
   296         
       
   297     def SetValues(self, values):
       
   298         blocktype = values.get("type", None)
       
   299         if blocktype is not None:
       
   300             inputs = values.get("inputs", None)
       
   301             item = self.FindTreeItem(self.TypeTree.GetRootItem(), blocktype, inputs)
       
   302             if item:
       
   303                 self.TypeTree.SelectItem(item)
       
   304         for name, value in values.items():
       
   305             if name == "name":
       
   306                 self.BlockName.SetValue(value)
       
   307             elif name == "extension":
       
   308                 self.Inputs.SetValue(value)
       
   309             elif name == "executionOrder":
       
   310                 self.ExecutionOrder.SetValue(value)
       
   311             elif name == "executionControl":
       
   312            	    self.ExecutionControl.SetValue(value)
       
   313         self.RefreshPreview()
       
   314 
       
   315     def GetValues(self):
       
   316         values = {}
       
   317         item = self.TypeTree.GetSelection()
       
   318         values["type"] = self.TypeTree.GetItemText(item)
       
   319         values["inputs"] = self.TypeTree.GetPyData(item)["inputs"]
       
   320         if self.BlockName.GetValue() != "":
       
   321             values["name"] = self.BlockName.GetValue()
       
   322         values["width"], values["height"] = self.Block.GetSize()
       
   323         values["extension"] = self.Inputs.GetValue()
       
   324         values["executionOrder"] = self.ExecutionOrder.GetValue()
       
   325         values["executionControl"] = self.ExecutionControl.GetValue()
       
   326         return values
       
   327 
       
   328     def OnTypeTreeItemSelected(self, event):
       
   329         self.BlockName.SetValue("")
       
   330         selected = event.GetItem()
       
   331         pydata = self.TypeTree.GetPyData(selected)
       
   332         if pydata["type"] != CATEGORY:
       
   333             blocktype = self.Controler.GetBlockType(self.TypeTree.GetItemText(selected), pydata["inputs"])
       
   334             if blocktype:
       
   335                 self.Inputs.SetValue(len(blocktype["inputs"]))
       
   336                 self.Inputs.Enable(blocktype["extensible"])
       
   337                 self.BlockName.Enable(blocktype["type"] != "function")
       
   338                 comment = blocktype["comment"]
       
   339                 self.TypeDesc.SetValue(_(comment) + blocktype.get("usage", ""))
       
   340                 wx.CallAfter(self.RefreshPreview)
       
   341             else:
       
   342                 self.BlockName.Enable(False)
       
   343                 self.Inputs.Enable(False)
       
   344                 self.Inputs.SetValue(2)
       
   345                 self.TypeDesc.SetValue("")
       
   346                 wx.CallAfter(self.ErasePreview)
       
   347         else:
       
   348             self.BlockName.Enable(False)
       
   349             self.Inputs.Enable(False)
       
   350             self.Inputs.SetValue(2)
       
   351             self.TypeDesc.SetValue("")
       
   352             wx.CallAfter(self.ErasePreview)
       
   353         event.Skip()
       
   354 
       
   355     def OnNameChanged(self, event):
       
   356         if self.BlockName.IsEnabled():
       
   357             self.RefreshPreview()
       
   358         event.Skip()
       
   359     
       
   360     def OnInputsChanged(self, event):
       
   361         if self.Inputs.IsEnabled():
       
   362             self.RefreshPreview()
       
   363         event.Skip()
       
   364     
       
   365     def OnExecutionOrderChanged(self, event):
       
   366         self.RefreshPreview()
       
   367         event.Skip()
       
   368     
       
   369     def OnExecutionControlChanged(self, event):
       
   370         self.RefreshPreview()
       
   371         event.Skip()
       
   372     
       
   373     def ErasePreview(self):
       
   374         dc = wx.ClientDC(self.Preview)
       
   375         dc.Clear()
       
   376         self.Block = None
       
   377         
       
   378     def RefreshPreview(self):
       
   379         dc = wx.ClientDC(self.Preview)
       
   380         dc.SetFont(self.Preview.GetFont())
       
   381         dc.Clear()
       
   382         item = self.TypeTree.GetSelection()
       
   383         if item.IsOk():
       
   384             pydata = self.TypeTree.GetPyData(item)
       
   385             if pydata["type"] == CATEGORY:
       
   386                 self.Block = None
       
   387             else:
       
   388                 blocktype = self.TypeTree.GetItemText(item)
       
   389                 if blocktype:
       
   390                     self.Block = FBD_Block(self.Preview, blocktype, 
       
   391                             self.BlockName.GetValue(), 
       
   392                             extension = self.Inputs.GetValue(), 
       
   393                             inputs = pydata["inputs"], 
       
   394                             executionControl = self.ExecutionControl.GetValue(), 
       
   395                             executionOrder = self.ExecutionOrder.GetValue())
       
   396                     width, height = self.MinBlockSize
       
   397                     min_width, min_height = self.Block.GetMinSize()
       
   398                     width, height = max(min_width, width), max(min_height, height)
       
   399                     self.Block.SetSize(width, height)
       
   400                     clientsize = self.Preview.GetClientSize()
       
   401                     x = (clientsize.width - width) / 2
       
   402                     y = (clientsize.height - height) / 2
       
   403                     self.Block.SetPosition(x, y)
       
   404                     self.Block.Draw(dc)
       
   405                 else:
       
   406                     self.Block = None
       
   407 
       
   408     def OnPaint(self, event):
       
   409         if self.Block is not None:
       
   410             self.RefreshPreview()
       
   411         event.Skip()
       
   412 
       
   413 #-------------------------------------------------------------------------------
       
   414 #                          Create New Variable Dialog
       
   415 #-------------------------------------------------------------------------------
       
   416 
       
   417 [ID_VARIABLEPROPERTIESDIALOG, ID_VARIABLEPROPERTIESDIALOGSPACER, 
       
   418  ID_VARIABLEPROPERTIESDIALOGNAME, ID_VARIABLEPROPERTIESDIALOGCLASS, 
       
   419  ID_VARIABLEPROPERTIESDIALOGPREVIEW, ID_VARIABLEPROPERTIESDIALOGEXPRESSION,
       
   420  ID_VARIABLEPROPERTIESDIALOGEXECUTIONORDER, ID_VARIABLEPROPERTIESDIALOGSTATICTEXT1, 
       
   421  ID_VARIABLEPROPERTIESDIALOGSTATICTEXT2, ID_VARIABLEPROPERTIESDIALOGSTATICTEXT3, 
       
   422  ID_VARIABLEPROPERTIESDIALOGSTATICTEXT4, ID_VARIABLEPROPERTIESDIALOGSTATICTEXT5
       
   423 ] = [wx.NewId() for _init_ctrls in range(12)]
       
   424 
       
   425 VARIABLE_CLASSES_DICT = {INPUT : _("Input"),
       
   426                          INOUT : _("InOut"),
       
   427                          OUTPUT : _("Output")}
       
   428 VARIABLE_CLASSES_DICT_REVERSE = dict([(value, key) for key, value in VARIABLE_CLASSES_DICT.iteritems()])
       
   429 
       
   430 class VariablePropertiesDialog(wx.Dialog):
       
   431     
       
   432     if wx.VERSION < (2, 6, 0):
       
   433         def Bind(self, event, function, id = None):
       
   434             if id is not None:
       
   435                 event(self, id, function)
       
   436             else:
       
   437                 event(self, function)
       
   438     
       
   439     def _init_coll_flexGridSizer1_Items(self, parent):
       
   440         parent.AddSizer(self.MainSizer, 0, border=20, flag=wx.GROW|wx.TOP|wx.LEFT|wx.RIGHT)
       
   441         parent.AddSizer(self.ButtonSizer, 0, border=20, flag=wx.ALIGN_RIGHT|wx.BOTTOM|wx.LEFT|wx.RIGHT)
       
   442         
       
   443     def _init_coll_flexGridSizer1_Growables(self, parent):
       
   444         parent.AddGrowableCol(0)
       
   445         parent.AddGrowableRow(0)
       
   446     
       
   447     def _init_coll_MainSizer_Items(self, parent):
       
   448         parent.AddSizer(self.TopSizer, 0, border=0, flag=wx.GROW)
       
   449         parent.AddWindow(self.staticText5, 0, border=0, flag=wx.GROW)
       
   450         parent.AddWindow(self.Preview, 0, border=0, flag=wx.GROW)
       
   451         
       
   452     def _init_coll_MainSizer_Growables(self, parent):
       
   453         parent.AddGrowableCol(0)
       
   454         parent.AddGrowableRow(2)
       
   455     
       
   456     def _init_coll_TopSizer_Items(self, parent):
       
   457         parent.AddSizer(self.LeftGridSizer, 1, border=5, flag=wx.GROW|wx.RIGHT)
       
   458         parent.AddSizer(self.RightGridSizer, 1, border=5, flag=wx.GROW|wx.LEFT)
       
   459     
       
   460     def _init_coll_LeftGridSizer_Items(self, parent):
       
   461         parent.AddWindow(self.staticText1, 0, border=0, flag=wx.GROW)
       
   462         parent.AddWindow(self.Class, 0, border=0, flag=wx.GROW)
       
   463         parent.AddWindow(self.staticText2, 0, border=0, flag=wx.GROW)
       
   464         parent.AddWindow(self.Expression, 0, border=0, flag=wx.GROW)
       
   465         parent.AddWindow(self.staticText3, 0, border=0, flag=wx.GROW)
       
   466         parent.AddWindow(self.ExecutionOrder, 0, border=0, flag=wx.GROW)
       
   467         parent.AddWindow(self.Spacer, 0, border=0, flag=wx.GROW)
       
   468     
       
   469     def _init_coll_LeftGridSizer_Growables(self, parent):
       
   470         parent.AddGrowableCol(0)
       
   471         parent.AddGrowableRow(2)
       
   472             
       
   473     def _init_coll_RightGridSizer_Items(self, parent):
       
   474         parent.AddWindow(self.staticText4, 0, border=0, flag=wx.GROW)
       
   475         parent.AddWindow(self.VariableName, 0, border=0, flag=wx.GROW)
       
   476         
       
   477     def _init_coll_RightGridSizer_Growables(self, parent):
       
   478         parent.AddGrowableCol(0)
       
   479         parent.AddGrowableRow(1)
       
   480         
       
   481     def _init_sizers(self):
       
   482         self.flexGridSizer1 = wx.FlexGridSizer(cols=1, hgap=0, rows=2, vgap=10)
       
   483         self.MainSizer = wx.FlexGridSizer(cols=1, hgap=0, rows=3, vgap=5)
       
   484         self.TopSizer = wx.BoxSizer(wx.HORIZONTAL)
       
   485         self.LeftGridSizer = wx.FlexGridSizer(cols=1, hgap=0, rows=7, vgap=5)
       
   486         self.RightGridSizer = wx.FlexGridSizer(cols=1, hgap=0, rows=2, vgap=5)
       
   487 
       
   488         self._init_coll_flexGridSizer1_Items(self.flexGridSizer1)
       
   489         self._init_coll_flexGridSizer1_Growables(self.flexGridSizer1)
       
   490         self._init_coll_MainSizer_Items(self.MainSizer)
       
   491         self._init_coll_MainSizer_Growables(self.MainSizer)
       
   492         self._init_coll_TopSizer_Items(self.TopSizer)
       
   493         self._init_coll_LeftGridSizer_Items(self.LeftGridSizer)
       
   494         self._init_coll_LeftGridSizer_Growables(self.LeftGridSizer)
       
   495         self._init_coll_RightGridSizer_Items(self.RightGridSizer)
       
   496         self._init_coll_RightGridSizer_Growables(self.RightGridSizer)
       
   497         
       
   498         self.SetSizer(self.flexGridSizer1)
       
   499 
       
   500     def _init_ctrls(self, prnt, ctrler):
       
   501         wx.Dialog.__init__(self, id=ID_VARIABLEPROPERTIESDIALOG,
       
   502               name='VariablePropertiesDialog', parent=prnt, pos=wx.Point(376, 223),
       
   503               size=wx.Size(400, 380), style=wx.DEFAULT_DIALOG_STYLE,
       
   504               title=_('Variable Properties'))
       
   505         self.SetClientSize(wx.Size(400, 380))
       
   506 
       
   507         self.staticText1 = wx.StaticText(id=ID_VARIABLEPROPERTIESDIALOGSTATICTEXT1,
       
   508               label=_('Class:'), name='staticText1', parent=self,
       
   509               pos=wx.Point(0, 0), size=wx.Size(0, 17), style=0)
       
   510 
       
   511         self.staticText2 = wx.StaticText(id=ID_VARIABLEPROPERTIESDIALOGSTATICTEXT2,
       
   512               label=_('Expression:'), name='staticText2', parent=self,
       
   513               pos=wx.Point(0, 0), size=wx.Size(0, 17), style=0)
       
   514 
       
   515         self.staticText3 = wx.StaticText(id=ID_VARIABLEPROPERTIESDIALOGSTATICTEXT3,
       
   516               label=_('Execution Order:'), name='staticText3', parent=self,
       
   517               pos=wx.Point(0, 0), size=wx.Size(0, 17), style=0)
       
   518 
       
   519         self.staticText4 = wx.StaticText(id=ID_VARIABLEPROPERTIESDIALOGSTATICTEXT4,
       
   520               label=_('Name:'), name='staticText4', parent=self,
       
   521               pos=wx.Point(0, 0), size=wx.Size(0, 17), style=0)
       
   522 
       
   523         self.staticText5 = wx.StaticText(id=ID_VARIABLEPROPERTIESDIALOGSTATICTEXT5,
       
   524               label=_('Preview:'), name='staticText5', parent=self,
       
   525               pos=wx.Point(0, 0), size=wx.Size(0, 17), style=0)
       
   526 
       
   527         self.Class = wx.ComboBox(id=ID_VARIABLEPROPERTIESDIALOGCLASS,
       
   528               name='Class', parent=self, pos=wx.Point(0, 0),
       
   529               size=wx.Size(0, 28), style=wx.CB_READONLY)
       
   530         self.Bind(wx.EVT_COMBOBOX, self.OnClassChanged, id=ID_VARIABLEPROPERTIESDIALOGCLASS)
       
   531         
       
   532         self.VariableName = wx.ListBox(id=ID_VARIABLEPROPERTIESDIALOGNAME,
       
   533               name='Name', parent=self, pos=wx.Point(0, 0),
       
   534               size=wx.Size(0, 90), style=wx.LB_SINGLE|wx.LB_SORT)
       
   535         self.Bind(wx.EVT_LISTBOX, self.OnNameChanged, id=ID_VARIABLEPROPERTIESDIALOGNAME)
       
   536 
       
   537         self.Expression = wx.TextCtrl(id=ID_VARIABLEPROPERTIESDIALOGEXPRESSION,
       
   538               name='Expression', parent=self, pos=wx.Point(0, 0),
       
   539               size=wx.Size(0, 24), style=0)
       
   540         self.Bind(wx.EVT_TEXT, self.OnExpressionChanged, id=ID_VARIABLEPROPERTIESDIALOGEXPRESSION)
       
   541 
       
   542         self.ExecutionOrder = wx.SpinCtrl(id=ID_VARIABLEPROPERTIESDIALOGEXECUTIONORDER,
       
   543               name='ExecutionOrder', parent=self, pos=wx.Point(0, 0),
       
   544               size=wx.Size(0, 24), style=wx.SP_ARROW_KEYS, min=0)
       
   545         self.Bind(wx.EVT_SPINCTRL, self.OnExecutionOrderChanged, id=ID_VARIABLEPROPERTIESDIALOGEXECUTIONORDER)
       
   546 
       
   547         self.Spacer = wx.Panel(id=ID_VARIABLEPROPERTIESDIALOGSPACER,
       
   548               name='Spacer', parent=self, pos=wx.Point(0, 0),
       
   549               size=wx.Size(0, 0), style=wx.TAB_TRAVERSAL)
       
   550 
       
   551         self.Preview = wx.Panel(id=ID_VARIABLEPROPERTIESDIALOGPREVIEW,
       
   552               name='Preview', parent=self, pos=wx.Point(0, 0),
       
   553               size=wx.Size(0, 0), style=wx.TAB_TRAVERSAL|wx.SIMPLE_BORDER)
       
   554         self.Preview.SetBackgroundColour(wx.Colour(255,255,255))
       
   555         setattr(self.Preview, "GetDrawingMode", lambda:FREEDRAWING_MODE)
       
   556         setattr(self.Preview, "GetScaling", lambda:None)
       
   557         setattr(self.Preview, "IsOfType", ctrler.IsOfType)
       
   558 
       
   559         self.ButtonSizer = self.CreateButtonSizer(wx.OK|wx.CANCEL|wx.CENTRE)
       
   560         if wx.VERSION >= (2, 5, 0):
       
   561             self.Bind(wx.EVT_BUTTON, self.OnOK, id=self.ButtonSizer.GetAffirmativeButton().GetId())
       
   562             self.Preview.Bind(wx.EVT_PAINT, self.OnPaint)
       
   563         else:
       
   564             self.Bind(wx.EVT_BUTTON, self.OnOK, id=self.ButtonSizer.GetChildren()[0].GetSizer().GetChildren()[0].GetWindow().GetId())
       
   565             wx.EVT_PAINT(self.Preview, self.OnPaint)
       
   566         
       
   567         self._init_sizers()
       
   568 
       
   569     def __init__(self, parent, controler, transition = ""):
       
   570         self._init_ctrls(parent, controler)
       
   571         self.Transition = transition
       
   572         self.Variable = None
       
   573         self.VarList = []
       
   574         self.MinVariableSize = None
       
   575         
       
   576         for choice in VARIABLE_CLASSES_DICT.itervalues():
       
   577             self.Class.Append(choice)
       
   578         self.Class.SetStringSelection(VARIABLE_CLASSES_DICT[INPUT])
       
   579 
       
   580         self.RefreshNameList()
       
   581 
       
   582     def SetPreviewFont(self, font):
       
   583         self.Preview.SetFont(font)
       
   584 
       
   585     def RefreshNameList(self):
       
   586         selected = self.VariableName.GetStringSelection()
       
   587         var_class = VARIABLE_CLASSES_DICT_REVERSE[self.Class.GetStringSelection()]
       
   588         self.VariableName.Clear()
       
   589         self.VariableName.Append("")
       
   590         for name, var_type, value_type in self.VarList:
       
   591             if var_type != "Input" or var_class == INPUT:
       
   592                 self.VariableName.Append(name)
       
   593         if selected != "" and self.VariableName.FindString(selected) != wx.NOT_FOUND:
       
   594             self.VariableName.SetStringSelection(selected)
       
   595             self.Expression.Enable(False)
       
   596         else:
       
   597             self.VariableName.SetStringSelection("")
       
   598             self.Expression.Enable(var_class == INPUT)
       
   599         self.VariableName.Enable(self.VariableName.GetCount() > 0)
       
   600             
       
   601     def SetMinVariableSize(self, size):
       
   602         self.MinVariableSize = size
       
   603 
       
   604     def SetVariables(self, vars):
       
   605         self.VarList = vars
       
   606         self.RefreshNameList()
       
   607 
       
   608     def SetValues(self, values):
       
   609         value_type = values.get("type", None)
       
   610         value_name = values.get("name", None)
       
   611         if value_type:
       
   612             self.Class.SetStringSelection(VARIABLE_CLASSES_DICT[value_type])
       
   613             self.RefreshNameList()
       
   614         if value_name:
       
   615             if self.VariableName.FindString(value_name) != wx.NOT_FOUND:
       
   616                 self.VariableName.SetStringSelection(value_name)
       
   617                 self.Expression.Enable(False)
       
   618             else:
       
   619                 self.Expression.SetValue(value_name)
       
   620                 self.VariableName.Enable(False)
       
   621         if "executionOrder" in values:
       
   622             self.ExecutionOrder.SetValue(values["executionOrder"])
       
   623         self.RefreshPreview()
       
   624         
       
   625     def GetValues(self):
       
   626         values = {}
       
   627         values["type"] = VARIABLE_CLASSES_DICT_REVERSE[self.Class.GetStringSelection()]
       
   628         expression = self.Expression.GetValue()
       
   629         if self.Expression.IsEnabled() and expression != "":
       
   630             values["name"] = expression
       
   631         else:
       
   632             values["name"] = self.VariableName.GetStringSelection()
       
   633         values["value_type"] = None
       
   634         for var_name, var_type, value_type in self.VarList:
       
   635             if var_name == values["name"]:
       
   636                 values["value_type"] = value_type
       
   637         values["width"], values["height"] = self.Variable.GetSize()
       
   638         values["executionOrder"] = self.ExecutionOrder.GetValue()
       
   639         return values
       
   640 
       
   641     def OnOK(self, event):
       
   642         expression = self.Expression.GetValue()
       
   643         if self.Expression.IsEnabled():
       
   644             value = expression
       
   645         else:
       
   646             value = self.VariableName.GetStringSelection()
       
   647         if value == "":
       
   648             message = wx.MessageDialog(self, _("At least a variable or an expression must be selected!"), _("Error"), wx.OK|wx.ICON_ERROR)
       
   649             message.ShowModal()
       
   650             message.Destroy()
       
   651         elif value.upper() in IEC_KEYWORDS:
       
   652             message = wx.MessageDialog(self, _("\"%s\" is a keyword. It can't be used!")%value, _("Error"), wx.OK|wx.ICON_ERROR)
       
   653             message.ShowModal()
       
   654             message.Destroy()
       
   655         else:
       
   656             self.EndModal(wx.ID_OK)
       
   657 
       
   658     def OnClassChanged(self, event):
       
   659         self.RefreshNameList()
       
   660         self.RefreshPreview()
       
   661         event.Skip()
       
   662 
       
   663     def OnNameChanged(self, event):
       
   664         if self.VariableName.GetStringSelection() != "":
       
   665             self.Expression.Enable(False)
       
   666         elif VARIABLE_CLASSES_DICT_REVERSE[self.Class.GetStringSelection()] == INPUT:
       
   667             self.Expression.Enable(True)
       
   668         self.RefreshPreview()
       
   669         event.Skip()
       
   670     
       
   671     def OnExpressionChanged(self, event):
       
   672         if self.Expression.GetValue() != "":
       
   673             self.VariableName.Enable(False)
       
   674         else:
       
   675             self.VariableName.Enable(True)
       
   676         self.RefreshPreview()
       
   677         event.Skip()
       
   678     
       
   679     def OnExecutionOrderChanged(self, event):
       
   680         self.RefreshPreview()
       
   681         event.Skip()
       
   682     
       
   683     def RefreshPreview(self):
       
   684         dc = wx.ClientDC(self.Preview)
       
   685         dc.SetFont(self.Preview.GetFont())
       
   686         dc.Clear()
       
   687         expression = self.Expression.GetValue()
       
   688         if self.Expression.IsEnabled() and expression != "":
       
   689             name = expression
       
   690         else:
       
   691             name = self.VariableName.GetStringSelection()
       
   692         type = ""
       
   693         for var_name, var_type, value_type in self.VarList:
       
   694             if var_name == name:
       
   695                 type = value_type
       
   696         classtype = VARIABLE_CLASSES_DICT_REVERSE[self.Class.GetStringSelection()]
       
   697         self.Variable = FBD_Variable(self.Preview, classtype, name, type, executionOrder = self.ExecutionOrder.GetValue())
       
   698         width, height = self.MinVariableSize
       
   699         min_width, min_height = self.Variable.GetMinSize()
       
   700         width, height = max(min_width, width), max(min_height, height)
       
   701         self.Variable.SetSize(width, height)
       
   702         clientsize = self.Preview.GetClientSize()
       
   703         x = (clientsize.width - width) / 2
       
   704         y = (clientsize.height - height) / 2
       
   705         self.Variable.SetPosition(x, y)
       
   706         self.Variable.Draw(dc)
       
   707 
       
   708     def OnPaint(self, event):
       
   709         self.RefreshPreview()
       
   710         event.Skip()
       
   711 
       
   712 #-------------------------------------------------------------------------------
       
   713 #                          Create New Connection Dialog
       
   714 #-------------------------------------------------------------------------------
       
   715 
       
   716 [ID_CONNECTIONPROPERTIESDIALOG, ID_CONNECTIONPROPERTIESDIALOGSPACER, 
       
   717  ID_CONNECTIONPROPERTIESDIALOGNAME, ID_CONNECTIONPROPERTIESDIALOGRADIOBUTTON1, 
       
   718  ID_CONNECTIONPROPERTIESDIALOGRADIOBUTTON2, ID_CONNECTIONPROPERTIESDIALOGPREVIEW,
       
   719  ID_CONNECTIONPROPERTIESDIALOGSTATICTEXT1, ID_CONNECTIONPROPERTIESDIALOGSTATICTEXT2, 
       
   720  ID_CONNECTIONPROPERTIESDIALOGSTATICTEXT3, 
       
   721 ] = [wx.NewId() for _init_ctrls in range(9)]
       
   722 
       
   723 class ConnectionPropertiesDialog(wx.Dialog):
       
   724     
       
   725     if wx.VERSION < (2, 6, 0):
       
   726         def Bind(self, event, function, id = None):
       
   727             if id is not None:
       
   728                 event(self, id, function)
       
   729             else:
       
   730                 event(self, function)
       
   731     
       
   732     def _init_coll_flexGridSizer1_Items(self, parent):
       
   733         parent.AddSizer(self.MainSizer, 0, border=20, flag=wx.GROW|wx.TOP|wx.LEFT|wx.RIGHT)
       
   734         parent.AddSizer(self.ButtonSizer, 0, border=20, flag=wx.ALIGN_RIGHT|wx.BOTTOM|wx.LEFT|wx.RIGHT)
       
   735         
       
   736     def _init_coll_flexGridSizer1_Growables(self, parent):
       
   737         parent.AddGrowableCol(0)
       
   738         parent.AddGrowableRow(0)
       
   739     
       
   740     def _init_coll_MainSizer_Items(self, parent):
       
   741         parent.AddSizer(self.LeftGridSizer, 1, border=5, flag=wx.GROW|wx.RIGHT)
       
   742         parent.AddSizer(self.RightGridSizer, 1, border=5, flag=wx.GROW|wx.LEFT)
       
   743     
       
   744     def _init_coll_LeftGridSizer_Items(self, parent):
       
   745         parent.AddWindow(self.staticText1, 0, border=0, flag=wx.GROW)
       
   746         parent.AddWindow(self.radioButton1, 0, border=0, flag=wx.GROW)
       
   747         parent.AddWindow(self.radioButton2, 0, border=0, flag=wx.GROW)
       
   748         parent.AddWindow(self.staticText2, 0, border=0, flag=wx.GROW)
       
   749         parent.AddWindow(self.ConnectionName, 0, border=0, flag=wx.GROW)
       
   750         parent.AddWindow(self.Spacer, 0, border=0, flag=wx.GROW)
       
   751     
       
   752     def _init_coll_LeftGridSizer_Growables(self, parent):
       
   753         parent.AddGrowableCol(0)
       
   754         parent.AddGrowableRow(5)
       
   755             
       
   756     def _init_coll_RightGridSizer_Items(self, parent):
       
   757         parent.AddWindow(self.staticText3, 0, border=0, flag=wx.GROW)
       
   758         parent.AddWindow(self.Preview, 0, border=0, flag=wx.GROW)
       
   759         
       
   760     def _init_coll_RightGridSizer_Growables(self, parent):
       
   761         parent.AddGrowableCol(0)
       
   762         parent.AddGrowableRow(1)
       
   763 
       
   764     def _init_sizers(self):
       
   765         self.flexGridSizer1 = wx.FlexGridSizer(cols=1, hgap=0, rows=2, vgap=10)
       
   766         self.MainSizer = wx.BoxSizer(wx.HORIZONTAL)
       
   767         self.LeftGridSizer = wx.FlexGridSizer(cols=1, hgap=0, rows=6, vgap=5)
       
   768         self.RightGridSizer = wx.FlexGridSizer(cols=1, hgap=0, rows=2, vgap=5)
       
   769 
       
   770         self._init_coll_flexGridSizer1_Items(self.flexGridSizer1)
       
   771         self._init_coll_flexGridSizer1_Growables(self.flexGridSizer1)
       
   772         self._init_coll_MainSizer_Items(self.MainSizer)
       
   773         self._init_coll_LeftGridSizer_Items(self.LeftGridSizer)
       
   774         self._init_coll_LeftGridSizer_Growables(self.LeftGridSizer)
       
   775         self._init_coll_RightGridSizer_Items(self.RightGridSizer)
       
   776         self._init_coll_RightGridSizer_Growables(self.RightGridSizer)
       
   777 
       
   778         self.SetSizer(self.flexGridSizer1)
       
   779 
       
   780     def _init_ctrls(self, prnt, ctrler):
       
   781         wx.Dialog.__init__(self, id=ID_CONNECTIONPROPERTIESDIALOG,
       
   782               name='ConnectionPropertiesDialog', parent=prnt, pos=wx.Point(376, 223),
       
   783               size=wx.Size(350, 220), style=wx.DEFAULT_DIALOG_STYLE,
       
   784               title=_('Connection Properties'))
       
   785         self.SetClientSize(wx.Size(350, 220))
       
   786 
       
   787         self.staticText1 = wx.StaticText(id=ID_CONNECTIONPROPERTIESDIALOGSTATICTEXT1,
       
   788               label=_('Type:'), name='staticText1', parent=self,
       
   789               pos=wx.Point(0, 0), size=wx.Size(0, 17), style=0)
       
   790 
       
   791         self.staticText2 = wx.StaticText(id=ID_CONNECTIONPROPERTIESDIALOGSTATICTEXT2,
       
   792               label=_('Name:'), name='staticText2', parent=self,
       
   793               pos=wx.Point(0, 0), size=wx.Size(0, 17), style=0)
       
   794 
       
   795         self.staticText3 = wx.StaticText(id=ID_CONNECTIONPROPERTIESDIALOGSTATICTEXT3,
       
   796               label=_('Preview:'), name='staticText3', parent=self,
       
   797               pos=wx.Point(0, 0), size=wx.Size(0, 17), style=0)
       
   798 
       
   799         self.radioButton1 = wx.RadioButton(id=ID_CONNECTIONPROPERTIESDIALOGRADIOBUTTON1,
       
   800               label=_('Connector'), name='radioButton1', parent=self,
       
   801               pos=wx.Point(0, 0), size=wx.Size(0, 24), style=wx.RB_GROUP)
       
   802         self.Bind(wx.EVT_RADIOBUTTON, self.OnTypeChanged, id=ID_CONNECTIONPROPERTIESDIALOGRADIOBUTTON1)
       
   803         self.radioButton1.SetValue(True)
       
   804 
       
   805         self.radioButton2 = wx.RadioButton(id=ID_CONNECTIONPROPERTIESDIALOGRADIOBUTTON2,
       
   806               label=_('Continuation'), name='radioButton2', parent=self, 
       
   807               pos=wx.Point(0, 0), size=wx.Size(0, 24), style=0)
       
   808         self.Bind(wx.EVT_RADIOBUTTON, self.OnTypeChanged, id=ID_CONNECTIONPROPERTIESDIALOGRADIOBUTTON2)
       
   809         self.radioButton2.SetValue(False)
       
   810         
       
   811         self.ConnectionName = wx.TextCtrl(id=ID_CONNECTIONPROPERTIESDIALOGNAME,
       
   812               name='Name', parent=self, pos=wx.Point(0, 0),
       
   813               size=wx.Size(0, 24), style=0)
       
   814         self.Bind(wx.EVT_TEXT, self.OnNameChanged, id=ID_CONNECTIONPROPERTIESDIALOGNAME)
       
   815 
       
   816         self.Preview = wx.Panel(id=ID_CONNECTIONPROPERTIESDIALOGPREVIEW,
       
   817               name='Preview', parent=self, pos=wx.Point(0, 0),
       
   818               size=wx.Size(0, 0), style=wx.TAB_TRAVERSAL|wx.SIMPLE_BORDER)
       
   819         self.Preview.SetBackgroundColour(wx.Colour(255,255,255))
       
   820         setattr(self.Preview, "GetDrawingMode", lambda:FREEDRAWING_MODE)
       
   821         setattr(self.Preview, "GetScaling", lambda:None)
       
   822         setattr(self.Preview, "IsOfType", ctrler.IsOfType)
       
   823 
       
   824         self.Spacer = wx.Panel(id=ID_CONNECTIONPROPERTIESDIALOGSPACER,
       
   825               name='Spacer', parent=self, pos=wx.Point(0, 0),
       
   826               size=wx.Size(0, 0), style=wx.TAB_TRAVERSAL)
       
   827 
       
   828         self.ButtonSizer = self.CreateButtonSizer(wx.OK|wx.CANCEL|wx.CENTRE)
       
   829         if wx.VERSION >= (2, 5, 0):
       
   830             self.Bind(wx.EVT_BUTTON, self.OnOK, id=self.ButtonSizer.GetAffirmativeButton().GetId())
       
   831             self.Preview.Bind(wx.EVT_PAINT, self.OnPaint)
       
   832         else:
       
   833             self.Bind(wx.EVT_BUTTON, self.OnOK, id=self.ButtonSizer.GetChildren()[0].GetSizer().GetChildren()[0].GetWindow().GetId())
       
   834             wx.EVT_PAINT(self.Preview, self.OnPaint)
       
   835         
       
   836         self._init_sizers()
       
   837 
       
   838     def __init__(self, parent, controler):
       
   839         self._init_ctrls(parent, controler)
       
   840         self.Connection = None
       
   841         self.MinConnectionSize = None
       
   842         
       
   843         self.PouNames = []
       
   844         self.PouElementNames = []
       
   845     
       
   846     def SetPreviewFont(self, font):
       
   847         self.Preview.SetFont(font)
       
   848     
       
   849     def SetMinConnectionSize(self, size):
       
   850         self.MinConnectionSize = size
       
   851     
       
   852     def SetValues(self, values):
       
   853         for name, value in values.items():
       
   854             if name == "type":
       
   855                 if value == CONNECTOR:
       
   856                     self.radioButton1.SetValue(True)
       
   857                 elif value == CONTINUATION:
       
   858                     self.radioButton2.SetValue(True)
       
   859             elif name == "name":
       
   860                 self.ConnectionName.SetValue(value)
       
   861         self.RefreshPreview()
       
   862     
       
   863     def GetValues(self):
       
   864         values = {}
       
   865         if self.radioButton1.GetValue():
       
   866             values["type"] = CONNECTOR
       
   867         else:
       
   868             values["type"] = CONTINUATION
       
   869         values["name"] = self.ConnectionName.GetValue()
       
   870         values["width"], values["height"] = self.Connection.GetSize()
       
   871         return values
       
   872 
       
   873     def SetPouNames(self, pou_names):
       
   874         self.PouNames = [pou_name.upper() for pou_name in pou_names]
       
   875         
       
   876     def SetPouElementNames(self, element_names):
       
   877         self.PouElementNames = [element_name.upper() for element_name in element_names]
       
   878 
       
   879     def OnOK(self, event):
       
   880         connection_name = self.ConnectionName.GetValue()
       
   881         if connection_name == "":
       
   882             message = wx.MessageDialog(self, _("Form isn't complete. Name must be filled!"), _("Error"), wx.OK|wx.ICON_ERROR)
       
   883             message.ShowModal()
       
   884             message.Destroy()
       
   885         elif not TestIdentifier(connection_name):
       
   886             message = wx.MessageDialog(self, _("\"%s\" is not a valid identifier!")%connection_name, _("Error"), wx.OK|wx.ICON_ERROR)
       
   887             message.ShowModal()
       
   888             message.Destroy()
       
   889         elif connection_name.upper() in IEC_KEYWORDS:
       
   890             message = wx.MessageDialog(self, _("\"%s\" is a keyword. It can't be used!")%connection_name, _("Error"), wx.OK|wx.ICON_ERROR)
       
   891             message.ShowModal()
       
   892             message.Destroy()
       
   893         elif connection_name.upper() in self.PouNames:
       
   894             message = wx.MessageDialog(self, _("\"%s\" pou already exists!")%connection_name, _("Error"), wx.OK|wx.ICON_ERROR)
       
   895             message.ShowModal()
       
   896             message.Destroy()
       
   897         elif connection_name.upper() in self.PouElementNames:
       
   898             message = wx.MessageDialog(self, _("\"%s\" element for this pou already exists!")%connection_name, _("Error"), wx.OK|wx.ICON_ERROR)
       
   899             message.ShowModal()
       
   900             message.Destroy()
       
   901         else:
       
   902             self.EndModal(wx.ID_OK)
       
   903 
       
   904     def OnTypeChanged(self, event):
       
   905         self.RefreshPreview()
       
   906         event.Skip()
       
   907 
       
   908     def OnNameChanged(self, event):
       
   909         self.RefreshPreview()
       
   910         event.Skip()
       
   911         
       
   912     def RefreshPreview(self):
       
   913         dc = wx.ClientDC(self.Preview)
       
   914         dc.SetFont(self.Preview.GetFont())
       
   915         dc.Clear()
       
   916         if self.radioButton1.GetValue():
       
   917             self.Connection = FBD_Connector(self.Preview, CONNECTOR, self.ConnectionName.GetValue())
       
   918         else:
       
   919             self.Connection = FBD_Connector(self.Preview, CONTINUATION, self.ConnectionName.GetValue())
       
   920         width, height = self.MinConnectionSize
       
   921         min_width, min_height = self.Connection.GetMinSize()
       
   922         width, height = max(min_width, width), max(min_height, height)
       
   923         self.Connection.SetSize(width, height)
       
   924         clientsize = self.Preview.GetClientSize()
       
   925         x = (clientsize.width - width) / 2
       
   926         y = (clientsize.height - height) / 2
       
   927         self.Connection.SetPosition(x, y)
       
   928         self.Connection.Draw(dc)
       
   929 
       
   930     def OnPaint(self, event):
       
   931         self.RefreshPreview()
       
   932         event.Skip()
       
   933 
       
   934 #-------------------------------------------------------------------------------
       
   935 #                        Edit Ladder Element Properties Dialog
       
   936 #-------------------------------------------------------------------------------
       
   937 
       
   938 
       
   939 [ID_LDELEMENTDIALOG, ID_LDELEMENTDIALOGSPACER, 
       
   940  ID_LDELEMENTDIALOGNAME, ID_LDELEMENTDIALOGRADIOBUTTON1, 
       
   941  ID_LDELEMENTDIALOGRADIOBUTTON2, ID_LDELEMENTDIALOGRADIOBUTTON3,
       
   942  ID_LDELEMENTDIALOGRADIOBUTTON4, ID_LDELEMENTDIALOGRADIOBUTTON5,
       
   943  ID_LDELEMENTDIALOGRADIOBUTTON6, ID_LDELEMENTDIALOGPREVIEW,
       
   944  ID_LDELEMENTDIALOGSTATICTEXT1, ID_LDELEMENTDIALOGSTATICTEXT2, 
       
   945  ID_LDELEMENTDIALOGSTATICTEXT3, 
       
   946 ] = [wx.NewId() for _init_ctrls in range(13)]
       
   947 
       
   948 class LDElementDialog(wx.Dialog):
       
   949     
       
   950     if wx.VERSION < (2, 6, 0):
       
   951         def Bind(self, event, function, id = None):
       
   952             if id is not None:
       
   953                 event(self, id, function)
       
   954             else:
       
   955                 event(self, function)
       
   956     
       
   957     def _init_coll_flexGridSizer1_Items(self, parent):
       
   958         parent.AddSizer(self.MainSizer, 0, border=20, flag=wx.GROW|wx.TOP|wx.LEFT|wx.RIGHT)
       
   959         parent.AddSizer(self.ButtonSizer, 0, border=20, flag=wx.ALIGN_RIGHT|wx.BOTTOM|wx.LEFT|wx.RIGHT)
       
   960         
       
   961     def _init_coll_flexGridSizer1_Growables(self, parent):
       
   962         parent.AddGrowableCol(0)
       
   963         parent.AddGrowableRow(0)
       
   964     
       
   965     def _init_coll_MainSizer_Items(self, parent):
       
   966         parent.AddSizer(self.LeftGridSizer, 1, border=5, flag=wx.GROW|wx.RIGHT)
       
   967         parent.AddSizer(self.RightGridSizer, 1, border=5, flag=wx.GROW|wx.LEFT)
       
   968     
       
   969     def _init_coll_LeftGridSizer_Items(self, parent):
       
   970         parent.AddWindow(self.staticText1, 0, border=0, flag=wx.GROW)
       
   971         parent.AddSizer(self.RadioButtonSizer, 0, border=0, flag=wx.GROW)
       
   972         parent.AddWindow(self.staticText2, 0, border=0, flag=wx.GROW)
       
   973         parent.AddWindow(self.ElementName, 0, border=0, flag=wx.GROW)
       
   974         parent.AddWindow(self.Spacer, 0, border=0, flag=wx.GROW)
       
   975         
       
   976     def _init_coll_LeftGridSizer_Growables(self, parent):
       
   977         parent.AddGrowableCol(0)
       
   978         parent.AddGrowableRow(7)
       
   979     
       
   980     def _init_coll_RadioButtonSizer_Items(self, parent):
       
   981         parent.AddWindow(self.radioButton1, 0, border=0, flag=wx.GROW)
       
   982         parent.AddWindow(self.radioButton2, 0, border=0, flag=wx.GROW)
       
   983         parent.AddWindow(self.radioButton3, 0, border=0, flag=wx.GROW)
       
   984         parent.AddWindow(self.radioButton4, 0, border=0, flag=wx.GROW)
       
   985         parent.AddWindow(self.radioButton5, 0, border=0, flag=wx.GROW)
       
   986         parent.AddWindow(self.radioButton6, 0, border=0, flag=wx.GROW)
       
   987         
       
   988     def _init_coll_RightGridSizer_Items(self, parent):
       
   989         parent.AddWindow(self.staticText3, 0, border=0, flag=wx.GROW)
       
   990         parent.AddWindow(self.Preview, 0, border=0, flag=wx.GROW)
       
   991         
       
   992     def _init_coll_RightGridSizer_Growables(self, parent):
       
   993         parent.AddGrowableCol(0)
       
   994         parent.AddGrowableRow(1)
       
   995 
       
   996     def _init_sizers(self):
       
   997         self.flexGridSizer1 = wx.FlexGridSizer(cols=1, hgap=0, rows=2, vgap=10)
       
   998         self.MainSizer = wx.BoxSizer(wx.HORIZONTAL)
       
   999         self.LeftGridSizer = wx.FlexGridSizer(cols=1, hgap=0, rows=5, vgap=5)
       
  1000         self.RadioButtonSizer = wx.BoxSizer(wx.VERTICAL)
       
  1001         self.RightGridSizer = wx.FlexGridSizer(cols=1, hgap=0, rows=2, vgap=5)
       
  1002 
       
  1003         self._init_coll_flexGridSizer1_Items(self.flexGridSizer1)
       
  1004         self._init_coll_flexGridSizer1_Growables(self.flexGridSizer1)
       
  1005         self._init_coll_MainSizer_Items(self.MainSizer)
       
  1006         self._init_coll_LeftGridSizer_Items(self.LeftGridSizer)
       
  1007         self._init_coll_LeftGridSizer_Growables(self.LeftGridSizer)
       
  1008         self._init_coll_RadioButtonSizer_Items(self.RadioButtonSizer)
       
  1009         self._init_coll_RightGridSizer_Items(self.RightGridSizer)
       
  1010         self._init_coll_RightGridSizer_Growables(self.RightGridSizer)
       
  1011 
       
  1012         self.SetSizer(self.flexGridSizer1)
       
  1013 
       
  1014     def _init_ctrls(self, prnt, ctrler, title, extra_size = 0):
       
  1015         wx.Dialog.__init__(self, id=ID_LDELEMENTDIALOG,
       
  1016               name='LDElementDialog', parent=prnt, pos=wx.Point(376, 223),
       
  1017               size=wx.Size(350, 260 + extra_size), style=wx.DEFAULT_DIALOG_STYLE,
       
  1018               title=title)
       
  1019         self.SetClientSize(wx.Size(350, 260 + extra_size))
       
  1020 
       
  1021         self.staticText1 = wx.StaticText(id=ID_LDELEMENTDIALOGSTATICTEXT1,
       
  1022               label=_('Modifier:'), name='staticText1', parent=self,
       
  1023               pos=wx.Point(0, 0), size=wx.Size(0, 17), style=0)
       
  1024 
       
  1025         self.staticText2 = wx.StaticText(id=ID_LDELEMENTDIALOGSTATICTEXT2,
       
  1026               label=_('Name:'), name='staticText2', parent=self,
       
  1027               pos=wx.Point(0, 0), size=wx.Size(0, 17), style=0)
       
  1028 
       
  1029         self.staticText3 = wx.StaticText(id=ID_LDELEMENTDIALOGSTATICTEXT3,
       
  1030               label=_('Preview:'), name='staticText3', parent=self,
       
  1031               pos=wx.Point(0, 0), size=wx.Size(0, 17), style=0)
       
  1032 
       
  1033         self.radioButton1 = wx.RadioButton(id=ID_LDELEMENTDIALOGRADIOBUTTON1,
       
  1034               label=_("Normal"), name='radioButton1', parent=self,
       
  1035               pos=wx.Point(0, 0), size=wx.Size(0, 24), style=wx.RB_GROUP)
       
  1036         self.Bind(wx.EVT_RADIOBUTTON, self.OnTypeChanged, id=ID_LDELEMENTDIALOGRADIOBUTTON1)
       
  1037         self.radioButton1.SetValue(True)
       
  1038 
       
  1039         self.radioButton2 = wx.RadioButton(id=ID_LDELEMENTDIALOGRADIOBUTTON2,
       
  1040               label=_("Negated"), name='radioButton2', parent=self, 
       
  1041               pos=wx.Point(0, 0), size=wx.Size(0, 24), style=0)
       
  1042         self.Bind(wx.EVT_RADIOBUTTON, self.OnTypeChanged, id=ID_LDELEMENTDIALOGRADIOBUTTON2)
       
  1043 
       
  1044         self.radioButton3 = wx.RadioButton(id=ID_LDELEMENTDIALOGRADIOBUTTON3,
       
  1045               label=_("Set"), name='radioButton3', parent=self,
       
  1046               pos=wx.Point(0, 0), size=wx.Size(0, 24), style=0)
       
  1047         self.Bind(wx.EVT_RADIOBUTTON, self.OnTypeChanged, id=ID_LDELEMENTDIALOGRADIOBUTTON3)
       
  1048 
       
  1049         self.radioButton4 = wx.RadioButton(id=ID_LDELEMENTDIALOGRADIOBUTTON4,
       
  1050               label=_("Reset"), name='radioButton4', parent=self, 
       
  1051               pos=wx.Point(0, 0), size=wx.Size(0, 24), style=0)
       
  1052         self.Bind(wx.EVT_RADIOBUTTON, self.OnTypeChanged, id=ID_LDELEMENTDIALOGRADIOBUTTON4)
       
  1053 
       
  1054         self.radioButton5 = wx.RadioButton(id=ID_LDELEMENTDIALOGRADIOBUTTON5,
       
  1055               label=_("Rising Edge"), name='radioButton5', parent=self, 
       
  1056               pos=wx.Point(0, 0), size=wx.Size(0, 24), style=0)
       
  1057         self.Bind(wx.EVT_RADIOBUTTON, self.OnTypeChanged, id=ID_LDELEMENTDIALOGRADIOBUTTON5)
       
  1058 
       
  1059         self.radioButton6 = wx.RadioButton(id=ID_LDELEMENTDIALOGRADIOBUTTON6,
       
  1060               label=_("Falling Edge"), name='radioButton6', parent=self, 
       
  1061               pos=wx.Point(0, 0), size=wx.Size(0, 24), style=0)
       
  1062         self.Bind(wx.EVT_RADIOBUTTON, self.OnTypeChanged, id=ID_LDELEMENTDIALOGRADIOBUTTON6)
       
  1063 
       
  1064         self.ElementName = wx.ComboBox(id=ID_LDELEMENTDIALOGNAME,
       
  1065               name='Name', parent=self, pos=wx.Point(0, 0),
       
  1066               size=wx.Size(0, 28), style=wx.CB_READONLY)
       
  1067         self.Bind(wx.EVT_COMBOBOX, self.OnNameChanged, id=ID_LDELEMENTDIALOGNAME)
       
  1068 
       
  1069         self.Preview = wx.Panel(id=ID_LDELEMENTDIALOGPREVIEW,
       
  1070               name='Preview', parent=self, pos=wx.Point(0, 0),
       
  1071               size=wx.Size(0, 0), style=wx.TAB_TRAVERSAL|wx.SIMPLE_BORDER)
       
  1072         self.Preview.SetBackgroundColour(wx.Colour(255,255,255))
       
  1073         setattr(self.Preview, "GetDrawingMode", lambda:FREEDRAWING_MODE)
       
  1074         setattr(self.Preview, "GetScaling", lambda:None)
       
  1075         setattr(self.Preview, "IsOfType", ctrler.IsOfType)
       
  1076 
       
  1077         self.Spacer = wx.Panel(id=ID_LDELEMENTDIALOGSPACER,
       
  1078               name='Spacer', parent=self, pos=wx.Point(0, 0),
       
  1079               size=wx.Size(0, 0), style=wx.TAB_TRAVERSAL)
       
  1080 
       
  1081         self.ButtonSizer = self.CreateButtonSizer(wx.OK|wx.CANCEL|wx.CENTRE)
       
  1082         
       
  1083         if wx.VERSION >= (2, 5, 0):
       
  1084             self.Preview.Bind(wx.EVT_PAINT, self.OnPaint)
       
  1085         else:
       
  1086             wx.EVT_PAINT(self.Preview, self.OnPaint)
       
  1087         
       
  1088         self._init_sizers()
       
  1089 
       
  1090     def __init__(self, parent, controler, type):
       
  1091         self.Type = type
       
  1092         if type == "contact":
       
  1093             self._init_ctrls(parent, controler, _("Edit Contact Values"))
       
  1094             self.Element = LD_Contact(self.Preview, CONTACT_NORMAL, "")
       
  1095             self.radioButton3.Hide()
       
  1096             self.radioButton4.Hide()
       
  1097         elif type == "coil":
       
  1098             self._init_ctrls(parent, controler, _("Edit Coil Values"), 50)
       
  1099             self.Element = LD_Coil(self.Preview, COIL_NORMAL, "")
       
  1100             
       
  1101     
       
  1102     def SetPreviewFont(self, font):
       
  1103         self.Preview.SetFont(font)
       
  1104     
       
  1105     def SetElementSize(self, size):
       
  1106         min_width, min_height = self.Element.GetMinSize()
       
  1107         width, height = max(min_width, size[0]), max(min_height, size[1])
       
  1108         self.Element.SetSize(width, height)
       
  1109         
       
  1110     def SetVariables(self, vars):
       
  1111         self.ElementName.Clear()
       
  1112         for name in vars:
       
  1113             self.ElementName.Append(name)
       
  1114         self.ElementName.Enable(self.ElementName.GetCount() > 0)
       
  1115 
       
  1116     def SetValues(self, values):
       
  1117         for name, value in values.items():
       
  1118             if name == "name":
       
  1119                 self.Element.SetName(value)
       
  1120                 self.ElementName.SetStringSelection(value)
       
  1121             elif name == "type":
       
  1122                 self.Element.SetType(value)
       
  1123                 if self.Type == "contact":
       
  1124                     if value == CONTACT_NORMAL:
       
  1125                         self.radioButton1.SetValue(True)
       
  1126                     elif value == CONTACT_REVERSE:
       
  1127                         self.radioButton2.SetValue(True)
       
  1128                     elif value == CONTACT_RISING:
       
  1129                         self.radioButton5.SetValue(True)
       
  1130                     elif value == CONTACT_FALLING:
       
  1131                         self.radioButton6.SetValue(True)
       
  1132                 elif self.Type == "coil":
       
  1133                     if value == COIL_NORMAL:
       
  1134                         self.radioButton1.SetValue(True)
       
  1135                     elif value == COIL_REVERSE:
       
  1136                         self.radioButton2.SetValue(True)
       
  1137                     elif value == COIL_SET:
       
  1138                         self.radioButton3.SetValue(True)
       
  1139                     elif value == COIL_RESET:
       
  1140                         self.radioButton4.SetValue(True)
       
  1141                     elif value == COIL_RISING:
       
  1142                         self.radioButton5.SetValue(True)
       
  1143                     elif value == COIL_FALLING:
       
  1144                         self.radioButton6.SetValue(True)
       
  1145 
       
  1146     def GetValues(self):
       
  1147         values = {}
       
  1148         values["name"] = self.Element.GetName()
       
  1149         values["type"] = self.Element.GetType()
       
  1150         values["width"], values["height"] = self.Element.GetSize()
       
  1151         return values
       
  1152 
       
  1153     def OnTypeChanged(self, event):
       
  1154         if self.Type == "contact":
       
  1155             if self.radioButton1.GetValue():
       
  1156                 self.Element.SetType(CONTACT_NORMAL)
       
  1157             elif self.radioButton2.GetValue():
       
  1158                 self.Element.SetType(CONTACT_REVERSE)
       
  1159             elif self.radioButton5.GetValue():
       
  1160                 self.Element.SetType(CONTACT_RISING)
       
  1161             elif self.radioButton6.GetValue():
       
  1162                 self.Element.SetType(CONTACT_FALLING)
       
  1163         elif self.Type == "coil":
       
  1164             if self.radioButton1.GetValue():
       
  1165                 self.Element.SetType(COIL_NORMAL)
       
  1166             elif self.radioButton2.GetValue():
       
  1167                 self.Element.SetType(COIL_REVERSE)
       
  1168             elif self.radioButton3.GetValue():
       
  1169                 self.Element.SetType(COIL_SET)
       
  1170             elif self.radioButton4.GetValue():
       
  1171                 self.Element.SetType(COIL_RESET)
       
  1172             elif self.radioButton5.GetValue():
       
  1173                 self.Element.SetType(COIL_RISING)
       
  1174             elif self.radioButton6.GetValue():
       
  1175                 self.Element.SetType(COIL_FALLING)
       
  1176         self.RefreshPreview()
       
  1177         event.Skip()
       
  1178 
       
  1179     def OnNameChanged(self, event):
       
  1180         self.Element.SetName(self.ElementName.GetStringSelection())
       
  1181         self.RefreshPreview()
       
  1182         event.Skip()
       
  1183 
       
  1184     def RefreshPreview(self):
       
  1185         dc = wx.ClientDC(self.Preview)
       
  1186         dc.SetFont(self.Preview.GetFont())
       
  1187         dc.Clear()
       
  1188         clientsize = self.Preview.GetClientSize()
       
  1189         width, height = self.Element.GetSize()
       
  1190         self.Element.SetPosition((clientsize.width - width) / 2, (clientsize.height - height) / 2)
       
  1191         self.Element.Draw(dc)
       
  1192 
       
  1193     def OnPaint(self, event):
       
  1194         self.RefreshPreview()
       
  1195         event.Skip()
       
  1196 
       
  1197 
       
  1198 #-------------------------------------------------------------------------------
       
  1199 #                      Edit Ladder Power Rail Properties Dialog
       
  1200 #-------------------------------------------------------------------------------
       
  1201 
       
  1202 
       
  1203 [ID_LDPOWERRAILDIALOG, ID_LDPOWERRAILDIALOGSPACER, 
       
  1204  ID_LDPOWERRAILDIALOGTYPE, ID_LDPOWERRAILDIALOGRADIOBUTTON1, 
       
  1205  ID_LDPOWERRAILDIALOGRADIOBUTTON2, ID_LDPOWERRAILDIALOGPREVIEW,
       
  1206  ID_LDPOWERRAILDIALOGSTATICTEXT1, ID_LDPOWERRAILDIALOGSTATICTEXT2, 
       
  1207  ID_LDPOWERRAILDIALOGSTATICTEXT3, ID_LDPOWERRAILDIALOGPINNUMBER,
       
  1208 ] = [wx.NewId() for _init_ctrls in range(10)]
       
  1209 
       
  1210 class LDPowerRailDialog(wx.Dialog):
       
  1211     
       
  1212     if wx.VERSION < (2, 6, 0):
       
  1213         def Bind(self, event, function, id = None):
       
  1214             if id is not None:
       
  1215                 event(self, id, function)
       
  1216             else:
       
  1217                 event(self, function)
       
  1218     
       
  1219     def _init_coll_flexGridSizer1_Items(self, parent):
       
  1220         parent.AddSizer(self.MainSizer, 0, border=20, flag=wx.GROW|wx.TOP|wx.LEFT|wx.RIGHT)
       
  1221         parent.AddSizer(self.ButtonSizer, 0, border=20, flag=wx.ALIGN_RIGHT|wx.BOTTOM|wx.LEFT|wx.RIGHT)
       
  1222         
       
  1223     def _init_coll_flexGridSizer1_Growables(self, parent):
       
  1224         parent.AddGrowableCol(0)
       
  1225         parent.AddGrowableRow(0)
       
  1226     
       
  1227     def _init_coll_MainSizer_Items(self, parent):
       
  1228         parent.AddSizer(self.LeftGridSizer, 1, border=5, flag=wx.GROW|wx.RIGHT)
       
  1229         parent.AddSizer(self.RightGridSizer, 1, border=5, flag=wx.GROW|wx.LEFT)
       
  1230     
       
  1231     def _init_coll_LeftGridSizer_Items(self, parent):
       
  1232         parent.AddWindow(self.staticText1, 0, border=0, flag=wx.GROW)
       
  1233         parent.AddWindow(self.radioButton1, 0, border=0, flag=wx.GROW)
       
  1234         parent.AddWindow(self.radioButton2, 0, border=0, flag=wx.GROW)
       
  1235         parent.AddWindow(self.staticText2, 0, border=0, flag=wx.GROW)
       
  1236         parent.AddWindow(self.PinNumber, 0, border=0, flag=wx.GROW)
       
  1237         parent.AddWindow(self.Spacer, 0, border=0, flag=wx.GROW)
       
  1238     
       
  1239     def _init_coll_LeftGridSizer_Growables(self, parent):
       
  1240         parent.AddGrowableCol(0)
       
  1241         parent.AddGrowableRow(5)
       
  1242             
       
  1243     def _init_coll_RightGridSizer_Items(self, parent):
       
  1244         parent.AddWindow(self.staticText3, 0, border=0, flag=wx.GROW)
       
  1245         parent.AddWindow(self.Preview, 0, border=0, flag=wx.GROW)
       
  1246         
       
  1247     def _init_coll_RightGridSizer_Growables(self, parent):
       
  1248         parent.AddGrowableCol(0)
       
  1249         parent.AddGrowableRow(1)
       
  1250 
       
  1251     def _init_sizers(self):
       
  1252         self.flexGridSizer1 = wx.FlexGridSizer(cols=1, hgap=0, rows=2, vgap=10)
       
  1253         self.MainSizer = wx.BoxSizer(wx.HORIZONTAL)
       
  1254         self.LeftGridSizer = wx.FlexGridSizer(cols=1, hgap=0, rows=6, vgap=5)
       
  1255         self.RightGridSizer = wx.FlexGridSizer(cols=1, hgap=0, rows=2, vgap=5)
       
  1256 
       
  1257         self._init_coll_flexGridSizer1_Items(self.flexGridSizer1)
       
  1258         self._init_coll_flexGridSizer1_Growables(self.flexGridSizer1)
       
  1259         self._init_coll_MainSizer_Items(self.MainSizer)
       
  1260         self._init_coll_LeftGridSizer_Items(self.LeftGridSizer)
       
  1261         self._init_coll_LeftGridSizer_Growables(self.LeftGridSizer)
       
  1262         self._init_coll_RightGridSizer_Items(self.RightGridSizer)
       
  1263         self._init_coll_RightGridSizer_Growables(self.RightGridSizer)
       
  1264 
       
  1265         self.SetSizer(self.flexGridSizer1)
       
  1266 
       
  1267     def _init_ctrls(self, prnt, ctrler):
       
  1268         wx.Dialog.__init__(self, id=ID_LDPOWERRAILDIALOG,
       
  1269               name='PowerRailDialog', parent=prnt, pos=wx.Point(376, 223),
       
  1270               size=wx.Size(350, 260), style=wx.DEFAULT_DIALOG_STYLE,
       
  1271               title=_('Power Rail Properties'))
       
  1272         self.SetClientSize(wx.Size(350, 260))
       
  1273 
       
  1274         self.staticText1 = wx.StaticText(id=ID_LDPOWERRAILDIALOGSTATICTEXT1,
       
  1275               label=_('Type:'), name='staticText1', parent=self,
       
  1276               pos=wx.Point(0, 0), size=wx.Size(0, 17), style=0)
       
  1277 
       
  1278         self.staticText2 = wx.StaticText(id=ID_LDPOWERRAILDIALOGSTATICTEXT2,
       
  1279               label=_('Pin number:'), name='staticText2', parent=self,
       
  1280               pos=wx.Point(0, 0), size=wx.Size(0, 17), style=0)
       
  1281 
       
  1282         self.staticText3 = wx.StaticText(id=ID_LDPOWERRAILDIALOGSTATICTEXT3,
       
  1283               label=_('Preview:'), name='staticText3', parent=self,
       
  1284               pos=wx.Point(0, 0), size=wx.Size(0, 17), style=0)
       
  1285 
       
  1286         self.radioButton1 = wx.RadioButton(id=ID_LDPOWERRAILDIALOGRADIOBUTTON1,
       
  1287               label=_('Left PowerRail'), name='radioButton1', parent=self,
       
  1288               pos=wx.Point(0, 0), size=wx.Size(0, 24), style=wx.RB_GROUP)
       
  1289         self.Bind(wx.EVT_RADIOBUTTON, self.OnTypeChanged, id=ID_LDPOWERRAILDIALOGRADIOBUTTON1)
       
  1290         self.radioButton1.SetValue(True)
       
  1291 
       
  1292         self.radioButton2 = wx.RadioButton(id=ID_LDPOWERRAILDIALOGRADIOBUTTON2,
       
  1293               label=_('Right PowerRail'), name='radioButton2', parent=self, 
       
  1294               pos=wx.Point(0, 0), size=wx.Size(0, 24), style=0)
       
  1295         self.Bind(wx.EVT_RADIOBUTTON, self.OnTypeChanged, id=ID_LDPOWERRAILDIALOGRADIOBUTTON2)
       
  1296 
       
  1297         self.PinNumber = wx.SpinCtrl(id=ID_LDPOWERRAILDIALOGPINNUMBER,
       
  1298               name='PinNumber', parent=self, pos=wx.Point(0, 0),
       
  1299               size=wx.Size(0, 24), style=wx.SP_ARROW_KEYS, min=1, max=50)
       
  1300         self.Bind(wx.EVT_SPINCTRL, self.OnPinNumberChanged, id=ID_LDPOWERRAILDIALOGPINNUMBER)
       
  1301 
       
  1302         self.Preview = wx.Panel(id=ID_LDPOWERRAILDIALOGPREVIEW,
       
  1303               name='Preview', parent=self, pos=wx.Point(0, 0),
       
  1304               size=wx.Size(0, 0), style=wx.TAB_TRAVERSAL|wx.SIMPLE_BORDER)
       
  1305         self.Preview.SetBackgroundColour(wx.Colour(255,255,255))
       
  1306         setattr(self.Preview, "GetDrawingMode", lambda:FREEDRAWING_MODE)
       
  1307         setattr(self.Preview, "GetScaling", lambda:None)
       
  1308         setattr(self.Preview, "IsOfType", ctrler.IsOfType)
       
  1309 
       
  1310         self.Spacer = wx.Panel(id=ID_LDELEMENTDIALOGSPACER,
       
  1311               name='Spacer', parent=self, pos=wx.Point(0, 0),
       
  1312               size=wx.Size(0, 0), style=wx.TAB_TRAVERSAL)
       
  1313 
       
  1314         self.ButtonSizer = self.CreateButtonSizer(wx.OK|wx.CANCEL|wx.CENTRE)
       
  1315         
       
  1316         if wx.VERSION >= (2, 5, 0):
       
  1317             self.Preview.Bind(wx.EVT_PAINT, self.OnPaint)
       
  1318         else:
       
  1319             wx.EVT_PAINT(self.Preview, self.OnPaint)
       
  1320         
       
  1321         self._init_sizers()
       
  1322 
       
  1323     def __init__(self, parent, controler, type = LEFTRAIL, number = 1):
       
  1324         self._init_ctrls(parent, controler)
       
  1325         self.Type = type
       
  1326         if type == LEFTRAIL:
       
  1327             self.radioButton1.SetValue(True)
       
  1328         elif type == RIGHTRAIL:
       
  1329             self.radioButton2.SetValue(True)
       
  1330         self.PinNumber.SetValue(number)
       
  1331         
       
  1332         self.PowerRailMinSize = (0, 0)
       
  1333         self.PowerRail = None
       
  1334 
       
  1335     def SetPreviewFont(self, font):
       
  1336         self.Preview.SetFont(font)
       
  1337 
       
  1338     def SetMinSize(self, size):
       
  1339         self.PowerRailMinSize = size
       
  1340         self.RefreshPreview()    
       
  1341 
       
  1342     def GetValues(self):
       
  1343         values = {}
       
  1344         values["type"] = self.Type
       
  1345         values["number"] = self.PinNumber.GetValue()
       
  1346         values["width"], values["height"] = self.PowerRail.GetSize()
       
  1347         return values
       
  1348 
       
  1349     def OnTypeChanged(self, event):
       
  1350         if self.radioButton1.GetValue():
       
  1351             self.Type = LEFTRAIL
       
  1352         elif self.radioButton2.GetValue():
       
  1353             self.Type = RIGHTRAIL
       
  1354         self.RefreshPreview()
       
  1355         event.Skip()
       
  1356 
       
  1357     def OnPinNumberChanged(self, event):
       
  1358         self.RefreshPreview()
       
  1359         event.Skip()
       
  1360 
       
  1361     def RefreshPreview(self):
       
  1362         dc = wx.ClientDC(self.Preview)
       
  1363         dc.SetFont(self.Preview.GetFont())
       
  1364         dc.Clear()
       
  1365         self.PowerRail = LD_PowerRail(self.Preview, self.Type, connectors = [True for i in xrange(self.PinNumber.GetValue())])
       
  1366         min_width, min_height = 2, LD_LINE_SIZE * self.PinNumber.GetValue()
       
  1367         width, height = max(min_width, self.PowerRailMinSize[0]), max(min_height, self.PowerRailMinSize[1])
       
  1368         self.PowerRail.SetSize(width, height)
       
  1369         clientsize = self.Preview.GetClientSize()
       
  1370         self.PowerRail.SetPosition((clientsize.width - width) / 2, (clientsize.height - height) / 2)
       
  1371         self.PowerRail.Draw(dc)
       
  1372 
       
  1373     def OnPaint(self, event):
       
  1374         self.RefreshPreview()
       
  1375         event.Skip()
       
  1376 
       
  1377 
       
  1378 #-------------------------------------------------------------------------------
       
  1379 #                          Edit Step Content Dialog
       
  1380 #-------------------------------------------------------------------------------
       
  1381 
       
  1382 [ID_STEPCONTENTDIALOG, ID_STEPCONTENTDIALOGSPACER, 
       
  1383  ID_STEPCONTENTDIALOGNAME, ID_STEPCONTENTDIALOGPREVIEW, 
       
  1384  ID_STEPCONTENTDIALOGCHECKBOX1, ID_STEPCONTENTDIALOGCHECKBOX2,
       
  1385  ID_STEPCONTENTDIALOGCHECKBOX3, ID_STEPCONTENTDIALOGSTATICTEXT1, 
       
  1386  ID_STEPCONTENTDIALOGSTATICTEXT2, ID_STEPCONTENTDIALOGSTATICTEXT3, 
       
  1387 ] = [wx.NewId() for _init_ctrls in range(10)]
       
  1388 
       
  1389 class StepContentDialog(wx.Dialog):
       
  1390     
       
  1391     if wx.VERSION < (2, 6, 0):
       
  1392         def Bind(self, event, function, id = None):
       
  1393             if id is not None:
       
  1394                 event(self, id, function)
       
  1395             else:
       
  1396                 event(self, function)
       
  1397     
       
  1398     def _init_coll_flexGridSizer1_Items(self, parent):
       
  1399         parent.AddSizer(self.MainSizer, 0, border=20, flag=wx.GROW|wx.TOP|wx.LEFT|wx.RIGHT)
       
  1400         parent.AddSizer(self.ButtonSizer, 0, border=20, flag=wx.ALIGN_RIGHT|wx.BOTTOM|wx.LEFT|wx.RIGHT)
       
  1401         
       
  1402     def _init_coll_flexGridSizer1_Growables(self, parent):
       
  1403         parent.AddGrowableCol(0)
       
  1404         parent.AddGrowableRow(0)
       
  1405     
       
  1406     def _init_coll_MainSizer_Items(self, parent):
       
  1407         parent.AddSizer(self.LeftGridSizer, 1, border=5, flag=wx.GROW|wx.RIGHT)
       
  1408         parent.AddSizer(self.RightGridSizer, 1, border=5, flag=wx.GROW|wx.LEFT)
       
  1409     
       
  1410     def _init_coll_LeftGridSizer_Items(self, parent):
       
  1411         parent.AddWindow(self.staticText1, 0, border=0, flag=wx.GROW)
       
  1412         parent.AddWindow(self.StepName, 0, border=0, flag=wx.GROW)
       
  1413         parent.AddWindow(self.staticText2, 0, border=0, flag=wx.GROW)
       
  1414         parent.AddWindow(self.checkBox1, 0, border=0, flag=wx.GROW)
       
  1415         parent.AddWindow(self.checkBox2, 0, border=0, flag=wx.GROW)
       
  1416         parent.AddWindow(self.checkBox3, 0, border=0, flag=wx.GROW)
       
  1417         parent.AddWindow(self.Spacer, 0, border=0, flag=wx.GROW)
       
  1418         
       
  1419     def _init_coll_LeftGridSizer_Growables(self, parent):
       
  1420         parent.AddGrowableCol(0)
       
  1421         parent.AddGrowableRow(6)
       
  1422             
       
  1423     def _init_coll_RightGridSizer_Items(self, parent):
       
  1424         parent.AddWindow(self.staticText3, 0, border=0, flag=wx.GROW)
       
  1425         parent.AddWindow(self.Preview, 0, border=0, flag=wx.GROW)
       
  1426         
       
  1427     def _init_coll_RightGridSizer_Growables(self, parent):
       
  1428         parent.AddGrowableCol(0)
       
  1429         parent.AddGrowableRow(1)
       
  1430 
       
  1431     def _init_sizers(self):
       
  1432         self.flexGridSizer1 = wx.FlexGridSizer(cols=1, hgap=0, rows=2, vgap=10)
       
  1433         self.MainSizer = wx.BoxSizer(wx.HORIZONTAL)
       
  1434         self.LeftGridSizer = wx.FlexGridSizer(cols=1, hgap=0, rows=7, vgap=5)
       
  1435         self.RightGridSizer = wx.FlexGridSizer(cols=1, hgap=0, rows=2, vgap=5)
       
  1436 
       
  1437         self._init_coll_flexGridSizer1_Items(self.flexGridSizer1)
       
  1438         self._init_coll_flexGridSizer1_Growables(self.flexGridSizer1)
       
  1439         self._init_coll_MainSizer_Items(self.MainSizer)
       
  1440         self._init_coll_LeftGridSizer_Items(self.LeftGridSizer)
       
  1441         self._init_coll_LeftGridSizer_Growables(self.LeftGridSizer)
       
  1442         self._init_coll_RightGridSizer_Items(self.RightGridSizer)
       
  1443         self._init_coll_RightGridSizer_Growables(self.RightGridSizer)
       
  1444 
       
  1445         self.SetSizer(self.flexGridSizer1)
       
  1446 
       
  1447     def _init_ctrls(self, prnt, ctrler):
       
  1448         wx.Dialog.__init__(self, id=ID_STEPCONTENTDIALOG,
       
  1449               name='StepContentDialog', parent=prnt, pos=wx.Point(376, 223),
       
  1450               size=wx.Size(400, 250), style=wx.DEFAULT_DIALOG_STYLE,
       
  1451               title=_('Edit Step'))
       
  1452         self.SetClientSize(wx.Size(400, 250))
       
  1453 
       
  1454         self.staticText1 = wx.StaticText(id=ID_STEPCONTENTDIALOGSTATICTEXT1,
       
  1455               label=_('Name:'), name='staticText1', parent=self,
       
  1456               pos=wx.Point(0, 0), size=wx.Size(0, 17), style=0)
       
  1457 
       
  1458         self.staticText2 = wx.StaticText(id=ID_STEPCONTENTDIALOGSTATICTEXT2,
       
  1459               label=_('Connectors:'), name='staticText2', parent=self,
       
  1460               pos=wx.Point(0, 0), size=wx.Size(0, 17), style=0)
       
  1461 
       
  1462         self.staticText3 = wx.StaticText(id=ID_STEPCONTENTDIALOGSTATICTEXT3,
       
  1463               label=_('Preview:'), name='staticText4', parent=self,
       
  1464               pos=wx.Point(0, 0), size=wx.Size(0, 17), style=0)
       
  1465 
       
  1466         self.StepName = wx.TextCtrl(id=ID_STEPCONTENTDIALOGNAME,
       
  1467               name='Name', parent=self, pos=wx.Point(0, 0),
       
  1468               size=wx.Size(0, 24), style=0)
       
  1469         self.Bind(wx.EVT_TEXT, self.OnNameChanged, id=ID_STEPCONTENTDIALOGNAME)
       
  1470 
       
  1471         self.checkBox1 = wx.CheckBox(id=ID_STEPCONTENTDIALOGCHECKBOX1,
       
  1472               label=_("Input"), name='checkBox1', parent=self,
       
  1473               pos=wx.Point(0, 0), size=wx.Size(0, 24), style=0)
       
  1474         self.Bind(wx.EVT_CHECKBOX, self.OnConnectorsChanged, id=ID_STEPCONTENTDIALOGCHECKBOX1)
       
  1475         
       
  1476         self.checkBox2 = wx.CheckBox(id=ID_STEPCONTENTDIALOGCHECKBOX2,
       
  1477               label=_("Output"), name='checkBox2', parent=self,
       
  1478               pos=wx.Point(0, 0), size=wx.Size(0, 24), style=0)
       
  1479         self.Bind(wx.EVT_CHECKBOX, self.OnConnectorsChanged, id=ID_STEPCONTENTDIALOGCHECKBOX2)
       
  1480         
       
  1481         self.checkBox3 = wx.CheckBox(id=ID_STEPCONTENTDIALOGCHECKBOX3,
       
  1482               label=_("Action"), name='checkBox3', parent=self,
       
  1483               pos=wx.Point(0, 0), size=wx.Size(0, 24), style=0)
       
  1484         self.Bind(wx.EVT_CHECKBOX, self.OnConnectorsChanged, id=ID_STEPCONTENTDIALOGCHECKBOX3)
       
  1485         
       
  1486         self.Spacer = wx.Panel(id=ID_STEPCONTENTDIALOGSPACER,
       
  1487               name='Spacer', parent=self, pos=wx.Point(0, 0),
       
  1488               size=wx.Size(0, 0), style=wx.TAB_TRAVERSAL)
       
  1489 
       
  1490         self.Preview = wx.Panel(id=ID_STEPCONTENTDIALOGPREVIEW,
       
  1491               name='Preview', parent=self, pos=wx.Point(0, 0),
       
  1492               size=wx.Size(0, 0), style=wx.TAB_TRAVERSAL|wx.SIMPLE_BORDER)
       
  1493         self.Preview.SetBackgroundColour(wx.Colour(255,255,255))
       
  1494         setattr(self.Preview, "GetDrawingMode", lambda:FREEDRAWING_MODE)
       
  1495         setattr(self.Preview, "RefreshStepModel", lambda x:None)
       
  1496         setattr(self.Preview, "GetScaling", lambda:None)
       
  1497         setattr(self.Preview, "IsOfType", ctrler.IsOfType)
       
  1498 
       
  1499         self.ButtonSizer = self.CreateButtonSizer(wx.OK|wx.CANCEL|wx.CENTRE)
       
  1500         if wx.VERSION >= (2, 5, 0):
       
  1501             self.Bind(wx.EVT_BUTTON, self.OnOK, id=self.ButtonSizer.GetAffirmativeButton().GetId())
       
  1502             self.Preview.Bind(wx.EVT_PAINT, self.OnPaint)
       
  1503         else:
       
  1504             self.Bind(wx.EVT_BUTTON, self.OnOK, id=self.ButtonSizer.GetChildren()[0].GetSizer().GetChildren()[0].GetWindow().GetId())
       
  1505             wx.EVT_PAINT(self.Preview, self.OnPaint)
       
  1506         
       
  1507         self._init_sizers()
       
  1508 
       
  1509     def __init__(self, parent, controler, initial = False):
       
  1510         self._init_ctrls(parent, controler)
       
  1511         self.Step = None
       
  1512         self.Initial = initial
       
  1513         self.MinStepSize = None
       
  1514     
       
  1515         self.PouNames = []
       
  1516         self.Variables = []
       
  1517         self.StepNames = []
       
  1518     
       
  1519     def SetPreviewFont(self, font):
       
  1520         self.Preview.SetFont(font)
       
  1521     
       
  1522     def OnOK(self, event):
       
  1523         step_name = self.StepName.GetValue()
       
  1524         if step_name == "":
       
  1525             message = wx.MessageDialog(self, _("You must type a name!"), _("Error"), wx.OK|wx.ICON_ERROR)
       
  1526             message.ShowModal()
       
  1527             message.Destroy()
       
  1528         elif not TestIdentifier(step_name):
       
  1529             message = wx.MessageDialog(self, _("\"%s\" is not a valid identifier!")%step_name, _("Error"), wx.OK|wx.ICON_ERROR)
       
  1530             message.ShowModal()
       
  1531             message.Destroy()
       
  1532         elif step_name.upper() in IEC_KEYWORDS:
       
  1533             message = wx.MessageDialog(self, _("\"%s\" is a keyword. It can't be used!")%step_name, _("Error"), wx.OK|wx.ICON_ERROR)
       
  1534             message.ShowModal()
       
  1535             message.Destroy()
       
  1536         elif step_name.upper() in self.PouNames:
       
  1537             message = wx.MessageDialog(self, _("A pou with \"%s\" as name exists!")%step_name, _("Error"), wx.OK|wx.ICON_ERROR)
       
  1538             message.ShowModal()
       
  1539             message.Destroy()
       
  1540         elif step_name.upper() in self.Variables:
       
  1541             message = wx.MessageDialog(self, _("A variable with \"%s\" as name already exists in this pou!")%step_name, _("Error"), wx.OK|wx.ICON_ERROR)
       
  1542             message.ShowModal()
       
  1543             message.Destroy()
       
  1544         elif step_name.upper() in self.StepNames:
       
  1545             message = wx.MessageDialog(self, _("\"%s\" step already exists!")%step_name, _("Error"), wx.OK|wx.ICON_ERROR)
       
  1546             message.ShowModal()
       
  1547             message.Destroy()
       
  1548         else:
       
  1549             self.EndModal(wx.ID_OK)
       
  1550     
       
  1551     def SetMinStepSize(self, size):
       
  1552         self.MinStepSize = size
       
  1553 
       
  1554     def SetPouNames(self, pou_names):
       
  1555         self.PouNames = [pou_name.upper() for pou_name in pou_names]
       
  1556 
       
  1557     def SetVariables(self, variables):
       
  1558         self.Variables = [var["Name"].upper() for var in variables]
       
  1559 
       
  1560     def SetStepNames(self, step_names):
       
  1561         self.StepNames = [step_name.upper() for step_name in step_names]
       
  1562 
       
  1563     def SetValues(self, values):
       
  1564         value_name = values.get("name", None)
       
  1565         if value_name:
       
  1566             self.StepName.SetValue(value_name)
       
  1567         else:
       
  1568             self.StepName.SetValue("")
       
  1569         self.checkBox1.SetValue(values.get("input", False))
       
  1570         self.checkBox2.SetValue(values.get("output", False))
       
  1571         self.checkBox3.SetValue(values.get("action", False))
       
  1572         self.RefreshPreview()
       
  1573         
       
  1574     def GetValues(self):
       
  1575         values = {}
       
  1576         values["name"] = self.StepName.GetValue()
       
  1577         values["input"] = self.checkBox1.IsChecked()
       
  1578         values["output"] = self.checkBox2.IsChecked()
       
  1579         values["action"] = self.checkBox3.IsChecked()
       
  1580         values["width"], values["height"] = self.Step.GetSize()
       
  1581         return values
       
  1582     
       
  1583     def OnConnectorsChanged(self, event):
       
  1584         self.RefreshPreview()
       
  1585         event.Skip()
       
  1586 
       
  1587     def OnNameChanged(self, event):
       
  1588         self.RefreshPreview()
       
  1589         event.Skip()
       
  1590     
       
  1591     def RefreshPreview(self):
       
  1592         dc = wx.ClientDC(self.Preview)
       
  1593         dc.SetFont(self.Preview.GetFont())
       
  1594         dc.Clear()
       
  1595         self.Step = SFC_Step(self.Preview, self.StepName.GetValue(), self.Initial)
       
  1596         if self.checkBox1.IsChecked():
       
  1597             self.Step.AddInput()
       
  1598         else:
       
  1599             self.Step.RemoveInput()
       
  1600         if self.checkBox2.IsChecked():
       
  1601             self.Step.AddOutput()
       
  1602         else:
       
  1603             self.Step.RemoveOutput()
       
  1604         if self.checkBox3.IsChecked():
       
  1605             self.Step.AddAction()    
       
  1606         else:
       
  1607             self.Step.RemoveAction()
       
  1608         width, height = self.MinStepSize
       
  1609         min_width, min_height = self.Step.GetMinSize()
       
  1610         width, height = max(min_width, width), max(min_height, height)
       
  1611         self.Step.SetSize(width, height)
       
  1612         clientsize = self.Preview.GetClientSize()
       
  1613         x = (clientsize.width - width) / 2
       
  1614         y = (clientsize.height - height) / 2
       
  1615         self.Step.SetPosition(x, y)
       
  1616         self.Step.Draw(dc)
       
  1617 
       
  1618     def OnPaint(self, event):
       
  1619         self.RefreshPreview()
       
  1620         event.Skip()
       
  1621 
       
  1622 #-------------------------------------------------------------------------------
       
  1623 #                          Edit Transition Content Dialog
       
  1624 #-------------------------------------------------------------------------------
       
  1625 
       
  1626 [ID_TRANSITIONCONTENTDIALOG, ID_TRANSITIONCONTENTDIALOGSPACER, 
       
  1627  ID_TRANSITIONCONTENTDIALOGREFERENCE, ID_TRANSITIONCONTENTDIALOGINLINE, 
       
  1628  ID_TRANSITIONCONTENTDIALOGPRIORITY, ID_TRANSITIONCONTENTDIALOGPREVIEW, 
       
  1629  ID_TRANSITIONCONTENTDIALOGRADIOBUTTON1, ID_TRANSITIONCONTENTDIALOGRADIOBUTTON2, 
       
  1630  ID_TRANSITIONCONTENTDIALOGRADIOBUTTON3, ID_TRANSITIONCONTENTDIALOGSTATICTEXT1, 
       
  1631  ID_TRANSITIONCONTENTDIALOGSTATICTEXT2, ID_TRANSITIONCONTENTDIALOGSTATICTEXT3, 
       
  1632 ] = [wx.NewId() for _init_ctrls in range(12)]
       
  1633 
       
  1634 class TransitionContentDialog(wx.Dialog):
       
  1635     
       
  1636     if wx.VERSION < (2, 6, 0):
       
  1637         def Bind(self, event, function, id = None):
       
  1638             if id is not None:
       
  1639                 event(self, id, function)
       
  1640             else:
       
  1641                 event(self, function)
       
  1642     
       
  1643     def _init_coll_flexGridSizer1_Items(self, parent):
       
  1644         parent.AddSizer(self.MainSizer, 0, border=20, flag=wx.GROW|wx.TOP|wx.LEFT|wx.RIGHT)
       
  1645         parent.AddSizer(self.ButtonSizer, 0, border=20, flag=wx.ALIGN_RIGHT|wx.BOTTOM|wx.LEFT|wx.RIGHT)
       
  1646         
       
  1647     def _init_coll_flexGridSizer1_Growables(self, parent):
       
  1648         parent.AddGrowableCol(0)
       
  1649         parent.AddGrowableRow(0)
       
  1650     
       
  1651     def _init_coll_MainSizer_Items(self, parent):
       
  1652         parent.AddSizer(self.LeftGridSizer, 1, border=5, flag=wx.GROW|wx.RIGHT)
       
  1653         parent.AddSizer(self.RightGridSizer, 1, border=5, flag=wx.GROW|wx.LEFT)
       
  1654     
       
  1655     def _init_coll_LeftGridSizer_Items(self, parent):
       
  1656         parent.AddWindow(self.staticText1, 0, border=0, flag=wx.GROW)
       
  1657         parent.AddWindow(self.radioButton1, 0, border=0, flag=wx.GROW)
       
  1658         parent.AddWindow(self.Reference, 0, border=0, flag=wx.GROW)
       
  1659         parent.AddWindow(self.radioButton2, 0, border=0, flag=wx.GROW)
       
  1660         parent.AddWindow(self.Inline, 0, border=0, flag=wx.GROW)
       
  1661         parent.AddWindow(self.radioButton3, 0, border=0, flag=wx.GROW)
       
  1662         parent.AddWindow(self.staticText3, 0, border=0, flag=wx.GROW)
       
  1663         parent.AddWindow(self.Priority, 0, border=0, flag=wx.GROW)
       
  1664         parent.AddWindow(self.Spacer, 0, border=0, flag=wx.GROW)
       
  1665     
       
  1666     def _init_coll_LeftGridSizer_Growables(self, parent):
       
  1667         parent.AddGrowableCol(0)
       
  1668         parent.AddGrowableRow(6)
       
  1669             
       
  1670     def _init_coll_RightGridSizer_Items(self, parent):
       
  1671         parent.AddWindow(self.staticText2, 0, border=0, flag=wx.GROW)
       
  1672         parent.AddWindow(self.Preview, 0, border=0, flag=wx.GROW)
       
  1673         
       
  1674     def _init_coll_RightGridSizer_Growables(self, parent):
       
  1675         parent.AddGrowableCol(0)
       
  1676         parent.AddGrowableRow(1)
       
  1677 
       
  1678     def _init_sizers(self):
       
  1679         self.flexGridSizer1 = wx.FlexGridSizer(cols=1, hgap=0, rows=2, vgap=10)
       
  1680         self.MainSizer = wx.BoxSizer(wx.HORIZONTAL)
       
  1681         self.LeftGridSizer = wx.FlexGridSizer(cols=1, hgap=0, rows=9, vgap=5)
       
  1682         self.RightGridSizer = wx.FlexGridSizer(cols=1, hgap=0, rows=2, vgap=5)
       
  1683 
       
  1684         self._init_coll_flexGridSizer1_Items(self.flexGridSizer1)
       
  1685         self._init_coll_flexGridSizer1_Growables(self.flexGridSizer1)
       
  1686         self._init_coll_MainSizer_Items(self.MainSizer)
       
  1687         self._init_coll_LeftGridSizer_Items(self.LeftGridSizer)
       
  1688         self._init_coll_LeftGridSizer_Growables(self.LeftGridSizer)
       
  1689         self._init_coll_RightGridSizer_Items(self.RightGridSizer)
       
  1690         self._init_coll_RightGridSizer_Growables(self.RightGridSizer)
       
  1691 
       
  1692         self.SetSizer(self.flexGridSizer1)
       
  1693 
       
  1694     def _init_ctrls(self, prnt, ctrler):
       
  1695         wx.Dialog.__init__(self, id=ID_TRANSITIONCONTENTDIALOG,
       
  1696               name='ProjectDialog', parent=prnt, pos=wx.Point(376, 223),
       
  1697               size=wx.Size(350, 300), style=wx.DEFAULT_DIALOG_STYLE,
       
  1698               title=_('Edit transition'))
       
  1699         self.SetClientSize(wx.Size(350, 300))
       
  1700 
       
  1701         self.staticText1 = wx.StaticText(id=ID_TRANSITIONCONTENTDIALOGSTATICTEXT1,
       
  1702               label=_('Type:'), name='staticText1', parent=self,
       
  1703               pos=wx.Point(0, 0), size=wx.Size(0, 17), style=0)
       
  1704 
       
  1705         self.staticText2 = wx.StaticText(id=ID_TRANSITIONCONTENTDIALOGSTATICTEXT2,
       
  1706               label=_('Preview:'), name='staticText2', parent=self,
       
  1707               pos=wx.Point(0, 0), size=wx.Size(0, 17), style=0)
       
  1708 
       
  1709         self.staticText3 = wx.StaticText(id=ID_TRANSITIONCONTENTDIALOGSTATICTEXT3,
       
  1710               label=_('Priority:'), name='staticText3', parent=self,
       
  1711               pos=wx.Point(0, 0), size=wx.Size(0, 17), style=0)
       
  1712         
       
  1713         self.radioButton1 = wx.RadioButton(id=ID_TRANSITIONCONTENTDIALOGRADIOBUTTON1,
       
  1714               label=_('Reference'), name='radioButton1', parent=self,
       
  1715               pos=wx.Point(0, 0), size=wx.Size(0, 24), style=wx.RB_GROUP)
       
  1716         self.Bind(wx.EVT_RADIOBUTTON, self.OnTypeChanged, id=ID_TRANSITIONCONTENTDIALOGRADIOBUTTON1)
       
  1717         self.radioButton1.SetValue(True)
       
  1718 
       
  1719         self.Reference = wx.ComboBox(id=ID_TRANSITIONCONTENTDIALOGREFERENCE,
       
  1720               name='Reference', parent=self, pos=wx.Point(0, 0), 
       
  1721               size=wx.Size(0, 28), style=wx.CB_READONLY)
       
  1722         self.Bind(wx.EVT_COMBOBOX, self.OnReferenceChanged, id=ID_TRANSITIONCONTENTDIALOGREFERENCE)
       
  1723 
       
  1724         self.radioButton2 = wx.RadioButton(id=ID_TRANSITIONCONTENTDIALOGRADIOBUTTON2,
       
  1725               label=_('Inline'), name='radioButton2', parent=self,
       
  1726               pos=wx.Point(0, 0), size=wx.Size(0, 24), style=0)
       
  1727         self.Bind(wx.EVT_RADIOBUTTON, self.OnTypeChanged, id=ID_TRANSITIONCONTENTDIALOGRADIOBUTTON2)
       
  1728         self.radioButton2.SetValue(False)
       
  1729 
       
  1730         self.Inline = wx.TextCtrl(id=ID_TRANSITIONCONTENTDIALOGINLINE,
       
  1731               name='Inline', parent=self, pos=wx.Point(0, 0),
       
  1732               size=wx.Size(0, 24), style=0)
       
  1733         self.Bind(wx.EVT_TEXT, self.OnInlineChanged, id=ID_TRANSITIONCONTENTDIALOGINLINE)
       
  1734         self.Inline.Enable(False)
       
  1735         
       
  1736         self.radioButton3 = wx.RadioButton(id=ID_TRANSITIONCONTENTDIALOGRADIOBUTTON3,
       
  1737               label=_('Connection'), name='radioButton3', parent=self,
       
  1738               pos=wx.Point(0, 0), size=wx.Size(0, 24), style=0)
       
  1739         self.Bind(wx.EVT_RADIOBUTTON, self.OnTypeChanged, id=ID_TRANSITIONCONTENTDIALOGRADIOBUTTON3)
       
  1740         self.radioButton3.SetValue(False)
       
  1741         if not self.Connection:
       
  1742             self.radioButton3.Hide()
       
  1743 
       
  1744         self.Priority = wx.SpinCtrl(id=ID_TRANSITIONCONTENTDIALOGPRIORITY,
       
  1745               name='Priority', parent=self, pos=wx.Point(0, 0),
       
  1746               size=wx.Size(0, 24), style=wx.SP_ARROW_KEYS, min=0)
       
  1747         self.Bind(wx.EVT_TEXT, self.OnPriorityChanged, id=ID_TRANSITIONCONTENTDIALOGPRIORITY)
       
  1748 
       
  1749         self.Preview = wx.Panel(id=ID_TRANSITIONCONTENTDIALOGPREVIEW,
       
  1750               name='Preview', parent=self, pos=wx.Point(0, 0),
       
  1751               size=wx.Size(0, 0), style=wx.TAB_TRAVERSAL|wx.SIMPLE_BORDER)
       
  1752         self.Preview.SetBackgroundColour(wx.Colour(255,255,255))
       
  1753         setattr(self.Preview, "GetDrawingMode", lambda:FREEDRAWING_MODE)
       
  1754         setattr(self.Preview, "RefreshTransitionModel", lambda x:None)
       
  1755         setattr(self.Preview, "GetScaling", lambda:None)
       
  1756         setattr(self.Preview, "IsOfType", ctrler.IsOfType)
       
  1757 
       
  1758         self.Spacer = wx.Panel(id=ID_TRANSITIONCONTENTDIALOGSPACER,
       
  1759               name='Spacer', parent=self, pos=wx.Point(0, 0),
       
  1760               size=wx.Size(0, 0), style=wx.TAB_TRAVERSAL)
       
  1761 
       
  1762         self.ButtonSizer = self.CreateButtonSizer(wx.OK|wx.CANCEL|wx.CENTRE)
       
  1763         if wx.VERSION >= (2, 5, 0):
       
  1764             self.Bind(wx.EVT_BUTTON, self.OnOK, id=self.ButtonSizer.GetAffirmativeButton().GetId())
       
  1765             self.Preview.Bind(wx.EVT_PAINT, self.OnPaint)
       
  1766         else:
       
  1767             self.Bind(wx.EVT_BUTTON, self.OnOK, id=self.ButtonSizer.GetChildren()[0].GetSizer().GetChildren()[0].GetWindow().GetId())
       
  1768             wx.EVT_PAINT(self.Preview, self.OnPaint)
       
  1769         
       
  1770         self._init_sizers()
       
  1771 
       
  1772     def __init__(self, parent, controler, connection):
       
  1773         self.Connection = connection
       
  1774         self._init_ctrls(parent, controler)
       
  1775         self.Transition = None
       
  1776         self.MinTransitionSize = None
       
  1777         
       
  1778         self.Element = SFC_Transition(self.Preview)
       
  1779     
       
  1780     def SetPreviewFont(self, font):
       
  1781         self.Preview.SetFont(font)
       
  1782     
       
  1783     def SetElementSize(self, size):
       
  1784         min_width, min_height = self.Element.GetMinSize()
       
  1785         width, height = max(min_width, size[0]), max(min_height, size[1])
       
  1786         self.Element.SetSize(width, height)
       
  1787     
       
  1788     def OnOK(self, event):
       
  1789         error = []
       
  1790         if self.radioButton1.GetValue() and self.Reference.GetStringSelection() == "":
       
  1791             error.append(_("Reference"))
       
  1792         if self.radioButton2.GetValue() and self.Inline.GetValue() == "":
       
  1793             error.append(_("Inline"))
       
  1794         if len(error) > 0:
       
  1795             text = ""
       
  1796             for i, item in enumerate(error):
       
  1797                 if i == 0:
       
  1798                     text += item
       
  1799                 elif i == len(error) - 1:
       
  1800                     text += _(" and %s")%item
       
  1801                 else:
       
  1802                     text += _(", %s")%item 
       
  1803             message = wx.MessageDialog(self, _("Form isn't complete. %s must be filled!")%text, _("Error"), wx.OK|wx.ICON_ERROR)
       
  1804             message.ShowModal()
       
  1805             message.Destroy()
       
  1806         else:
       
  1807             self.EndModal(wx.ID_OK)
       
  1808 
       
  1809     def OnTypeChanged(self, event):
       
  1810         if self.radioButton1.GetValue():
       
  1811             self.Element.SetType("reference", self.Reference.GetStringSelection())
       
  1812             self.Reference.Enable(True)
       
  1813             self.Inline.Enable(False)
       
  1814         elif self.radioButton2.GetValue():
       
  1815             self.Element.SetType("inline", self.Inline.GetValue())
       
  1816             self.Reference.Enable(False)
       
  1817             self.Inline.Enable(True)
       
  1818         else:
       
  1819             self.Element.SetType("connection")
       
  1820             self.Reference.Enable(False)
       
  1821             self.Inline.Enable(False)
       
  1822         self.RefreshPreview()
       
  1823         event.Skip()
       
  1824 
       
  1825     def OnReferenceChanged(self, event):
       
  1826         self.Element.SetType("reference", self.Reference.GetStringSelection())
       
  1827         self.RefreshPreview()
       
  1828         event.Skip()
       
  1829 
       
  1830     def OnInlineChanged(self, event):
       
  1831         self.Element.SetType("inline", self.Inline.GetValue())
       
  1832         self.RefreshPreview()
       
  1833         event.Skip()
       
  1834 
       
  1835     def OnPriorityChanged(self, event):
       
  1836         self.Element.SetPriority(int(self.Priority.GetValue()))
       
  1837         self.RefreshPreview()
       
  1838         event.Skip()
       
  1839 
       
  1840     def SetTransitions(self, transitions):
       
  1841         self.Reference.Append("")
       
  1842         for transition in transitions:
       
  1843             self.Reference.Append(transition)
       
  1844 
       
  1845     def SetValues(self, values):
       
  1846         if values["type"] == "reference":
       
  1847             self.radioButton1.SetValue(True)
       
  1848             self.radioButton2.SetValue(False)
       
  1849             self.radioButton3.SetValue(False)
       
  1850             self.Reference.Enable(True)
       
  1851             self.Inline.Enable(False)
       
  1852             self.Reference.SetStringSelection(values["value"])
       
  1853             self.Element.SetType("reference", values["value"])
       
  1854         elif values["type"] == "inline":
       
  1855             self.radioButton1.SetValue(False)
       
  1856             self.radioButton2.SetValue(True)
       
  1857             self.radioButton3.SetValue(False)
       
  1858             self.Reference.Enable(False)
       
  1859             self.Inline.Enable(True)
       
  1860             self.Inline.SetValue(values["value"])
       
  1861             self.Element.SetType("inline", values["value"])
       
  1862         elif values["type"] == "connection" and self.Connection:
       
  1863             self.radioButton1.SetValue(False)
       
  1864             self.radioButton2.SetValue(False)
       
  1865             self.radioButton3.SetValue(True)
       
  1866             self.Reference.Enable(False)
       
  1867             self.Inline.Enable(False)
       
  1868             self.Element.SetType("connection")
       
  1869         self.Priority.SetValue(values["priority"])
       
  1870         self.Element.SetPriority(values["priority"])
       
  1871         self.RefreshPreview()
       
  1872         
       
  1873     def GetValues(self):
       
  1874         values = {"priority" : int(self.Priority.GetValue())}
       
  1875         if self.radioButton1.GetValue():
       
  1876             values["type"] = "reference"
       
  1877             values["value"] = self.Reference.GetStringSelection()
       
  1878         elif self.radioButton2.GetValue():
       
  1879             values["type"] = "inline"
       
  1880             values["value"] = self.Inline.GetValue()
       
  1881         else:
       
  1882             values["type"] = "connection"
       
  1883             values["value"] = None
       
  1884         return values
       
  1885 
       
  1886     def RefreshPreview(self):
       
  1887         dc = wx.ClientDC(self.Preview)
       
  1888         dc.SetFont(self.Preview.GetFont())
       
  1889         dc.Clear()
       
  1890         clientsize = self.Preview.GetClientSize()
       
  1891         posx, posy = self.Element.GetPosition()
       
  1892         rect = self.Element.GetBoundingBox()
       
  1893         diffx, diffy = posx - rect.x, posy - rect.y
       
  1894         self.Element.SetPosition((clientsize.width - rect.width) / 2 + diffx, (clientsize.height - rect.height) / 2 + diffy)
       
  1895         self.Element.Draw(dc)
       
  1896 
       
  1897     def OnPaint(self, event):
       
  1898         self.RefreshPreview()
       
  1899         event.Skip()
       
  1900 
       
  1901 #-------------------------------------------------------------------------------
       
  1902 #                         Create New Divergence Dialog
       
  1903 #-------------------------------------------------------------------------------
       
  1904 
       
  1905 [ID_DIVERGENCECREATEDIALOG, ID_DIVERGENCECREATEDIALOGSPACER, 
       
  1906  ID_DIVERGENCECREATEDIALOGRADIOBUTTON1, ID_DIVERGENCECREATEDIALOGRADIOBUTTON2,
       
  1907  ID_DIVERGENCECREATEDIALOGRADIOBUTTON3, ID_DIVERGENCECREATEDIALOGRADIOBUTTON4, 
       
  1908  ID_DIVERGENCECREATEDIALOGSEQUENCES, ID_DIVERGENCECREATEDIALOGPREVIEW, 
       
  1909  ID_DIVERGENCECREATEDIALOGSTATICTEXT1, ID_DIVERGENCECREATEDIALOGSTATICTEXT2, 
       
  1910  ID_DIVERGENCECREATEDIALOGSTATICTEXT3,  
       
  1911 ] = [wx.NewId() for _init_ctrls in range(11)]
       
  1912 
       
  1913 class DivergenceCreateDialog(wx.Dialog):
       
  1914     
       
  1915     if wx.VERSION < (2, 6, 0):
       
  1916         def Bind(self, event, function, id = None):
       
  1917             if id is not None:
       
  1918                 event(self, id, function)
       
  1919             else:
       
  1920                 event(self, function)
       
  1921     
       
  1922     def _init_coll_flexGridSizer1_Items(self, parent):
       
  1923         parent.AddSizer(self.MainSizer, 0, border=20, flag=wx.GROW|wx.TOP|wx.LEFT|wx.RIGHT)
       
  1924         parent.AddSizer(self.ButtonSizer, 0, border=20, flag=wx.ALIGN_RIGHT|wx.BOTTOM|wx.LEFT|wx.RIGHT)
       
  1925         
       
  1926     def _init_coll_flexGridSizer1_Growables(self, parent):
       
  1927         parent.AddGrowableCol(0)
       
  1928         parent.AddGrowableRow(0)
       
  1929     
       
  1930     def _init_coll_MainSizer_Items(self, parent):
       
  1931         parent.AddSizer(self.LeftGridSizer, 1, border=5, flag=wx.GROW|wx.RIGHT)
       
  1932         parent.AddSizer(self.RightGridSizer, 1, border=5, flag=wx.GROW|wx.LEFT)
       
  1933     
       
  1934     def _init_coll_LeftGridSizer_Items(self, parent):
       
  1935         parent.AddWindow(self.staticText1, 0, border=0, flag=wx.GROW)
       
  1936         parent.AddWindow(self.radioButton1, 0, border=0, flag=wx.GROW)
       
  1937         parent.AddWindow(self.radioButton2, 0, border=0, flag=wx.GROW)
       
  1938         parent.AddWindow(self.radioButton3, 0, border=0, flag=wx.GROW)
       
  1939         parent.AddWindow(self.radioButton4, 0, border=0, flag=wx.GROW)
       
  1940         parent.AddWindow(self.staticText2, 0, border=0, flag=wx.GROW)
       
  1941         parent.AddWindow(self.Sequences, 0, border=0, flag=wx.GROW)
       
  1942         parent.AddWindow(self.Spacer, 0, border=0, flag=wx.GROW)
       
  1943     
       
  1944     def _init_coll_LeftGridSizer_Growables(self, parent):
       
  1945         parent.AddGrowableCol(0)
       
  1946         parent.AddGrowableRow(7)
       
  1947             
       
  1948     def _init_coll_RightGridSizer_Items(self, parent):
       
  1949         parent.AddWindow(self.staticText3, 0, border=0, flag=wx.GROW)
       
  1950         parent.AddWindow(self.Preview, 0, border=0, flag=wx.GROW)
       
  1951         
       
  1952     def _init_coll_RightGridSizer_Growables(self, parent):
       
  1953         parent.AddGrowableCol(0)
       
  1954         parent.AddGrowableRow(1)
       
  1955 
       
  1956     def _init_sizers(self):
       
  1957         self.flexGridSizer1 = wx.FlexGridSizer(cols=1, hgap=0, rows=2, vgap=10)
       
  1958         self.MainSizer = wx.BoxSizer(wx.HORIZONTAL)
       
  1959         self.LeftGridSizer = wx.FlexGridSizer(cols=1, hgap=0, rows=8, vgap=5)
       
  1960         self.RightGridSizer = wx.FlexGridSizer(cols=1, hgap=0, rows=2, vgap=5)
       
  1961 
       
  1962         self._init_coll_flexGridSizer1_Items(self.flexGridSizer1)
       
  1963         self._init_coll_flexGridSizer1_Growables(self.flexGridSizer1)
       
  1964         self._init_coll_MainSizer_Items(self.MainSizer)
       
  1965         self._init_coll_LeftGridSizer_Items(self.LeftGridSizer)
       
  1966         self._init_coll_LeftGridSizer_Growables(self.LeftGridSizer)
       
  1967         self._init_coll_RightGridSizer_Items(self.RightGridSizer)
       
  1968         self._init_coll_RightGridSizer_Growables(self.RightGridSizer)
       
  1969 
       
  1970         self.SetSizer(self.flexGridSizer1)
       
  1971     
       
  1972     def _init_ctrls(self, prnt, ctrler):
       
  1973         wx.Dialog.__init__(self, id=ID_DIVERGENCECREATEDIALOG,
       
  1974               name='DivergencePropertiesDialog', parent=prnt, pos=wx.Point(376, 223),
       
  1975               size=wx.Size(500, 300), style=wx.DEFAULT_DIALOG_STYLE,
       
  1976               title=_('Create a new divergence or convergence'))
       
  1977         self.SetClientSize(wx.Size(500, 300))
       
  1978 
       
  1979         self.staticText1 = wx.StaticText(id=ID_DIVERGENCECREATEDIALOGSTATICTEXT1,
       
  1980               label=_('Type:'), name='staticText1', parent=self,
       
  1981               pos=wx.Point(0, 0), size=wx.Size(0, 17), style=0)
       
  1982 
       
  1983         self.radioButton1 = wx.RadioButton(id=ID_DIVERGENCECREATEDIALOGRADIOBUTTON1,
       
  1984               label=_('Selection Divergence'), name='radioButton1', parent=self,
       
  1985               pos=wx.Point(0, 0), size=wx.Size(0, 24), style=wx.RB_GROUP)
       
  1986         self.Bind(wx.EVT_RADIOBUTTON, self.OnTypeChanged, id=ID_DIVERGENCECREATEDIALOGRADIOBUTTON1)
       
  1987         self.radioButton1.SetValue(True)
       
  1988 
       
  1989         self.radioButton2 = wx.RadioButton(id=ID_DIVERGENCECREATEDIALOGRADIOBUTTON2,
       
  1990               label=_('Selection Convergence'), name='radioButton2', parent=self, 
       
  1991               pos=wx.Point(0, 0), size=wx.Size(0, 24), style=0)
       
  1992         self.Bind(wx.EVT_RADIOBUTTON, self.OnTypeChanged, id=ID_DIVERGENCECREATEDIALOGRADIOBUTTON2)
       
  1993         self.radioButton2.SetValue(False)
       
  1994 
       
  1995         self.radioButton3 = wx.RadioButton(id=ID_DIVERGENCECREATEDIALOGRADIOBUTTON3,
       
  1996               label=_('Simultaneous Divergence'), name='radioButton3', parent=self,
       
  1997               pos=wx.Point(0, 0), size=wx.Size(0, 24), style=0)
       
  1998         self.Bind(wx.EVT_RADIOBUTTON, self.OnTypeChanged, id=ID_DIVERGENCECREATEDIALOGRADIOBUTTON3)
       
  1999         self.radioButton3.SetValue(False)
       
  2000 
       
  2001         self.radioButton4 = wx.RadioButton(id=ID_DIVERGENCECREATEDIALOGRADIOBUTTON4,
       
  2002               label=_('Simultaneous Convergence'), name='radioButton4', parent=self, 
       
  2003               pos=wx.Point(0, 0), size=wx.Size(0, 24), style=0)
       
  2004         self.Bind(wx.EVT_RADIOBUTTON, self.OnTypeChanged, id=ID_DIVERGENCECREATEDIALOGRADIOBUTTON4)
       
  2005         self.radioButton4.SetValue(False)
       
  2006 
       
  2007         self.staticText2 = wx.StaticText(id=ID_DIVERGENCECREATEDIALOGSTATICTEXT2,
       
  2008               label=_('Number of sequences:'), name='staticText2', parent=self,
       
  2009               pos=wx.Point(0, 0), size=wx.Size(0, 17), style=0)
       
  2010 
       
  2011         self.Sequences = wx.SpinCtrl(id=ID_DIVERGENCECREATEDIALOGSEQUENCES,
       
  2012               name='Sequences', parent=self, pos=wx.Point(0, 0),
       
  2013               size=wx.Size(0, 24), style=0, min=2, max=20)
       
  2014         self.Bind(wx.EVT_SPINCTRL, self.OnSequencesChanged, id=ID_DIVERGENCECREATEDIALOGSEQUENCES)
       
  2015 
       
  2016         self.staticText3 = wx.StaticText(id=ID_DIVERGENCECREATEDIALOGSTATICTEXT3,
       
  2017               label=_('Preview:'), name='staticText3', parent=self,
       
  2018               pos=wx.Point(0, 0), size=wx.Size(0, 17), style=0)
       
  2019 
       
  2020         self.Preview = wx.Panel(id=ID_DIVERGENCECREATEDIALOGPREVIEW,
       
  2021               name='Preview', parent=self, pos=wx.Point(0, 0),
       
  2022               size=wx.Size(0, 0), style=wx.TAB_TRAVERSAL|wx.SIMPLE_BORDER)
       
  2023         self.Preview.SetBackgroundColour(wx.Colour(255,255,255))
       
  2024         setattr(self.Preview, "GetDrawingMode", lambda:FREEDRAWING_MODE)
       
  2025         setattr(self.Preview, "IsOfType", ctrler.IsOfType)
       
  2026 
       
  2027         self.Spacer = wx.Panel(id=ID_TRANSITIONCONTENTDIALOGSPACER,
       
  2028               name='Spacer', parent=self, pos=wx.Point(0, 0),
       
  2029               size=wx.Size(0, 0), style=wx.TAB_TRAVERSAL)
       
  2030 
       
  2031         self.ButtonSizer = self.CreateButtonSizer(wx.OK|wx.CANCEL|wx.CENTRE)
       
  2032         
       
  2033         if wx.VERSION >= (2, 5, 0):
       
  2034             self.Preview.Bind(wx.EVT_PAINT, self.OnPaint)
       
  2035         else:
       
  2036             wx.EVT_PAINT(self.Preview, self.OnPaint)
       
  2037         
       
  2038         self._init_sizers()
       
  2039 
       
  2040     def __init__(self, parent, controler):
       
  2041         self._init_ctrls(parent, controler)
       
  2042         
       
  2043         self.Divergence = None
       
  2044         self.MinSize = (0, 0)
       
  2045     
       
  2046     def SetPreviewFont(self, font):
       
  2047         self.Preview.SetFont(font)
       
  2048     
       
  2049     def GetValues(self):
       
  2050         values = {}
       
  2051         if self.radioButton1.GetValue():
       
  2052             values["type"] = SELECTION_DIVERGENCE
       
  2053         elif self.radioButton2.GetValue():
       
  2054             values["type"] = SELECTION_CONVERGENCE
       
  2055         elif self.radioButton3.GetValue():
       
  2056             values["type"] = SIMULTANEOUS_DIVERGENCE
       
  2057         else:
       
  2058             values["type"] = SIMULTANEOUS_CONVERGENCE
       
  2059         values["number"] = self.Sequences.GetValue()
       
  2060         return values
       
  2061 
       
  2062     def SetMinSize(self, size):
       
  2063         self.MinSize = size
       
  2064 
       
  2065     def OnTypeChanged(self, event):
       
  2066         self.RefreshPreview()
       
  2067         event.Skip()
       
  2068 
       
  2069     def OnSequencesChanged(self, event):
       
  2070         self.RefreshPreview()
       
  2071         event.Skip()
       
  2072         
       
  2073     def RefreshPreview(self):
       
  2074         dc = wx.ClientDC(self.Preview)
       
  2075         dc.SetFont(self.Preview.GetFont())
       
  2076         dc.Clear()
       
  2077         if self.radioButton1.GetValue():
       
  2078             self.Divergence = SFC_Divergence(self.Preview, SELECTION_DIVERGENCE, self.Sequences.GetValue())
       
  2079         elif self.radioButton2.GetValue():
       
  2080             self.Divergence = SFC_Divergence(self.Preview, SELECTION_CONVERGENCE, self.Sequences.GetValue())
       
  2081         elif self.radioButton3.GetValue():
       
  2082             self.Divergence = SFC_Divergence(self.Preview, SIMULTANEOUS_DIVERGENCE, self.Sequences.GetValue())
       
  2083         else:
       
  2084             self.Divergence = SFC_Divergence(self.Preview, SIMULTANEOUS_CONVERGENCE, self.Sequences.GetValue())
       
  2085         width, height = self.Divergence.GetSize()
       
  2086         min_width, min_height = max(width, self.MinSize[0]), max(height, self.MinSize[1])
       
  2087         self.Divergence.SetSize(min_width, min_height)
       
  2088         clientsize = self.Preview.GetClientSize()
       
  2089         x = (clientsize.width - min_width) / 2
       
  2090         y = (clientsize.height - min_height) / 2
       
  2091         self.Divergence.SetPosition(x, y)
       
  2092         self.Divergence.Draw(dc)
       
  2093 
       
  2094     def OnPaint(self, event):
       
  2095         self.RefreshPreview()
       
  2096         event.Skip()
       
  2097 
       
  2098 
       
  2099 #-------------------------------------------------------------------------------
       
  2100 #                            Action Block Dialog
       
  2101 #-------------------------------------------------------------------------------
       
  2102 
       
  2103 def GetActionTableColnames():
       
  2104     _ = lambda x: x
       
  2105     return [_("Qualifier"), _("Duration"), _("Type"), _("Value"), _("Indicator")]
       
  2106 
       
  2107 def GetTypeList():
       
  2108     _ = lambda x: x
       
  2109     return [_("Action"), _("Variable"), _("Inline")]
       
  2110 
       
  2111 class ActionTable(wx.grid.PyGridTableBase):
       
  2112     
       
  2113     """
       
  2114     A custom wx.Grid Table using user supplied data
       
  2115     """
       
  2116     def __init__(self, parent, data, colnames):
       
  2117         # The base class must be initialized *first*
       
  2118         wx.grid.PyGridTableBase.__init__(self)
       
  2119         self.data = data
       
  2120         self.colnames = colnames
       
  2121         self.Parent = parent
       
  2122         # XXX
       
  2123         # we need to store the row length and collength to
       
  2124         # see if the table has changed size
       
  2125         self._rows = self.GetNumberRows()
       
  2126         self._cols = self.GetNumberCols()
       
  2127     
       
  2128     def GetNumberCols(self):
       
  2129         return len(self.colnames)
       
  2130         
       
  2131     def GetNumberRows(self):
       
  2132         return len(self.data)
       
  2133 
       
  2134     def GetColLabelValue(self, col, translate=True):
       
  2135         if col < len(self.colnames):
       
  2136             colname = self.colnames[col]
       
  2137             if translate:
       
  2138 		return _(colname)
       
  2139 	    return colname
       
  2140 
       
  2141     def GetRowLabelValues(self, row, translate=True):
       
  2142         return row
       
  2143 
       
  2144     def GetValue(self, row, col):
       
  2145         if row < self.GetNumberRows():
       
  2146             colname = self.GetColLabelValue(col, False)
       
  2147             name = str(self.data[row].get(colname, ""))
       
  2148             if colname == "Type":
       
  2149                 return _(name)
       
  2150             return name
       
  2151     
       
  2152     def GetValueByName(self, row, colname):
       
  2153         return self.data[row].get(colname)
       
  2154 
       
  2155     def SetValue(self, row, col, value):
       
  2156         if col < len(self.colnames):
       
  2157             colname = self.GetColLabelValue(col, False)
       
  2158             if colname == "Type":
       
  2159                 value = self.Parent.TranslateType[value]
       
  2160             self.data[row][colname] = value
       
  2161         
       
  2162     def ResetView(self, grid):
       
  2163         """
       
  2164         (wx.Grid) -> Reset the grid view.   Call this to
       
  2165         update the grid if rows and columns have been added or deleted
       
  2166         """
       
  2167         grid.BeginBatch()
       
  2168         for current, new, delmsg, addmsg in [
       
  2169             (self._rows, self.GetNumberRows(), wx.grid.GRIDTABLE_NOTIFY_ROWS_DELETED, wx.grid.GRIDTABLE_NOTIFY_ROWS_APPENDED),
       
  2170             (self._cols, self.GetNumberCols(), wx.grid.GRIDTABLE_NOTIFY_COLS_DELETED, wx.grid.GRIDTABLE_NOTIFY_COLS_APPENDED),
       
  2171         ]:
       
  2172             if new < current:
       
  2173                 msg = wx.grid.GridTableMessage(self,delmsg,new,current-new)
       
  2174                 grid.ProcessTableMessage(msg)
       
  2175             elif new > current:
       
  2176                 msg = wx.grid.GridTableMessage(self,addmsg,new-current)
       
  2177                 grid.ProcessTableMessage(msg)
       
  2178                 self.UpdateValues(grid)
       
  2179         grid.EndBatch()
       
  2180 
       
  2181         self._rows = self.GetNumberRows()
       
  2182         self._cols = self.GetNumberCols()
       
  2183         # update the column rendering scheme
       
  2184         self._updateColAttrs(grid)
       
  2185 
       
  2186         # update the scrollbars and the displayed part of the grid
       
  2187         grid.AdjustScrollbars()
       
  2188         grid.ForceRefresh()
       
  2189 
       
  2190     def UpdateValues(self, grid):
       
  2191         """Update all displayed values"""
       
  2192         # This sends an event to the grid table to update all of the values
       
  2193         msg = wx.grid.GridTableMessage(self, wx.grid.GRIDTABLE_REQUEST_VIEW_GET_VALUES)
       
  2194         grid.ProcessTableMessage(msg)
       
  2195 
       
  2196     def _updateColAttrs(self, grid):
       
  2197         """
       
  2198         wx.Grid -> update the column attributes to add the
       
  2199         appropriate renderer given the column name.
       
  2200 
       
  2201         Otherwise default to the default renderer.
       
  2202         """
       
  2203         
       
  2204         for row in range(self.GetNumberRows()):
       
  2205             for col in range(self.GetNumberCols()):
       
  2206                 editor = None
       
  2207                 renderer = None
       
  2208                 readonly = False
       
  2209                 colname = self.GetColLabelValue(col, False)
       
  2210                 if colname == "Qualifier":
       
  2211                     editor = wx.grid.GridCellChoiceEditor()
       
  2212                     editor.SetParameters(self.Parent.QualifierList)
       
  2213                 if colname == "Duration":
       
  2214                     editor = wx.grid.GridCellTextEditor()
       
  2215                     renderer = wx.grid.GridCellStringRenderer()
       
  2216                     if self.Parent.DurationList[self.data[row]["Qualifier"]]:
       
  2217                         readonly = False
       
  2218                     else:
       
  2219                         readonly = True
       
  2220                         self.data[row]["Duration"] = ""
       
  2221                 elif colname == "Type":
       
  2222                     editor = wx.grid.GridCellChoiceEditor()
       
  2223                     editor.SetParameters(self.Parent.TypeList)
       
  2224                 elif colname == "Value":
       
  2225                     type = self.data[row]["Type"]
       
  2226                     if type == "Action":
       
  2227                         editor = wx.grid.GridCellChoiceEditor()
       
  2228                         editor.SetParameters(self.Parent.ActionList)
       
  2229                     elif type == "Variable":
       
  2230                         editor = wx.grid.GridCellChoiceEditor()
       
  2231                         editor.SetParameters(self.Parent.VariableList)
       
  2232                     elif type == "Inline":
       
  2233                         editor = wx.grid.GridCellTextEditor()
       
  2234                         renderer = wx.grid.GridCellStringRenderer()
       
  2235                 elif colname == "Indicator":
       
  2236                     editor = wx.grid.GridCellChoiceEditor()
       
  2237                     editor.SetParameters(self.Parent.VariableList)
       
  2238                     
       
  2239                 grid.SetCellEditor(row, col, editor)
       
  2240                 grid.SetCellRenderer(row, col, renderer)
       
  2241                 grid.SetReadOnly(row, col, readonly)
       
  2242                 
       
  2243                 grid.SetCellBackgroundColour(row, col, wx.WHITE)
       
  2244     
       
  2245     def SetData(self, data):
       
  2246         self.data = data
       
  2247     
       
  2248     def GetData(self):
       
  2249         return self.data
       
  2250     
       
  2251     def GetCurrentIndex(self):
       
  2252         return self.CurrentIndex
       
  2253     
       
  2254     def SetCurrentIndex(self, index):
       
  2255         self.CurrentIndex = index
       
  2256     
       
  2257     def AppendRow(self, row_content):
       
  2258         self.data.append(row_content)
       
  2259 
       
  2260     def RemoveRow(self, row_index):
       
  2261         self.data.pop(row_index)
       
  2262         
       
  2263     def MoveRow(self, row_index, move, grid):
       
  2264         new_index = max(0, min(row_index + move, len(self.data) - 1))
       
  2265         if new_index != row_index:
       
  2266             self.data.insert(new_index, self.data.pop(row_index))
       
  2267             grid.SetGridCursor(new_index, grid.GetGridCursorCol())
       
  2268 
       
  2269     def Empty(self):
       
  2270         self.data = []
       
  2271         self.editors = []
       
  2272 
       
  2273 [ID_ACTIONBLOCKDIALOG, ID_ACTIONBLOCKDIALOGVARIABLESGRID, 
       
  2274  ID_ACTIONBLOCKDIALOGSTATICTEXT1, ID_ACTIONBLOCKDIALOGADDBUTTON,
       
  2275  ID_ACTIONBLOCKDIALOGDELETEBUTTON, ID_ACTIONBLOCKDIALOGUPBUTTON, 
       
  2276  ID_ACTIONBLOCKDIALOGDOWNBUTTON, 
       
  2277 ] = [wx.NewId() for _init_ctrls in range(7)]
       
  2278 
       
  2279 class ActionBlockDialog(wx.Dialog):
       
  2280     
       
  2281     if wx.VERSION < (2, 6, 0):
       
  2282         def Bind(self, event, function, id = None):
       
  2283             if id is not None:
       
  2284                 event(self, id, function)
       
  2285             else:
       
  2286                 event(self, function)
       
  2287     
       
  2288     def _init_coll_flexGridSizer1_Items(self, parent):
       
  2289         parent.AddSizer(self.TopSizer, 0, border=20, flag=wx.GROW|wx.TOP|wx.LEFT|wx.RIGHT)
       
  2290         parent.AddSizer(self.GridButtonSizer, 0, border=20, flag=wx.ALIGN_RIGHT|wx.LEFT|wx.RIGHT)
       
  2291         parent.AddSizer(self.ButtonSizer, 0, border=20, flag=wx.ALIGN_RIGHT|wx.BOTTOM|wx.LEFT|wx.RIGHT)
       
  2292         
       
  2293     def _init_coll_flexGridSizer1_Growables(self, parent):
       
  2294         parent.AddGrowableCol(0)
       
  2295         parent.AddGrowableRow(0)
       
  2296         
       
  2297     def _init_coll_TopSizer_Items(self, parent):
       
  2298         parent.AddWindow(self.staticText1, 0, border=0, flag=wx.GROW)
       
  2299         parent.AddWindow(self.ActionsGrid, 0, border=0, flag=wx.GROW)
       
  2300     
       
  2301     def _init_coll_TopSizer_Growables(self, parent):
       
  2302         parent.AddGrowableCol(0)
       
  2303         parent.AddGrowableRow(1)
       
  2304 
       
  2305     def _init_coll_GridButtonSizer_Items(self, parent):
       
  2306         parent.AddWindow(self.AddButton, 0, border=10, flag=wx.GROW|wx.LEFT)
       
  2307         parent.AddWindow(self.DeleteButton, 0, border=10, flag=wx.GROW|wx.LEFT)
       
  2308         parent.AddWindow(self.UpButton, 0, border=10, flag=wx.GROW|wx.LEFT)
       
  2309         parent.AddWindow(self.DownButton, 0, border=10, flag=wx.GROW|wx.LEFT)
       
  2310 
       
  2311     def _init_sizers(self):
       
  2312         self.flexGridSizer1 = wx.FlexGridSizer(cols=1, hgap=0, rows=3, vgap=10)
       
  2313         self.TopSizer = wx.FlexGridSizer(cols=1, hgap=0, rows=2, vgap=5)
       
  2314         self.GridButtonSizer = wx.BoxSizer(wx.HORIZONTAL)
       
  2315         
       
  2316         self._init_coll_flexGridSizer1_Items(self.flexGridSizer1)
       
  2317         self._init_coll_flexGridSizer1_Growables(self.flexGridSizer1)
       
  2318         self._init_coll_TopSizer_Items(self.TopSizer)
       
  2319         self._init_coll_TopSizer_Growables(self.TopSizer)
       
  2320         self._init_coll_GridButtonSizer_Items(self.GridButtonSizer)
       
  2321         
       
  2322         self.SetSizer(self.flexGridSizer1)
       
  2323     
       
  2324     def _init_ctrls(self, prnt):
       
  2325         wx.Dialog.__init__(self, id=ID_ACTIONBLOCKDIALOG,
       
  2326               name='ActionBlockDialog', parent=prnt, pos=wx.Point(376, 223),
       
  2327               size=wx.Size(500, 300), style=wx.DEFAULT_DIALOG_STYLE|wx.RESIZE_BORDER,
       
  2328               title=_('Edit action block properties'))
       
  2329         self.SetClientSize(wx.Size(500, 300))
       
  2330 
       
  2331         self.staticText1 = wx.StaticText(id=ID_ACTIONBLOCKDIALOGSTATICTEXT1,
       
  2332               label=_('Actions:'), name='staticText1', parent=self,
       
  2333               pos=wx.Point(0, 0), size=wx.Size(0, 17), style=0)
       
  2334 
       
  2335         self.ActionsGrid = wx.grid.Grid(id=ID_ACTIONBLOCKDIALOGVARIABLESGRID,
       
  2336               name='ActionsGrid', parent=self, pos=wx.Point(0, 0), 
       
  2337               size=wx.Size(0, 0), style=wx.VSCROLL)
       
  2338         self.ActionsGrid.SetFont(wx.Font(12, 77, wx.NORMAL, wx.NORMAL, False,
       
  2339               'Sans'))
       
  2340         self.ActionsGrid.SetLabelFont(wx.Font(10, 77, wx.NORMAL, wx.NORMAL,
       
  2341               False, 'Sans'))
       
  2342         self.ActionsGrid.DisableDragGridSize()
       
  2343         self.ActionsGrid.EnableScrolling(False, True)
       
  2344         self.ActionsGrid.Bind(wx.grid.EVT_GRID_CELL_CHANGE, self.OnActionsGridCellChange)
       
  2345 
       
  2346         self.AddButton = wx.Button(id=ID_ACTIONBLOCKDIALOGADDBUTTON, label=_('Add'),
       
  2347               name='AddButton', parent=self, pos=wx.Point(0, 0),
       
  2348               size=wx.DefaultSize, style=0)
       
  2349         self.Bind(wx.EVT_BUTTON, self.OnAddButton, id=ID_ACTIONBLOCKDIALOGADDBUTTON)
       
  2350 
       
  2351         self.DeleteButton = wx.Button(id=ID_ACTIONBLOCKDIALOGDELETEBUTTON, label=_('Delete'),
       
  2352               name='DeleteButton', parent=self, pos=wx.Point(0, 0),
       
  2353               size=wx.DefaultSize, style=0)
       
  2354         self.Bind(wx.EVT_BUTTON, self.OnDeleteButton, id=ID_ACTIONBLOCKDIALOGDELETEBUTTON)
       
  2355 
       
  2356         self.UpButton = wx.Button(id=ID_ACTIONBLOCKDIALOGUPBUTTON, label='^',
       
  2357               name='UpButton', parent=self, pos=wx.Point(0, 0),
       
  2358               size=wx.Size(32, 32), style=0)
       
  2359         self.Bind(wx.EVT_BUTTON, self.OnUpButton, id=ID_ACTIONBLOCKDIALOGUPBUTTON)
       
  2360 
       
  2361         self.DownButton = wx.Button(id=ID_ACTIONBLOCKDIALOGDOWNBUTTON, label='v',
       
  2362               name='DownButton', parent=self, pos=wx.Point(0, 0),
       
  2363               size=wx.Size(32, 32), style=0)
       
  2364         self.Bind(wx.EVT_BUTTON, self.OnDownButton, id=ID_ACTIONBLOCKDIALOGDOWNBUTTON)
       
  2365 
       
  2366         self.ButtonSizer = self.CreateButtonSizer(wx.OK|wx.CANCEL|wx.CENTRE)
       
  2367         if wx.VERSION >= (2, 5, 0):
       
  2368             self.Bind(wx.EVT_BUTTON, self.OnOK, id=self.ButtonSizer.GetAffirmativeButton().GetId())
       
  2369         else:
       
  2370             self.Bind(wx.EVT_BUTTON, self.OnOK, id=self.ButtonSizer.GetChildren()[0].GetSizer().GetChildren()[0].GetWindow().GetId())
       
  2371         
       
  2372         self._init_sizers()
       
  2373 
       
  2374     def __init__(self, parent):
       
  2375         self._init_ctrls(parent)
       
  2376         
       
  2377         self.DefaultValue = {"Qualifier" : "N", "Duration" : "", "Type" : "Action", "Value" : "", "Indicator" : ""}
       
  2378         self.Table = ActionTable(self, [], GetActionTableColnames())
       
  2379         typelist = GetTypeList()       
       
  2380         self.TypeList = ",".join(map(_,typelist))
       
  2381         self.TranslateType = dict([(_(value), value) for value in typelist])
       
  2382         self.ColSizes = [60, 90, 80, 110, 80]
       
  2383         self.ColAlignements = [wx.ALIGN_LEFT, wx.ALIGN_LEFT, wx.ALIGN_LEFT, wx.ALIGN_LEFT, wx.ALIGN_LEFT]
       
  2384         
       
  2385         self.ActionsGrid.SetTable(self.Table)
       
  2386         self.ActionsGrid.SetRowLabelSize(0)
       
  2387         
       
  2388         for col in range(self.Table.GetNumberCols()):
       
  2389             attr = wx.grid.GridCellAttr()
       
  2390             attr.SetAlignment(self.ColAlignements[col], wx.ALIGN_CENTRE)
       
  2391             self.ActionsGrid.SetColAttr(col, attr)
       
  2392             self.ActionsGrid.SetColMinimalWidth(col, self.ColSizes[col])
       
  2393             self.ActionsGrid.AutoSizeColumn(col, False)
       
  2394         
       
  2395         self.Table.ResetView(self.ActionsGrid)
       
  2396 
       
  2397     def OnOK(self, event):
       
  2398         self.ActionsGrid.SetGridCursor(0, 0)
       
  2399         self.EndModal(wx.ID_OK)
       
  2400 
       
  2401     def OnAddButton(self, event):
       
  2402         self.Table.AppendRow(self.DefaultValue.copy())
       
  2403         self.Table.ResetView(self.ActionsGrid)
       
  2404         event.Skip()
       
  2405 
       
  2406     def OnDeleteButton(self, event):
       
  2407         row = self.ActionsGrid.GetGridCursorRow()
       
  2408         self.Table.RemoveRow(row)
       
  2409         self.Table.ResetView(self.ActionsGrid)
       
  2410         event.Skip()
       
  2411 
       
  2412     def OnUpButton(self, event):
       
  2413         row = self.ActionsGrid.GetGridCursorRow()
       
  2414         self.Table.MoveRow(row, -1, self.ActionsGrid)
       
  2415         self.Table.ResetView(self.ActionsGrid)
       
  2416         event.Skip()
       
  2417 
       
  2418     def OnDownButton(self, event):
       
  2419         row = self.ActionsGrid.GetGridCursorRow()
       
  2420         self.Table.MoveRow(row, 1, self.ActionsGrid)
       
  2421         self.Table.ResetView(self.ActionsGrid)
       
  2422         event.Skip()
       
  2423 
       
  2424     def OnActionsGridCellChange(self, event):
       
  2425         self.Table.ResetView(self.ActionsGrid)
       
  2426         event.Skip()
       
  2427 
       
  2428     def SetQualifierList(self, list):
       
  2429         self.QualifierList = "," + ",".join(list)
       
  2430         self.DurationList = list
       
  2431 
       
  2432     def SetVariableList(self, list):
       
  2433         self.VariableList = "," + ",".join([variable["Name"] for variable in list])
       
  2434         
       
  2435     def SetActionList(self, list):
       
  2436         self.ActionList = "," + ",".join(list)
       
  2437 
       
  2438     def SetValues(self, actions):
       
  2439         for action in actions:
       
  2440             row = {"Qualifier" : action["qualifier"], "Value" : action["value"]}
       
  2441             if action["type"] == "reference":
       
  2442                 if action["value"] in self.ActionList:
       
  2443                     row["Type"] = "Action"
       
  2444                 elif action["value"] in self.VariableList:
       
  2445                     row["Type"] = "Variable"
       
  2446                 else:
       
  2447                     row["Type"] = "Inline"
       
  2448             else:
       
  2449                 row["Type"] = "Inline"
       
  2450             if "duration" in action:
       
  2451                 row["Duration"] = action["duration"]
       
  2452             else:
       
  2453                 row["Duration"] = ""
       
  2454             if "indicator" in action:
       
  2455                 row["Indicator"] = action["indicator"]
       
  2456             else:
       
  2457                 row["Indicator"] = ""
       
  2458             self.Table.AppendRow(row)
       
  2459         self.Table.ResetView(self.ActionsGrid)
       
  2460     
       
  2461     def GetValues(self):
       
  2462         values = []
       
  2463         for data in self.Table.GetData():
       
  2464             action = {"qualifier" : data["Qualifier"], "value" : data["Value"]}
       
  2465             if data["Type"] in ["Action", "Variable"]:
       
  2466                 action["type"] = "reference"
       
  2467             else:
       
  2468                 action["type"] = "inline"
       
  2469             if data["Duration"] != "":
       
  2470                 action["duration"] = data["Duration"]
       
  2471             if data["Indicator"] != "":
       
  2472                 action["indicator"] = data["Indicator"]
       
  2473             values.append(action)
       
  2474         return values
       
  2475 
       
  2476 
       
  2477 #-------------------------------------------------------------------------------
       
  2478 #                          Edit Step Name Dialog
       
  2479 #-------------------------------------------------------------------------------
       
  2480 
       
  2481 class StepNameDialog(wx.TextEntryDialog):
       
  2482 
       
  2483     if wx.VERSION < (2, 6, 0):
       
  2484         def Bind(self, event, function, id = None):
       
  2485             if id is not None:
       
  2486                 event(self, id, function)
       
  2487             else:
       
  2488                 event(self, function)
       
  2489     
       
  2490 
       
  2491     def __init__(self, parent, message, caption = "Please enter text", defaultValue = "", 
       
  2492                        style = wx.OK|wx.CANCEL|wx.CENTRE, pos = wx.DefaultPosition):
       
  2493         wx.TextEntryDialog.__init__(self, parent, message, caption, defaultValue, style, pos)
       
  2494         
       
  2495         self.PouNames = []
       
  2496         self.Variables = []
       
  2497         self.StepNames = []
       
  2498         if wx.VERSION >= (2, 8, 0):
       
  2499             self.Bind(wx.EVT_BUTTON, self.OnOK, id=self.GetSizer().GetItem(2).GetSizer().GetItem(1).GetSizer().GetAffirmativeButton().GetId())
       
  2500         elif wx.VERSION >= (2, 6, 0):
       
  2501             self.Bind(wx.EVT_BUTTON, self.OnOK, id=self.GetSizer().GetItem(3).GetSizer().GetAffirmativeButton().GetId())
       
  2502         else:
       
  2503             self.Bind(wx.EVT_BUTTON, self.OnOK, id=self.GetSizer().GetItem(3).GetSizer().GetChildren()[0].GetSizer().GetChildren()[0].GetWindow().GetId())
       
  2504     
       
  2505     def OnOK(self, event):
       
  2506         step_name = self.GetSizer().GetItem(1).GetWindow().GetValue()
       
  2507         if step_name == "":
       
  2508             message = wx.MessageDialog(self, _("You must type a name!"), _("Error"), wx.OK|wx.ICON_ERROR)
       
  2509             message.ShowModal()
       
  2510             message.Destroy()
       
  2511         elif not TestIdentifier(step_name):
       
  2512             message = wx.MessageDialog(self, _("\"%s\" is not a valid identifier!")%step_name, _("Error"), wx.OK|wx.ICON_ERROR)
       
  2513             message.ShowModal()
       
  2514             message.Destroy()
       
  2515         elif step_name.upper() in IEC_KEYWORDS:
       
  2516             message = wx.MessageDialog(self, _("\"%s\" is a keyword. It can't be used!")%step_name, _("Error"), wx.OK|wx.ICON_ERROR)
       
  2517             message.ShowModal()
       
  2518             message.Destroy()
       
  2519         elif step_name.upper() in self.PouNames:
       
  2520             message = wx.MessageDialog(self, _("A pou with \"%s\" as name exists!")%step_name, _("Error"), wx.OK|wx.ICON_ERROR)
       
  2521             message.ShowModal()
       
  2522             message.Destroy()
       
  2523         elif step_name.upper() in self.Variables:
       
  2524             message = wx.MessageDialog(self, _("A variable with \"%s\" as name already exists in this pou!")%step_name, _("Error"), wx.OK|wx.ICON_ERROR)
       
  2525             message.ShowModal()
       
  2526             message.Destroy()
       
  2527         elif step_name.upper() in self.StepNames:
       
  2528             message = wx.MessageDialog(self, _("\"%s\" step already exists!")%step_name, _("Error"), wx.OK|wx.ICON_ERROR)
       
  2529             message.ShowModal()
       
  2530             message.Destroy()
       
  2531         else:
       
  2532             self.EndModal(wx.ID_OK)
       
  2533 
       
  2534     def SetPouNames(self, pou_names):
       
  2535         self.PouNames = [pou_name.upper() for pou_name in pou_names]
       
  2536 
       
  2537     def SetVariables(self, variables):
       
  2538         self.Variables = [var["Name"].upper() for var in variables]
       
  2539 
       
  2540     def SetStepNames(self, step_names):
       
  2541         self.StepNames = [step_name.upper() for step_name in step_names]
       
  2542 
       
  2543     def GetValue(self):
       
  2544         return self.GetSizer().GetItem(1).GetWindow().GetValue()
       
  2545 
       
  2546 #-------------------------------------------------------------------------------
       
  2547 #                                POU Name Dialog
       
  2548 #-------------------------------------------------------------------------------
       
  2549 
       
  2550 class PouNameDialog(wx.TextEntryDialog):
       
  2551 
       
  2552     if wx.VERSION < (2, 6, 0):
       
  2553         def Bind(self, event, function, id = None):
       
  2554             if id is not None:
       
  2555                 event(self, id, function)
       
  2556             else:
       
  2557                 event(self, function)
       
  2558     
       
  2559 
       
  2560     def __init__(self, parent, message, caption = "Please enter text", defaultValue = "", 
       
  2561                        style = wx.OK|wx.CANCEL|wx.CENTRE, pos = wx.DefaultPosition):
       
  2562         wx.TextEntryDialog.__init__(self, parent, message, caption, defaultValue, style, pos)
       
  2563         
       
  2564         self.PouNames = []
       
  2565         if wx.VERSION >= (2, 8, 0):
       
  2566             self.Bind(wx.EVT_BUTTON, self.OnOK, id=self.GetSizer().GetItem(2).GetSizer().GetItem(1).GetSizer().GetAffirmativeButton().GetId())
       
  2567         elif wx.VERSION >= (2, 6, 0):
       
  2568             self.Bind(wx.EVT_BUTTON, self.OnOK, id=self.GetSizer().GetItem(3).GetSizer().GetAffirmativeButton().GetId())
       
  2569         else:
       
  2570             self.Bind(wx.EVT_BUTTON, self.OnOK, id=self.GetSizer().GetItem(3).GetSizer().GetChildren()[0].GetSizer().GetChildren()[0].GetWindow().GetId())
       
  2571     
       
  2572     def OnOK(self, event):
       
  2573         step_name = self.GetSizer().GetItem(1).GetWindow().GetValue()
       
  2574         if step_name == "":
       
  2575             message = wx.MessageDialog(self, _("You must type a name!"), _("Error"), wx.OK|wx.ICON_ERROR)
       
  2576             message.ShowModal()
       
  2577             message.Destroy()
       
  2578         elif not TestIdentifier(step_name):
       
  2579             message = wx.MessageDialog(self, _("\"%s\" is not a valid identifier!")%step_name, _("Error"), wx.OK|wx.ICON_ERROR)
       
  2580             message.ShowModal()
       
  2581             message.Destroy()
       
  2582         elif step_name.upper() in IEC_KEYWORDS:
       
  2583             message = wx.MessageDialog(self, _("\"%s\" is a keyword. It can't be used!")%step_name, _("Error"), wx.OK|wx.ICON_ERROR)
       
  2584             message.ShowModal()
       
  2585             message.Destroy()
       
  2586         elif step_name.upper() in self.PouNames:
       
  2587             message = wx.MessageDialog(self, _("A pou with \"%s\" as name exists!")%step_name, _("Error"), wx.OK|wx.ICON_ERROR)
       
  2588             message.ShowModal()
       
  2589             message.Destroy()
       
  2590         else:
       
  2591             self.EndModal(wx.ID_OK)
       
  2592 
       
  2593     def SetPouNames(self, pou_names):
       
  2594         self.PouNames = [pou_name.upper() for pou_name in pou_names]
       
  2595 
       
  2596     def GetValue(self):
       
  2597         return self.GetSizer().GetItem(1).GetWindow().GetValue()