editors/Viewer.py
changeset 1417 374238039643
parent 1406 82db84fe88ea
child 1431 df59be5afb08
equal deleted inserted replaced
1416:d4222bad4841 1417:374238039643
     1 #!/usr/bin/env python
     1 #!/usr/bin/env python
     2 # -*- coding: utf-8 -*-
     2 # -*- coding: utf-8 -*-
     3 
     3 
     4 #This file is part of PLCOpenEditor, a library implementing an IEC 61131-3 editor
     4 #This file is part of PLCOpenEditor, a library implementing an IEC 61131-3 editor
     5 #based on the plcopen standard. 
     5 #based on the plcopen standard.
     6 #
     6 #
     7 #Copyright (C) 2007: Edouard TISSERANT and Laurent BESSARD
     7 #Copyright (C) 2007: Edouard TISSERANT and Laurent BESSARD
     8 #
     8 #
     9 #See COPYING file for copyrights details.
     9 #See COPYING file for copyrights details.
    10 #
    10 #
    45 CURSORS = None
    45 CURSORS = None
    46 
    46 
    47 def ResetCursors():
    47 def ResetCursors():
    48     global CURSORS
    48     global CURSORS
    49     if CURSORS == None:
    49     if CURSORS == None:
    50         CURSORS = [wx.NullCursor, 
    50         CURSORS = [wx.NullCursor,
    51                    wx.StockCursor(wx.CURSOR_HAND),
    51                    wx.StockCursor(wx.CURSOR_HAND),
    52                    wx.StockCursor(wx.CURSOR_SIZENWSE),
    52                    wx.StockCursor(wx.CURSOR_SIZENWSE),
    53                    wx.StockCursor(wx.CURSOR_SIZENESW),
    53                    wx.StockCursor(wx.CURSOR_SIZENESW),
    54                    wx.StockCursor(wx.CURSOR_SIZEWE),
    54                    wx.StockCursor(wx.CURSOR_SIZEWE),
    55                    wx.StockCursor(wx.CURSOR_SIZENS)]
    55                    wx.StockCursor(wx.CURSOR_SIZENS)]
    81     MAX_ZOOMIN = 7
    81     MAX_ZOOMIN = 7
    82 ZOOM_FACTORS = [math.sqrt(2) ** x for x in xrange(-6, MAX_ZOOMIN)]
    82 ZOOM_FACTORS = [math.sqrt(2) ** x for x in xrange(-6, MAX_ZOOMIN)]
    83 
    83 
    84 def GetVariableCreationFunction(variable_type):
    84 def GetVariableCreationFunction(variable_type):
    85     def variableCreationFunction(viewer, id, specific_values):
    85     def variableCreationFunction(viewer, id, specific_values):
    86         return FBD_Variable(viewer, variable_type, 
    86         return FBD_Variable(viewer, variable_type,
    87                                     specific_values.name, 
    87                                     specific_values.name,
    88                                     specific_values.value_type, 
    88                                     specific_values.value_type,
    89                                     id,
    89                                     id,
    90                                     specific_values.execution_order)
    90                                     specific_values.execution_order)
    91     return variableCreationFunction
    91     return variableCreationFunction
    92 
    92 
    93 def GetConnectorCreationFunction(connector_type):
    93 def GetConnectorCreationFunction(connector_type):
    94     def connectorCreationFunction(viewer, id, specific_values):
    94     def connectorCreationFunction(viewer, id, specific_values):
    95         return FBD_Connector(viewer, connector_type, 
    95         return FBD_Connector(viewer, connector_type,
    96                                      specific_values.name, id)
    96                                      specific_values.name, id)
    97     return connectorCreationFunction
    97     return connectorCreationFunction
    98 
    98 
    99 def commentCreationFunction(viewer, id, specific_values):
    99 def commentCreationFunction(viewer, id, specific_values):
   100     return Comment(viewer, specific_values.content, id)
   100     return Comment(viewer, specific_values.content, id)
   101 
   101 
   102 def GetPowerRailCreationFunction(powerrail_type):
   102 def GetPowerRailCreationFunction(powerrail_type):
   103     def powerRailCreationFunction(viewer, id, specific_values):
   103     def powerRailCreationFunction(viewer, id, specific_values):
   104         return LD_PowerRail(viewer, powerrail_type, id, 
   104         return LD_PowerRail(viewer, powerrail_type, id,
   105                                     specific_values.connectors)
   105                                     specific_values.connectors)
   106     return powerRailCreationFunction
   106     return powerRailCreationFunction
   107 
   107 
   108 NEGATED_VALUE = lambda x: x if x is not None else False
   108 NEGATED_VALUE = lambda x: x if x is not None else False
   109 MODIFIER_VALUE = lambda x: x if x is not None else 'none'
   109 MODIFIER_VALUE = lambda x: x if x is not None else 'none'
   111 CONTACT_TYPES = {(True, "none"): CONTACT_REVERSE,
   111 CONTACT_TYPES = {(True, "none"): CONTACT_REVERSE,
   112                  (False, "rising"): CONTACT_RISING,
   112                  (False, "rising"): CONTACT_RISING,
   113                  (False, "falling"): CONTACT_FALLING}
   113                  (False, "falling"): CONTACT_FALLING}
   114 
   114 
   115 def contactCreationFunction(viewer, id, specific_values):
   115 def contactCreationFunction(viewer, id, specific_values):
   116     contact_type = CONTACT_TYPES.get((NEGATED_VALUE(specific_values.negated), 
   116     contact_type = CONTACT_TYPES.get((NEGATED_VALUE(specific_values.negated),
   117                                       MODIFIER_VALUE(specific_values.edge)),
   117                                       MODIFIER_VALUE(specific_values.edge)),
   118                                      CONTACT_NORMAL)
   118                                      CONTACT_NORMAL)
   119     return LD_Contact(viewer, contact_type, specific_values.name, id)
   119     return LD_Contact(viewer, contact_type, specific_values.name, id)
   120 
   120 
   121 COIL_TYPES = {(True, "none", "none"): COIL_REVERSE,
   121 COIL_TYPES = {(True, "none", "none"): COIL_REVERSE,
   123               (False, "none", "reset"): COIL_RESET,
   123               (False, "none", "reset"): COIL_RESET,
   124               (False, "rising", "none"): COIL_RISING,
   124               (False, "rising", "none"): COIL_RISING,
   125               (False, "falling", "none"): COIL_FALLING}
   125               (False, "falling", "none"): COIL_FALLING}
   126 
   126 
   127 def coilCreationFunction(viewer, id, specific_values):
   127 def coilCreationFunction(viewer, id, specific_values):
   128     coil_type = COIL_TYPES.get((NEGATED_VALUE(specific_values.negated), 
   128     coil_type = COIL_TYPES.get((NEGATED_VALUE(specific_values.negated),
   129                                 MODIFIER_VALUE(specific_values.edge),
   129                                 MODIFIER_VALUE(specific_values.edge),
   130                                 MODIFIER_VALUE(specific_values.storage)),
   130                                 MODIFIER_VALUE(specific_values.storage)),
   131                                COIL_NORMAL)
   131                                COIL_NORMAL)
   132     return LD_Coil(viewer, coil_type, specific_values.name, id)
   132     return LD_Coil(viewer, coil_type, specific_values.name, id)
   133 
   133 
   134 def stepCreationFunction(viewer, id, specific_values):
   134 def stepCreationFunction(viewer, id, specific_values):
   135     step = SFC_Step(viewer, specific_values.name, 
   135     step = SFC_Step(viewer, specific_values.name,
   136                             specific_values.initial, id)
   136                             specific_values.initial, id)
   137     if specific_values.action is not None:
   137     if specific_values.action is not None:
   138         step.AddAction()
   138         step.AddAction()
   139         connector = step.GetActionConnector()
   139         connector = step.GetActionConnector()
   140         connector.SetPosition(wx.Point(*specific_values.action.position))
   140         connector.SetPosition(wx.Point(*specific_values.action.position))
   141     return step
   141     return step
   142 
   142 
   143 def transitionCreationFunction(viewer, id, specific_values):
   143 def transitionCreationFunction(viewer, id, specific_values):
   144     transition = SFC_Transition(viewer, specific_values.condition_type, 
   144     transition = SFC_Transition(viewer, specific_values.condition_type,
   145                                         specific_values.condition, 
   145                                         specific_values.condition,
   146                                         specific_values.priority, id)
   146                                         specific_values.priority, id)
   147     return transition
   147     return transition
   148 
   148 
   149 def GetDivergenceCreationFunction(divergence_type):
   149 def GetDivergenceCreationFunction(divergence_type):
   150     def divergenceCreationFunction(viewer, id, specific_values):
   150     def divergenceCreationFunction(viewer, id, specific_values):
   151         return SFC_Divergence(viewer, divergence_type, 
   151         return SFC_Divergence(viewer, divergence_type,
   152                                       specific_values.connectors, id)
   152                                       specific_values.connectors, id)
   153     return divergenceCreationFunction
   153     return divergenceCreationFunction
   154 
   154 
   155 def jumpCreationFunction(viewer, id, specific_values):
   155 def jumpCreationFunction(viewer, id, specific_values):
   156     return SFC_Jump(viewer, specific_values.target, id)
   156     return SFC_Jump(viewer, specific_values.target, id)
   167     "comment": commentCreationFunction,
   167     "comment": commentCreationFunction,
   168     "leftPowerRail": GetPowerRailCreationFunction(LEFTRAIL),
   168     "leftPowerRail": GetPowerRailCreationFunction(LEFTRAIL),
   169     "rightPowerRail": GetPowerRailCreationFunction(RIGHTRAIL),
   169     "rightPowerRail": GetPowerRailCreationFunction(RIGHTRAIL),
   170     "contact": contactCreationFunction,
   170     "contact": contactCreationFunction,
   171     "coil": coilCreationFunction,
   171     "coil": coilCreationFunction,
   172     "step": stepCreationFunction, 
   172     "step": stepCreationFunction,
   173     "transition": transitionCreationFunction,
   173     "transition": transitionCreationFunction,
   174     "selectionDivergence": GetDivergenceCreationFunction(SELECTION_DIVERGENCE), 
   174     "selectionDivergence": GetDivergenceCreationFunction(SELECTION_DIVERGENCE),
   175     "selectionConvergence": GetDivergenceCreationFunction(SELECTION_CONVERGENCE), 
   175     "selectionConvergence": GetDivergenceCreationFunction(SELECTION_CONVERGENCE),
   176     "simultaneousDivergence": GetDivergenceCreationFunction(SIMULTANEOUS_DIVERGENCE), 
   176     "simultaneousDivergence": GetDivergenceCreationFunction(SIMULTANEOUS_DIVERGENCE),
   177     "simultaneousConvergence": GetDivergenceCreationFunction(SIMULTANEOUS_CONVERGENCE), 
   177     "simultaneousConvergence": GetDivergenceCreationFunction(SIMULTANEOUS_CONVERGENCE),
   178     "jump": jumpCreationFunction,
   178     "jump": jumpCreationFunction,
   179     "actionBlock": actionBlockCreationFunction,
   179     "actionBlock": actionBlockCreationFunction,
   180 }
   180 }
   181 
   181 
   182 def sort_blocks(block_infos1, block_infos2):
   182 def sort_blocks(block_infos1, block_infos2):
   207  ID_VIEWERCONTEXTUALMENUITEMS17,
   207  ID_VIEWERCONTEXTUALMENUITEMS17,
   208 ] = [wx.NewId() for _init_coll_ContextualMenu_Items in range(13)]
   208 ] = [wx.NewId() for _init_coll_ContextualMenu_Items in range(13)]
   209 
   209 
   210 
   210 
   211 class ViewerDropTarget(wx.TextDropTarget):
   211 class ViewerDropTarget(wx.TextDropTarget):
   212     
   212 
   213     def __init__(self, parent):
   213     def __init__(self, parent):
   214         wx.TextDropTarget.__init__(self)
   214         wx.TextDropTarget.__init__(self)
   215         self.ParentWindow = parent
   215         self.ParentWindow = parent
   216     
   216 
   217     def OnDropText(self, x, y, data):
   217     def OnDropText(self, x, y, data):
   218         self.ParentWindow.Select()
   218         self.ParentWindow.Select()
   219         tagname = self.ParentWindow.GetTagName()
   219         tagname = self.ParentWindow.GetTagName()
   220         pou_name, pou_type = self.ParentWindow.Controler.GetEditedElementType(tagname, self.ParentWindow.Debug)
   220         pou_name, pou_type = self.ParentWindow.Controler.GetEditedElementType(tagname, self.ParentWindow.Debug)
   221         x, y = self.ParentWindow.CalcUnscrolledPosition(x, y)
   221         x, y = self.ParentWindow.CalcUnscrolledPosition(x, y)
   278                         self.ParentWindow.Refresh(False)
   278                         self.ParentWindow.Refresh(False)
   279             elif values[1] == "location":
   279             elif values[1] == "location":
   280                 if pou_type == "program":
   280                 if pou_type == "program":
   281                     location = values[0]
   281                     location = values[0]
   282                     if not location.startswith("%"):
   282                     if not location.startswith("%"):
   283                         dialog = wx.SingleChoiceDialog(self.ParentWindow.ParentWindow, 
   283                         dialog = wx.SingleChoiceDialog(self.ParentWindow.ParentWindow,
   284                               _("Select a variable class:"), _("Variable class"), 
   284                               _("Select a variable class:"), _("Variable class"),
   285                               ["Input", "Output", "Memory"], 
   285                               ["Input", "Output", "Memory"],
   286                               wx.DEFAULT_DIALOG_STYLE|wx.OK|wx.CANCEL)
   286                               wx.DEFAULT_DIALOG_STYLE|wx.OK|wx.CANCEL)
   287                         if dialog.ShowModal() == wx.ID_OK:
   287                         if dialog.ShowModal() == wx.ID_OK:
   288                             selected = dialog.GetSelection()
   288                             selected = dialog.GetSelection()
   289                         else:
   289                         else:
   290                             selected = None
   290                             selected = None
   296                         elif selected == 1:
   296                         elif selected == 1:
   297                             location = "%Q" + location
   297                             location = "%Q" + location
   298                         else:
   298                         else:
   299                             location = "%M" + location
   299                             location = "%M" + location
   300                     var_name = values[3]
   300                     var_name = values[3]
   301                     if var_name.upper() in [name.upper() for name in self.ParentWindow.Controler.GetProjectPouNames(self.ParentWindow.Debug)]:
   301                     dlg = wx.TextEntryDialog(
       
   302                         self.ParentWindow.ParentWindow,
       
   303                         _("Confirm or change variable name"),
       
   304                         'Variable Drop', var_name)
       
   305                     dlg.SetValue(var_name)
       
   306                     var_name = dlg.GetValue() if dlg.ShowModal() == wx.ID_OK else None
       
   307                     dlg.Destroy()
       
   308                     if var_name is None:
       
   309                         return
       
   310                     elif var_name.upper() in [name.upper() for name in self.ParentWindow.Controler.GetProjectPouNames(self.ParentWindow.Debug)]:
   302                         message = _("\"%s\" pou already exists!")%var_name
   311                         message = _("\"%s\" pou already exists!")%var_name
   303                     else:
   312                     elif not var_name.upper() in [name.upper() for name in self.ParentWindow.Controler.GetEditedElementVariables(tagname, self.ParentWindow.Debug)]:
   304                         if location[1] == "Q":
   313                         if location[1] == "Q":
   305                             var_class = OUTPUT
   314                             var_class = OUTPUT
   306                         else:
   315                         else:
   307                             var_class = INPUT
   316                             var_class = INPUT
   308                         if values[2] is not None:
   317                         if values[2] is not None:
   309                             var_type = values[2]
   318                             var_type = values[2]
   310                         else:
   319                         else:
   311                             var_type = LOCATIONDATATYPES.get(location[2], ["BOOL"])[0]
   320                             var_type = LOCATIONDATATYPES.get(location[2], ["BOOL"])[0]
   312                         if not var_name.upper() in [name.upper() for name in self.ParentWindow.Controler.GetEditedElementVariables(tagname, self.ParentWindow.Debug)]:
   321                         self.ParentWindow.Controler.AddEditedElementPouVar(tagname, var_type, var_name, location=location, description=values[4])
   313                             self.ParentWindow.Controler.AddEditedElementPouVar(tagname, var_type, var_name, location=location, description=values[4])
   322                         self.ParentWindow.RefreshVariablePanel()
   314                             self.ParentWindow.RefreshVariablePanel()
   323                         self.ParentWindow.ParentWindow.RefreshPouInstanceVariablesPanel()
   315                             self.ParentWindow.ParentWindow.RefreshPouInstanceVariablesPanel()
       
   316                         self.ParentWindow.AddVariableBlock(x, y, scaling, var_class, var_name, var_type)
   324                         self.ParentWindow.AddVariableBlock(x, y, scaling, var_class, var_name, var_type)
       
   325                     else:
       
   326                         message = _("\"%s\" element for this pou already exists!")%var_name
   317             elif values[1] == "NamedConstant":
   327             elif values[1] == "NamedConstant":
   318                 if pou_type == "program":
   328                 if pou_type == "program":
   319                     initval = values[0]
   329                     initval = values[0]
   320                     var_name = values[3]
   330                     var_name = values[3]
   321                     if var_name.upper() in [name.upper() for name in self.ParentWindow.Controler.GetProjectPouNames(self.ParentWindow.Debug)]:
   331                     dlg = wx.TextEntryDialog(
       
   332                         self.ParentWindow.ParentWindow,
       
   333                         _("Confirm or change variable name"),
       
   334                         'Variable Drop', var_name)
       
   335                     dlg.SetValue(var_name)
       
   336                     var_name = dlg.GetValue() if dlg.ShowModal() == wx.ID_OK else None
       
   337                     dlg.Destroy()
       
   338                     if var_name is None:
       
   339                         return
       
   340                     elif var_name.upper() in [name.upper() for name in self.ParentWindow.Controler.GetProjectPouNames(self.ParentWindow.Debug)]:
   322                         message = _("\"%s\" pou already exists!")%var_name
   341                         message = _("\"%s\" pou already exists!")%var_name
   323                     else:
   342                     elif not var_name.upper() in [name.upper() for name in self.ParentWindow.Controler.GetEditedElementVariables(tagname, self.ParentWindow.Debug)]:
   324                         var_class = INPUT
   343                         var_class = INPUT
   325                         var_type = values[2]
   344                         var_type = values[2]
   326                         if not var_name.upper() in [name.upper() for name in self.ParentWindow.Controler.GetEditedElementVariables(tagname, self.ParentWindow.Debug)]:
   345                         self.ParentWindow.Controler.AddEditedElementPouVar(tagname, var_type, var_name, description=values[4], initval=initval)
   327                             self.ParentWindow.Controler.AddEditedElementPouVar(tagname, var_type, var_name, description=values[4], initval=initval)
   346                         self.ParentWindow.RefreshVariablePanel()
   328                             self.ParentWindow.RefreshVariablePanel()
   347                         self.ParentWindow.ParentWindow.RefreshPouInstanceVariablesPanel()
   329                             self.ParentWindow.ParentWindow.RefreshPouInstanceVariablesPanel()
       
   330                         self.ParentWindow.AddVariableBlock(x, y, scaling, var_class, var_name, var_type)
   348                         self.ParentWindow.AddVariableBlock(x, y, scaling, var_class, var_name, var_type)
       
   349                     else:
       
   350                         message = _("\"%s\" element for this pou already exists!")%var_name
   331             elif values[1] == "Global":
   351             elif values[1] == "Global":
   332                 var_name = values[0]
   352                 var_name = values[0]
   333                 if var_name.upper() in [name.upper() for name in self.ParentWindow.Controler.GetProjectPouNames(self.ParentWindow.Debug)]:
   353                 dlg = wx.TextEntryDialog(
       
   354                     self.ParentWindow.ParentWindow,
       
   355                     _("Confirm or change variable name"),
       
   356                     'Variable Drop', var_name)
       
   357                 dlg.SetValue(var_name)
       
   358                 var_name = dlg.GetValue() if dlg.ShowModal() == wx.ID_OK else None
       
   359                 dlg.Destroy()
       
   360                 if var_name is None:
       
   361                     return
       
   362                 elif var_name.upper() in [name.upper() for name in self.ParentWindow.Controler.GetProjectPouNames(self.ParentWindow.Debug)]:
   334                     message = _("\"%s\" pou already exists!")%var_name
   363                     message = _("\"%s\" pou already exists!")%var_name
       
   364                 elif not var_name.upper() in [name.upper() for name in self.ParentWindow.Controler.GetEditedElementVariables(tagname, self.ParentWindow.Debug)]:
       
   365                     self.ParentWindow.Controler.AddEditedElementPouExternalVar(tagname, values[2], var_name)
       
   366                     self.ParentWindow.RefreshVariablePanel()
       
   367                     self.ParentWindow.ParentWindow.RefreshPouInstanceVariablesPanel()
       
   368                     self.ParentWindow.AddVariableBlock(x, y, scaling, INPUT, var_name, values[2])
   335                 else:
   369                 else:
   336                     if not var_name.upper() in [name.upper() for name in self.ParentWindow.Controler.GetEditedElementVariables(tagname, self.ParentWindow.Debug)]:
   370                     message = _("\"%s\" element for this pou already exists!")%var_name
   337                         self.ParentWindow.Controler.AddEditedElementPouExternalVar(tagname, values[2], var_name)
       
   338                         self.ParentWindow.RefreshVariablePanel()
       
   339                         self.ParentWindow.ParentWindow.RefreshPouInstanceVariablesPanel()
       
   340                     self.ParentWindow.AddVariableBlock(x, y, scaling, INPUT, var_name, values[2])
       
   341             elif values[1] == "Constant":
   371             elif values[1] == "Constant":
   342                 self.ParentWindow.AddVariableBlock(x, y, scaling, INPUT, values[0], None)
   372                 self.ParentWindow.AddVariableBlock(x, y, scaling, INPUT, values[0], None)
   343             elif values[3] == tagname:
   373             elif values[3] == tagname:
   344                 if values[1] == "Output":
   374                 if values[1] == "Output":
   345                     var_class = OUTPUT
   375                     var_class = OUTPUT
   377             if len(child_tree) > 0:
   407             if len(child_tree) > 0:
   378                 new_id = wx.NewId()
   408                 new_id = wx.NewId()
   379                 child_menu = wx.Menu(title='')
   409                 child_menu = wx.Menu(title='')
   380                 self.GenerateTreeMenu(x, y, scaling, child_menu, child_path, var_class, child_tree)
   410                 self.GenerateTreeMenu(x, y, scaling, child_menu, child_path, var_class, child_tree)
   381                 menu.AppendMenu(new_id, "%s." % child_name, child_menu)
   411                 menu.AppendMenu(new_id, "%s." % child_name, child_menu)
   382             
   412 
   383     def GetAddVariableBlockFunction(self, x, y, scaling, var_class, var_name, var_type):
   413     def GetAddVariableBlockFunction(self, x, y, scaling, var_class, var_name, var_type):
   384         def AddVariableFunction(event):
   414         def AddVariableFunction(event):
   385             self.ParentWindow.AddVariableBlock(x, y, scaling, var_class, var_name, var_type)
   415             self.ParentWindow.AddVariableBlock(x, y, scaling, var_class, var_name, var_type)
   386         return AddVariableFunction
   416         return AddVariableFunction
   387     
   417 
   388     def ShowMessage(self, message):
   418     def ShowMessage(self, message):
   389         message = wx.MessageDialog(self.ParentWindow, message, _("Error"), wx.OK|wx.ICON_ERROR)
   419         message = wx.MessageDialog(self.ParentWindow, message, _("Error"), wx.OK|wx.ICON_ERROR)
   390         message.ShowModal()
   420         message.ShowModal()
   391         message.Destroy()
   421         message.Destroy()
   392 
   422 
   393 """
   423 """
   394 Class that implements a Viewer based on a wx.ScrolledWindow for drawing and 
   424 Class that implements a Viewer based on a wx.ScrolledWindow for drawing and
   395 manipulating graphic elements
   425 manipulating graphic elements
   396 """
   426 """
   397 
   427 
   398 class Viewer(EditorPanel, DebugViewer):
   428 class Viewer(EditorPanel, DebugViewer):
   399     
   429 
   400     if wx.VERSION < (2, 6, 0):
   430     if wx.VERSION < (2, 6, 0):
   401         def Bind(self, event, function, id = None):
   431         def Bind(self, event, function, id = None):
   402             if id is not None:
   432             if id is not None:
   403                 event(self, id, function)
   433                 event(self, id, function)
   404             else:
   434             else:
   405                 event(self, function)
   435                 event(self, function)
   406     
   436 
   407     # Add list of menu items to the given menu
   437     # Add list of menu items to the given menu
   408     def AddMenuItems(self, menu, items):
   438     def AddMenuItems(self, menu, items):
   409         for item in items:
   439         for item in items:
   410             if item is None:
   440             if item is None:
   411                 menu.AppendSeparator()
   441                 menu.AppendSeparator()
   412             else:
   442             else:
   413                 id, kind, text, help, callback = item
   443                 id, kind, text, help, callback = item
   414                 AppendMenu(menu, help=help, id=id, kind=kind, text=text)
   444                 AppendMenu(menu, help=help, id=id, kind=kind, text=text)
   415                 # Link menu event to corresponding called functions
   445                 # Link menu event to corresponding called functions
   416                 self.Bind(wx.EVT_MENU, callback, id=id)
   446                 self.Bind(wx.EVT_MENU, callback, id=id)
   417     
   447 
   418     # Add Block Pin Menu items to the given menu
   448     # Add Block Pin Menu items to the given menu
   419     def AddBlockPinMenuItems(self, menu, connector):
   449     def AddBlockPinMenuItems(self, menu, connector):
   420         [ID_NO_MODIFIER, ID_NEGATED, ID_RISING_EDGE, 
   450         [ID_NO_MODIFIER, ID_NEGATED, ID_RISING_EDGE,
   421          ID_FALLING_EDGE] = [wx.NewId() for i in xrange(4)]
   451          ID_FALLING_EDGE] = [wx.NewId() for i in xrange(4)]
   422         
   452 
   423         # Create menu items
   453         # Create menu items
   424         self.AddMenuItems(menu, [
   454         self.AddMenuItems(menu, [
   425             (ID_NO_MODIFIER, wx.ITEM_RADIO, _(u'No Modifier'), '', self.OnNoModifierMenu),
   455             (ID_NO_MODIFIER, wx.ITEM_RADIO, _(u'No Modifier'), '', self.OnNoModifierMenu),
   426             (ID_NEGATED, wx.ITEM_RADIO, _(u'Negated'), '', self.OnNegatedMenu),
   456             (ID_NEGATED, wx.ITEM_RADIO, _(u'Negated'), '', self.OnNegatedMenu),
   427             (ID_RISING_EDGE, wx.ITEM_RADIO, _(u'Rising Edge'), '', self.OnRisingEdgeMenu),
   457             (ID_RISING_EDGE, wx.ITEM_RADIO, _(u'Rising Edge'), '', self.OnRisingEdgeMenu),
   428             (ID_FALLING_EDGE, wx.ITEM_RADIO, _(u'Falling Edge'), '', self.OnFallingEdgeMenu)])
   458             (ID_FALLING_EDGE, wx.ITEM_RADIO, _(u'Falling Edge'), '', self.OnFallingEdgeMenu)])
   429         
   459 
   430         type = self.Controler.GetEditedElementType(self.TagName, self.Debug)
   460         type = self.Controler.GetEditedElementType(self.TagName, self.Debug)
   431         menu.Enable(ID_RISING_EDGE, type != "function")
   461         menu.Enable(ID_RISING_EDGE, type != "function")
   432         menu.Enable(ID_FALLING_EDGE, type != "function")
   462         menu.Enable(ID_FALLING_EDGE, type != "function")
   433         
   463 
   434         if connector.IsNegated():
   464         if connector.IsNegated():
   435             menu.Check(ID_NEGATED, True)
   465             menu.Check(ID_NEGATED, True)
   436         elif connector.GetEdge() == "rising":
   466         elif connector.GetEdge() == "rising":
   437             menu.Check(ID_RISING_EDGE, True)
   467             menu.Check(ID_RISING_EDGE, True)
   438         elif connector.GetEdge() == "falling":
   468         elif connector.GetEdge() == "falling":
   439             menu.Check(ID_FALLING_EDGE, True)
   469             menu.Check(ID_FALLING_EDGE, True)
   440         else:
   470         else:
   441             menu.Check(ID_NO_MODIFIER, True)
   471             menu.Check(ID_NO_MODIFIER, True)
   442         
   472 
   443     # Add Alignment Menu items to the given menu
   473     # Add Alignment Menu items to the given menu
   444     def AddAlignmentMenuItems(self, menu):
   474     def AddAlignmentMenuItems(self, menu):
   445         [ID_ALIGN_LEFT, ID_ALIGN_CENTER, ID_ALIGN_RIGHT,
   475         [ID_ALIGN_LEFT, ID_ALIGN_CENTER, ID_ALIGN_RIGHT,
   446          ID_ALIGN_TOP, ID_ALIGN_MIDDLE, ID_ALIGN_BOTTOM,
   476          ID_ALIGN_TOP, ID_ALIGN_MIDDLE, ID_ALIGN_BOTTOM,
   447         ] = [wx.NewId() for i in xrange(6)]
   477         ] = [wx.NewId() for i in xrange(6)]
   448         
   478 
   449         # Create menu items
   479         # Create menu items
   450         self.AddMenuItems(menu, [
   480         self.AddMenuItems(menu, [
   451             (ID_ALIGN_LEFT, wx.ITEM_NORMAL, _(u'Left'), '', self.OnAlignLeftMenu),
   481             (ID_ALIGN_LEFT, wx.ITEM_NORMAL, _(u'Left'), '', self.OnAlignLeftMenu),
   452             (ID_ALIGN_CENTER, wx.ITEM_NORMAL, _(u'Center'), '', self.OnAlignCenterMenu), 
   482             (ID_ALIGN_CENTER, wx.ITEM_NORMAL, _(u'Center'), '', self.OnAlignCenterMenu),
   453             (ID_ALIGN_RIGHT, wx.ITEM_NORMAL, _(u'Right'), '', self.OnAlignRightMenu),
   483             (ID_ALIGN_RIGHT, wx.ITEM_NORMAL, _(u'Right'), '', self.OnAlignRightMenu),
   454             None,
   484             None,
   455             (ID_ALIGN_TOP, wx.ITEM_NORMAL, _(u'Top'), '', self.OnAlignTopMenu), 
   485             (ID_ALIGN_TOP, wx.ITEM_NORMAL, _(u'Top'), '', self.OnAlignTopMenu),
   456             (ID_ALIGN_MIDDLE, wx.ITEM_NORMAL, _(u'Middle'), '', self.OnAlignMiddleMenu),
   486             (ID_ALIGN_MIDDLE, wx.ITEM_NORMAL, _(u'Middle'), '', self.OnAlignMiddleMenu),
   457             (ID_ALIGN_BOTTOM, wx.ITEM_NORMAL, _(u'Bottom'), '', self.OnAlignBottomMenu)])
   487             (ID_ALIGN_BOTTOM, wx.ITEM_NORMAL, _(u'Bottom'), '', self.OnAlignBottomMenu)])
   458     
   488 
   459     # Add Wire Menu items to the given menu
   489     # Add Wire Menu items to the given menu
   460     def AddWireMenuItems(self, menu, delete=False, replace=False):
   490     def AddWireMenuItems(self, menu, delete=False, replace=False):
   461         [ID_ADD_SEGMENT, ID_DELETE_SEGMENT, ID_REPLACE_WIRE,
   491         [ID_ADD_SEGMENT, ID_DELETE_SEGMENT, ID_REPLACE_WIRE,
   462          ] = [wx.NewId() for i in xrange(3)]
   492          ] = [wx.NewId() for i in xrange(3)]
   463         
   493 
   464         # Create menu items
   494         # Create menu items
   465         self.AddMenuItems(menu, [
   495         self.AddMenuItems(menu, [
   466             (ID_ADD_SEGMENT, wx.ITEM_NORMAL, _(u'Add Wire Segment'), '', self.OnAddSegmentMenu),
   496             (ID_ADD_SEGMENT, wx.ITEM_NORMAL, _(u'Add Wire Segment'), '', self.OnAddSegmentMenu),
   467             (ID_DELETE_SEGMENT, wx.ITEM_NORMAL, _(u'Delete Wire Segment'), '', self.OnDeleteSegmentMenu),
   497             (ID_DELETE_SEGMENT, wx.ITEM_NORMAL, _(u'Delete Wire Segment'), '', self.OnDeleteSegmentMenu),
   468             (ID_REPLACE_WIRE, wx.ITEM_NORMAL, _(u'Replace Wire by connections'), '', self.OnReplaceWireMenu)])
   498             (ID_REPLACE_WIRE, wx.ITEM_NORMAL, _(u'Replace Wire by connections'), '', self.OnReplaceWireMenu)])
   469         
   499 
   470         menu.Enable(ID_DELETE_SEGMENT, delete)
   500         menu.Enable(ID_DELETE_SEGMENT, delete)
   471         menu.Enable(ID_REPLACE_WIRE, replace)
   501         menu.Enable(ID_REPLACE_WIRE, replace)
   472     
   502 
   473     # Add Divergence Menu items to the given menu
   503     # Add Divergence Menu items to the given menu
   474     def AddDivergenceMenuItems(self, menu, delete=False):
   504     def AddDivergenceMenuItems(self, menu, delete=False):
   475         [ID_ADD_BRANCH, ID_DELETE_BRANCH] = [wx.NewId() for i in xrange(2)]
   505         [ID_ADD_BRANCH, ID_DELETE_BRANCH] = [wx.NewId() for i in xrange(2)]
   476         
   506 
   477         # Create menu items
   507         # Create menu items
   478         self.AddMenuItems(menu, [
   508         self.AddMenuItems(menu, [
   479             (ID_ADD_BRANCH, wx.ITEM_NORMAL, _(u'Add Divergence Branch'), '', self.OnAddBranchMenu),
   509             (ID_ADD_BRANCH, wx.ITEM_NORMAL, _(u'Add Divergence Branch'), '', self.OnAddBranchMenu),
   480             (ID_DELETE_BRANCH, wx.ITEM_NORMAL, _(u'Delete Divergence Branch'), '', self.OnDeleteBranchMenu)])
   510             (ID_DELETE_BRANCH, wx.ITEM_NORMAL, _(u'Delete Divergence Branch'), '', self.OnDeleteBranchMenu)])
   481         
   511 
   482         menu.Enable(ID_DELETE_BRANCH, delete)
   512         menu.Enable(ID_DELETE_BRANCH, delete)
   483     
   513 
   484     # Add Add Menu items to the given menu
   514     # Add Add Menu items to the given menu
   485     def AddAddMenuItems(self, menu):
   515     def AddAddMenuItems(self, menu):
   486         [ID_ADD_BLOCK, ID_ADD_VARIABLE, ID_ADD_CONNECTION,
   516         [ID_ADD_BLOCK, ID_ADD_VARIABLE, ID_ADD_CONNECTION,
   487          ID_ADD_COMMENT] = [wx.NewId() for i in xrange(4)]
   517          ID_ADD_COMMENT] = [wx.NewId() for i in xrange(4)]
   488         
   518 
   489         # Create menu items
   519         # Create menu items
   490         self.AddMenuItems(menu, [
   520         self.AddMenuItems(menu, [
   491             (ID_ADD_BLOCK, wx.ITEM_NORMAL, _(u'Block'), '', self.GetAddMenuCallBack(self.AddNewBlock)),
   521             (ID_ADD_BLOCK, wx.ITEM_NORMAL, _(u'Block'), '', self.GetAddMenuCallBack(self.AddNewBlock)),
   492             (ID_ADD_VARIABLE, wx.ITEM_NORMAL, _(u'Variable'), '', self.GetAddMenuCallBack(self.AddNewVariable)),
   522             (ID_ADD_VARIABLE, wx.ITEM_NORMAL, _(u'Variable'), '', self.GetAddMenuCallBack(self.AddNewVariable)),
   493             (ID_ADD_CONNECTION, wx.ITEM_NORMAL, _(u'Connection'), '', self.GetAddMenuCallBack(self.AddNewConnection)),
   523             (ID_ADD_CONNECTION, wx.ITEM_NORMAL, _(u'Connection'), '', self.GetAddMenuCallBack(self.AddNewConnection)),
   494             None])
   524             None])
   495         
   525 
   496         if self.CurrentLanguage != "FBD":
   526         if self.CurrentLanguage != "FBD":
   497             [ID_ADD_POWER_RAIL, ID_ADD_CONTACT, ID_ADD_COIL,
   527             [ID_ADD_POWER_RAIL, ID_ADD_CONTACT, ID_ADD_COIL,
   498             ] = [wx.NewId() for i in xrange(3)]
   528             ] = [wx.NewId() for i in xrange(3)]
   499             
   529 
   500             # Create menu items
   530             # Create menu items
   501             self.AddMenuItems(menu, [
   531             self.AddMenuItems(menu, [
   502                 (ID_ADD_POWER_RAIL, wx.ITEM_NORMAL, _(u'Power Rail'), '', self.GetAddMenuCallBack(self.AddNewPowerRail)),
   532                 (ID_ADD_POWER_RAIL, wx.ITEM_NORMAL, _(u'Power Rail'), '', self.GetAddMenuCallBack(self.AddNewPowerRail)),
   503                 (ID_ADD_CONTACT, wx.ITEM_NORMAL, _(u'Contact'), '', self.GetAddMenuCallBack(self.AddNewContact))])
   533                 (ID_ADD_CONTACT, wx.ITEM_NORMAL, _(u'Contact'), '', self.GetAddMenuCallBack(self.AddNewContact))])
   504                 
   534 
   505             if self.CurrentLanguage != "SFC":
   535             if self.CurrentLanguage != "SFC":
   506                 self.AddMenuItems(menu, [
   536                 self.AddMenuItems(menu, [
   507                      (ID_ADD_COIL, wx.ITEM_NORMAL, _(u'Coil'), '', self.GetAddMenuCallBack(self.AddNewCoil))])
   537                      (ID_ADD_COIL, wx.ITEM_NORMAL, _(u'Coil'), '', self.GetAddMenuCallBack(self.AddNewCoil))])
   508             
   538 
   509             menu.AppendSeparator()
   539             menu.AppendSeparator()
   510         
   540 
   511         if self.CurrentLanguage == "SFC":
   541         if self.CurrentLanguage == "SFC":
   512             [ID_ADD_INITIAL_STEP, ID_ADD_STEP, ID_ADD_TRANSITION, 
   542             [ID_ADD_INITIAL_STEP, ID_ADD_STEP, ID_ADD_TRANSITION,
   513              ID_ADD_ACTION_BLOCK, ID_ADD_DIVERGENCE, ID_ADD_JUMP,
   543              ID_ADD_ACTION_BLOCK, ID_ADD_DIVERGENCE, ID_ADD_JUMP,
   514             ] = [wx.NewId() for i in xrange(6)]
   544             ] = [wx.NewId() for i in xrange(6)]
   515             
   545 
   516             # Create menu items
   546             # Create menu items
   517             self.AddMenuItems(menu, [
   547             self.AddMenuItems(menu, [
   518                 (ID_ADD_INITIAL_STEP, wx.ITEM_NORMAL, _(u'Initial Step'), '', self.GetAddMenuCallBack(self.AddNewStep, True)),
   548                 (ID_ADD_INITIAL_STEP, wx.ITEM_NORMAL, _(u'Initial Step'), '', self.GetAddMenuCallBack(self.AddNewStep, True)),
   519                 (ID_ADD_STEP, wx.ITEM_NORMAL, _(u'Step'), '', self.GetAddMenuCallBack(self.AddNewStep)),
   549                 (ID_ADD_STEP, wx.ITEM_NORMAL, _(u'Step'), '', self.GetAddMenuCallBack(self.AddNewStep)),
   520                 (ID_ADD_TRANSITION, wx.ITEM_NORMAL, _(u'Transition'), '', self.GetAddMenuCallBack(self.AddNewTransition)),
   550                 (ID_ADD_TRANSITION, wx.ITEM_NORMAL, _(u'Transition'), '', self.GetAddMenuCallBack(self.AddNewTransition)),
   521                 (ID_ADD_ACTION_BLOCK, wx.ITEM_NORMAL, _(u'Action Block'), '', self.GetAddMenuCallBack(self.AddNewActionBlock)),
   551                 (ID_ADD_ACTION_BLOCK, wx.ITEM_NORMAL, _(u'Action Block'), '', self.GetAddMenuCallBack(self.AddNewActionBlock)),
   522                 (ID_ADD_DIVERGENCE, wx.ITEM_NORMAL, _(u'Divergence'), '', self.GetAddMenuCallBack(self.AddNewDivergence)),
   552                 (ID_ADD_DIVERGENCE, wx.ITEM_NORMAL, _(u'Divergence'), '', self.GetAddMenuCallBack(self.AddNewDivergence)),
   523                 (ID_ADD_JUMP, wx.ITEM_NORMAL, _(u'Jump'), '', self.GetAddMenuCallBack(self.AddNewJump)),
   553                 (ID_ADD_JUMP, wx.ITEM_NORMAL, _(u'Jump'), '', self.GetAddMenuCallBack(self.AddNewJump)),
   524                 None])
   554                 None])
   525         
   555 
   526         self.AddMenuItems(menu, [
   556         self.AddMenuItems(menu, [
   527              (ID_ADD_COMMENT, wx.ITEM_NORMAL, _(u'Comment'), '', self.GetAddMenuCallBack(self.AddNewComment))])
   557              (ID_ADD_COMMENT, wx.ITEM_NORMAL, _(u'Comment'), '', self.GetAddMenuCallBack(self.AddNewComment))])
   528         
   558 
   529     # Add Default Menu items to the given menu
   559     # Add Default Menu items to the given menu
   530     def AddDefaultMenuItems(self, menu, edit=False, block=False):
   560     def AddDefaultMenuItems(self, menu, edit=False, block=False):
   531         if block:
   561         if block:
   532             [ID_EDIT_BLOCK, ID_DELETE, ID_ADJUST_BLOCK_SIZE] = [wx.NewId() for i in xrange(3)]
   562             [ID_EDIT_BLOCK, ID_DELETE, ID_ADJUST_BLOCK_SIZE] = [wx.NewId() for i in xrange(3)]
   533         
   563 
   534             # Create menu items
   564             # Create menu items
   535             self.AddMenuItems(menu, [
   565             self.AddMenuItems(menu, [
   536                  (ID_EDIT_BLOCK, wx.ITEM_NORMAL, _(u'Edit Block'), '', self.OnEditBlockMenu),
   566                  (ID_EDIT_BLOCK, wx.ITEM_NORMAL, _(u'Edit Block'), '', self.OnEditBlockMenu),
   537                  (ID_ADJUST_BLOCK_SIZE, wx.ITEM_NORMAL, _(u'Adjust Block Size'), '', self.OnAdjustBlockSizeMenu),
   567                  (ID_ADJUST_BLOCK_SIZE, wx.ITEM_NORMAL, _(u'Adjust Block Size'), '', self.OnAdjustBlockSizeMenu),
   538                  (ID_DELETE, wx.ITEM_NORMAL, _(u'Delete'), '', self.OnDeleteMenu)])
   568                  (ID_DELETE, wx.ITEM_NORMAL, _(u'Delete'), '', self.OnDeleteMenu)])
   539         
   569 
   540             menu.Enable(ID_EDIT_BLOCK, edit)
   570             menu.Enable(ID_EDIT_BLOCK, edit)
   541         
   571 
   542         else:
   572         else:
   543             [ID_CLEAR_EXEC_ORDER, ID_RESET_EXEC_ORDER] = [wx.NewId() for i in xrange(2)]
   573             [ID_CLEAR_EXEC_ORDER, ID_RESET_EXEC_ORDER] = [wx.NewId() for i in xrange(2)]
   544         
   574 
   545             # Create menu items
   575             # Create menu items
   546             self.AddMenuItems(menu, [
   576             self.AddMenuItems(menu, [
   547                  (ID_CLEAR_EXEC_ORDER, wx.ITEM_NORMAL, _(u'Clear Execution Order'), '', self.OnClearExecutionOrderMenu),
   577                  (ID_CLEAR_EXEC_ORDER, wx.ITEM_NORMAL, _(u'Clear Execution Order'), '', self.OnClearExecutionOrderMenu),
   548                  (ID_RESET_EXEC_ORDER, wx.ITEM_NORMAL, _(u'Reset Execution Order'), '', self.OnResetExecutionOrderMenu)])
   578                  (ID_RESET_EXEC_ORDER, wx.ITEM_NORMAL, _(u'Reset Execution Order'), '', self.OnResetExecutionOrderMenu)])
   549             
   579 
   550             menu.AppendSeparator()
   580             menu.AppendSeparator()
   551             
   581 
   552             add_menu = wx.Menu(title='')
   582             add_menu = wx.Menu(title='')
   553             self.AddAddMenuItems(add_menu)
   583             self.AddAddMenuItems(add_menu)
   554             menu.AppendMenu(-1, _(u'Add'), add_menu)
   584             menu.AppendMenu(-1, _(u'Add'), add_menu)
   555         
   585 
   556         menu.AppendSeparator()
   586         menu.AppendSeparator()
   557         
   587 
   558         [ID_CUT, ID_COPY, ID_PASTE] = [wx.NewId() for i in xrange(3)]
   588         [ID_CUT, ID_COPY, ID_PASTE] = [wx.NewId() for i in xrange(3)]
   559         
   589 
   560         # Create menu items
   590         # Create menu items
   561         self.AddMenuItems(menu, [
   591         self.AddMenuItems(menu, [
   562              (ID_CUT, wx.ITEM_NORMAL, _(u'Cut'), '', self.GetClipboardCallBack(self.Cut)),
   592              (ID_CUT, wx.ITEM_NORMAL, _(u'Cut'), '', self.GetClipboardCallBack(self.Cut)),
   563              (ID_COPY, wx.ITEM_NORMAL, _(u'Copy'), '', self.GetClipboardCallBack(self.Copy)),
   593              (ID_COPY, wx.ITEM_NORMAL, _(u'Copy'), '', self.GetClipboardCallBack(self.Copy)),
   564              (ID_PASTE, wx.ITEM_NORMAL, _(u'Paste'), '', self.GetAddMenuCallBack(self.Paste))])
   594              (ID_PASTE, wx.ITEM_NORMAL, _(u'Paste'), '', self.GetAddMenuCallBack(self.Paste))])
   565         
   595 
   566         menu.Enable(ID_CUT, block)
   596         menu.Enable(ID_CUT, block)
   567         menu.Enable(ID_COPY, block)
   597         menu.Enable(ID_COPY, block)
   568         menu.Enable(ID_PASTE, self.ParentWindow.GetCopyBuffer() is not None)
   598         menu.Enable(ID_PASTE, self.ParentWindow.GetCopyBuffer() is not None)
   569         
   599 
   570     def _init_Editor(self, prnt):
   600     def _init_Editor(self, prnt):
   571         self.Editor = wx.ScrolledWindow(prnt, name="Viewer", 
   601         self.Editor = wx.ScrolledWindow(prnt, name="Viewer",
   572             pos=wx.Point(0, 0), size=wx.Size(0, 0), 
   602             pos=wx.Point(0, 0), size=wx.Size(0, 0),
   573             style=wx.HSCROLL | wx.VSCROLL | wx.ALWAYS_SHOW_SB)
   603             style=wx.HSCROLL | wx.VSCROLL | wx.ALWAYS_SHOW_SB)
   574         self.Editor.ParentWindow = self
   604         self.Editor.ParentWindow = self
   575     
   605 
   576     # Create a new Viewer
   606     # Create a new Viewer
   577     def __init__(self, parent, tagname, window, controler, debug = False, instancepath = ""):
   607     def __init__(self, parent, tagname, window, controler, debug = False, instancepath = ""):
   578         self.VARIABLE_PANEL_TYPE = controler.GetPouType(tagname.split("::")[1])
   608         self.VARIABLE_PANEL_TYPE = controler.GetPouType(tagname.split("::")[1])
   579         
   609 
   580         EditorPanel.__init__(self, parent, tagname, window, controler, debug)
   610         EditorPanel.__init__(self, parent, tagname, window, controler, debug)
   581         DebugViewer.__init__(self, controler, debug)
   611         DebugViewer.__init__(self, controler, debug)
   582         
   612 
   583         # Adding a rubberband to Viewer
   613         # Adding a rubberband to Viewer
   584         self.rubberBand = RubberBand(viewer=self)
   614         self.rubberBand = RubberBand(viewer=self)
   585         self.Editor.SetBackgroundColour(wx.Colour(255,255,255))
   615         self.Editor.SetBackgroundColour(wx.Colour(255,255,255))
   586         self.Editor.SetBackgroundStyle(wx.BG_STYLE_CUSTOM)
   616         self.Editor.SetBackgroundStyle(wx.BG_STYLE_CUSTOM)
   587         self.ResetView()
   617         self.ResetView()
   599         self.SearchResults = None
   629         self.SearchResults = None
   600         self.CurrentFindHighlight = None
   630         self.CurrentFindHighlight = None
   601         self.InstancePath = instancepath
   631         self.InstancePath = instancepath
   602         self.StartMousePos = None
   632         self.StartMousePos = None
   603         self.StartScreenPos = None
   633         self.StartScreenPos = None
   604         
   634 
   605         # Prevent search for highlighted element to be called too often
   635         # Prevent search for highlighted element to be called too often
   606         self.LastHighlightCheckTime = gettime()
   636         self.LastHighlightCheckTime = gettime()
   607         # Prevent search for element producing tooltip to be called too often
   637         # Prevent search for element producing tooltip to be called too often
   608         self.LastToolTipCheckTime = gettime()
   638         self.LastToolTipCheckTime = gettime()
   609         
   639 
   610         self.Buffering = False
   640         self.Buffering = False
   611         
   641 
   612         # Initialize Cursors
   642         # Initialize Cursors
   613         ResetCursors()
   643         ResetCursors()
   614         self.CurrentCursor = 0
   644         self.CurrentCursor = 0
   615         
   645 
   616         # Initialize Block, Wire and Comment numbers
   646         # Initialize Block, Wire and Comment numbers
   617         self.wire_id = 0
   647         self.wire_id = 0
   618         
   648 
   619         # Initialize Viewer mode to Selection mode
   649         # Initialize Viewer mode to Selection mode
   620         self.Mode = MODE_SELECTION
   650         self.Mode = MODE_SELECTION
   621         self.SavedMode = False
   651         self.SavedMode = False
   622         self.CurrentLanguage = "FBD"
   652         self.CurrentLanguage = "FBD"
   623         
   653 
   624         if not self.Debug:
   654         if not self.Debug:
   625             self.Editor.SetDropTarget(ViewerDropTarget(self))
   655             self.Editor.SetDropTarget(ViewerDropTarget(self))
   626         
   656 
   627         self.ElementRefreshList = []
   657         self.ElementRefreshList = []
   628         self.ElementRefreshList_lock = Lock()
   658         self.ElementRefreshList_lock = Lock()
   629         
   659 
   630         dc = wx.ClientDC(self.Editor)
   660         dc = wx.ClientDC(self.Editor)
   631         font = wx.Font(faces["size"], wx.SWISS, wx.NORMAL, wx.NORMAL, faceName = faces["mono"])
   661         font = wx.Font(faces["size"], wx.SWISS, wx.NORMAL, wx.NORMAL, faceName = faces["mono"])
   632         dc.SetFont(font)
   662         dc.SetFont(font)
   633         width, height = dc.GetTextExtent("ABCDEFGHIJKLMNOPQRSTUVWXYZ")
   663         width, height = dc.GetTextExtent("ABCDEFGHIJKLMNOPQRSTUVWXYZ")
   634         while width > 260:
   664         while width > 260:
   637             dc.SetFont(font)
   667             dc.SetFont(font)
   638             width, height = dc.GetTextExtent("ABCDEFGHIJKLMNOPQRSTUVWXYZ")
   668             width, height = dc.GetTextExtent("ABCDEFGHIJKLMNOPQRSTUVWXYZ")
   639         self.SetFont(font)
   669         self.SetFont(font)
   640         self.MiniTextDC = wx.MemoryDC()
   670         self.MiniTextDC = wx.MemoryDC()
   641         self.MiniTextDC.SetFont(wx.Font(faces["size"] * 0.75, wx.SWISS, wx.NORMAL, wx.NORMAL, faceName = faces["helv"]))
   671         self.MiniTextDC.SetFont(wx.Font(faces["size"] * 0.75, wx.SWISS, wx.NORMAL, wx.NORMAL, faceName = faces["helv"]))
   642         
   672 
   643         self.CurrentScale = None
   673         self.CurrentScale = None
   644         self.SetScale(ZOOM_FACTORS.index(1.0), False)
   674         self.SetScale(ZOOM_FACTORS.index(1.0), False)
   645         
   675 
   646         self.RefreshHighlightsTimer = wx.Timer(self, -1)
   676         self.RefreshHighlightsTimer = wx.Timer(self, -1)
   647         self.Bind(wx.EVT_TIMER, self.OnRefreshHighlightsTimer, self.RefreshHighlightsTimer)
   677         self.Bind(wx.EVT_TIMER, self.OnRefreshHighlightsTimer, self.RefreshHighlightsTimer)
   648         
   678 
   649         self.ResetView()
   679         self.ResetView()
   650         
   680 
   651         # Link Viewer event to corresponding methods
   681         # Link Viewer event to corresponding methods
   652         self.Editor.Bind(wx.EVT_PAINT, self.OnPaint)
   682         self.Editor.Bind(wx.EVT_PAINT, self.OnPaint)
   653         self.Editor.Bind(wx.EVT_LEFT_DOWN, self.OnViewerLeftDown)
   683         self.Editor.Bind(wx.EVT_LEFT_DOWN, self.OnViewerLeftDown)
   654         self.Editor.Bind(wx.EVT_LEFT_UP, self.OnViewerLeftUp)
   684         self.Editor.Bind(wx.EVT_LEFT_UP, self.OnViewerLeftUp)
   655         self.Editor.Bind(wx.EVT_LEFT_DCLICK, self.OnViewerLeftDClick)
   685         self.Editor.Bind(wx.EVT_LEFT_DCLICK, self.OnViewerLeftDClick)
   663         self.Editor.Bind(wx.EVT_SCROLLWIN, self.OnScrollWindow)
   693         self.Editor.Bind(wx.EVT_SCROLLWIN, self.OnScrollWindow)
   664         self.Editor.Bind(wx.EVT_SCROLLWIN_THUMBRELEASE, self.OnScrollStop)
   694         self.Editor.Bind(wx.EVT_SCROLLWIN_THUMBRELEASE, self.OnScrollStop)
   665         self.Editor.Bind(wx.EVT_MOUSEWHEEL, self.OnMouseWheelWindow)
   695         self.Editor.Bind(wx.EVT_MOUSEWHEEL, self.OnMouseWheelWindow)
   666         self.Editor.Bind(wx.EVT_SIZE, self.OnMoveWindow)
   696         self.Editor.Bind(wx.EVT_SIZE, self.OnMoveWindow)
   667         self.Editor.Bind(wx.EVT_MOUSE_EVENTS, self.OnViewerMouseEvent)
   697         self.Editor.Bind(wx.EVT_MOUSE_EVENTS, self.OnViewerMouseEvent)
   668     
   698 
   669     # Destructor
   699     # Destructor
   670     def __del__(self):
   700     def __del__(self):
   671         DebugViewer.__del__(self)
   701         DebugViewer.__del__(self)
   672         self.Flush()
   702         self.Flush()
   673         self.ResetView()
   703         self.ResetView()
   674         self.RefreshHighlightsTimer.Stop()
   704         self.RefreshHighlightsTimer.Stop()
   675     
   705 
   676     def SetCurrentCursor(self, cursor):
   706     def SetCurrentCursor(self, cursor):
   677         if self.Mode != MODE_MOTION:
   707         if self.Mode != MODE_MOTION:
   678             global CURSORS
   708             global CURSORS
   679             if self.CurrentCursor != cursor:
   709             if self.CurrentCursor != cursor:
   680                 self.CurrentCursor = cursor
   710                 self.CurrentCursor = cursor
   681                 self.Editor.SetCursor(CURSORS[cursor])
   711                 self.Editor.SetCursor(CURSORS[cursor])
   682     
   712 
   683     def GetScrolledRect(self, rect):
   713     def GetScrolledRect(self, rect):
   684         rect.x, rect.y = self.Editor.CalcScrolledPosition(int(rect.x * self.ViewScale[0]), 
   714         rect.x, rect.y = self.Editor.CalcScrolledPosition(int(rect.x * self.ViewScale[0]),
   685                                                    int(rect.y * self.ViewScale[1]))
   715                                                    int(rect.y * self.ViewScale[1]))
   686         rect.width = int(rect.width * self.ViewScale[0]) + 2
   716         rect.width = int(rect.width * self.ViewScale[0]) + 2
   687         rect.height = int(rect.height * self.ViewScale[1]) + 2
   717         rect.height = int(rect.height * self.ViewScale[1]) + 2
   688         return rect
   718         return rect
   689     
   719 
   690     def GetTitle(self):
   720     def GetTitle(self):
   691         if self.Debug:
   721         if self.Debug:
   692             if len(self.InstancePath) > 15:
   722             if len(self.InstancePath) > 15:
   693                 return "..." + self.InstancePath[-12:]
   723                 return "..." + self.InstancePath[-12:]
   694             return self.InstancePath
   724             return self.InstancePath
   695         return EditorPanel.GetTitle(self)
   725         return EditorPanel.GetTitle(self)
   696     
   726 
   697     def GetScaling(self):
   727     def GetScaling(self):
   698         return self.Scaling
   728         return self.Scaling
   699     
   729 
   700     def GetInstancePath(self, variable_base=False):
   730     def GetInstancePath(self, variable_base=False):
   701         if variable_base:
   731         if variable_base:
   702             words = self.TagName.split("::")
   732             words = self.TagName.split("::")
   703             if words[0] in ["A", "T"]:
   733             if words[0] in ["A", "T"]:
   704                 return ".".join(self.InstancePath.split(".")[:-1])
   734                 return ".".join(self.InstancePath.split(".")[:-1])
   705         return self.InstancePath
   735         return self.InstancePath
   706     
   736 
   707     def IsViewing(self, tagname):
   737     def IsViewing(self, tagname):
   708         if self.Debug:
   738         if self.Debug:
   709             return self.InstancePath == tagname
   739             return self.InstancePath == tagname
   710         return EditorPanel.IsViewing(self, tagname)
   740         return EditorPanel.IsViewing(self, tagname)
   711     
   741 
   712     # Returns a new id
   742     # Returns a new id
   713     def GetNewId(self):
   743     def GetNewId(self):
   714         self.current_id += 1
   744         self.current_id += 1
   715         return self.current_id
   745         return self.current_id
   716         
   746 
   717     def SetScale(self, scale_number, refresh=True, mouse_event=None):
   747     def SetScale(self, scale_number, refresh=True, mouse_event=None):
   718         new_scale = max(0, min(scale_number, len(ZOOM_FACTORS) - 1))
   748         new_scale = max(0, min(scale_number, len(ZOOM_FACTORS) - 1))
   719         if self.CurrentScale != new_scale:
   749         if self.CurrentScale != new_scale:
   720             if refresh:
   750             if refresh:
   721                 dc = self.GetLogicalDC()
   751                 dc = self.GetLogicalDC()
   742                 else:
   772                 else:
   743                     self.Scroll(scrollx, scrolly)
   773                     self.Scroll(scrollx, scrolly)
   744                     self.RefreshScrollBars()
   774                     self.RefreshScrollBars()
   745                 self.RefreshScaling(refresh)
   775                 self.RefreshScaling(refresh)
   746                 self.Editor.Thaw()
   776                 self.Editor.Thaw()
   747     
   777 
   748     def GetScale(self):
   778     def GetScale(self):
   749         return self.CurrentScale
   779         return self.CurrentScale
   750 
   780 
   751     def GetViewScale(self):
   781     def GetViewScale(self):
   752         return self.ViewScale
   782         return self.ViewScale
   762             self.Editor.DoPrepareDC(dc)
   792             self.Editor.DoPrepareDC(dc)
   763         else:
   793         else:
   764             self.Editor.PrepareDC(dc)
   794             self.Editor.PrepareDC(dc)
   765         dc.SetUserScale(self.ViewScale[0], self.ViewScale[1])
   795         dc.SetUserScale(self.ViewScale[0], self.ViewScale[1])
   766         return dc
   796         return dc
   767     
   797 
   768     def RefreshRect(self, rect, eraseBackground=True):
   798     def RefreshRect(self, rect, eraseBackground=True):
   769         self.Editor.RefreshRect(rect, eraseBackground)
   799         self.Editor.RefreshRect(rect, eraseBackground)
   770     
   800 
   771     def Scroll(self, x, y):
   801     def Scroll(self, x, y):
   772         if self.Debug and wx.Platform == '__WXMSW__':
   802         if self.Debug and wx.Platform == '__WXMSW__':
   773             self.Editor.Freeze()
   803             self.Editor.Freeze()
   774         self.Editor.Scroll(x, y)
   804         self.Editor.Scroll(x, y)
   775         if self.Debug:
   805         if self.Debug:
   776             if wx.Platform == '__WXMSW__':
   806             if wx.Platform == '__WXMSW__':
   777                 self.Editor.Thaw()
   807                 self.Editor.Thaw()
   778             else:
   808             else:
   779                 self.Editor.Refresh()
   809                 self.Editor.Refresh()
   780     
   810 
   781     def GetScrollPos(self, orientation):
   811     def GetScrollPos(self, orientation):
   782         return self.Editor.GetScrollPos(orientation)
   812         return self.Editor.GetScrollPos(orientation)
   783     
   813 
   784     def GetScrollRange(self, orientation):
   814     def GetScrollRange(self, orientation):
   785         return self.Editor.GetScrollRange(orientation)
   815         return self.Editor.GetScrollRange(orientation)
   786     
   816 
   787     def GetScrollThumb(self, orientation):
   817     def GetScrollThumb(self, orientation):
   788         return self.Editor.GetScrollThumb(orientation)
   818         return self.Editor.GetScrollThumb(orientation)
   789     
   819 
   790     def CalcUnscrolledPosition(self, x, y):
   820     def CalcUnscrolledPosition(self, x, y):
   791         return self.Editor.CalcUnscrolledPosition(x, y)
   821         return self.Editor.CalcUnscrolledPosition(x, y)
   792     
   822 
   793     def GetViewStart(self):
   823     def GetViewStart(self):
   794         return self.Editor.GetViewStart()
   824         return self.Editor.GetViewStart()
   795     
   825 
   796     def GetTextExtent(self, text):
   826     def GetTextExtent(self, text):
   797         return self.Editor.GetTextExtent(text)
   827         return self.Editor.GetTextExtent(text)
   798     
   828 
   799     def GetFont(self):
   829     def GetFont(self):
   800         return self.Editor.GetFont()
   830         return self.Editor.GetFont()
   801     
   831 
   802     def GetMiniTextExtent(self, text):
   832     def GetMiniTextExtent(self, text):
   803         return self.MiniTextDC.GetTextExtent(text)
   833         return self.MiniTextDC.GetTextExtent(text)
   804     
   834 
   805     def GetMiniFont(self):
   835     def GetMiniFont(self):
   806         return self.MiniTextDC.GetFont()
   836         return self.MiniTextDC.GetFont()
   807     
   837 
   808 #-------------------------------------------------------------------------------
   838 #-------------------------------------------------------------------------------
   809 #                         Element management functions
   839 #                         Element management functions
   810 #-------------------------------------------------------------------------------
   840 #-------------------------------------------------------------------------------
   811 
   841 
   812     def AddBlock(self, block):
   842     def AddBlock(self, block):
   813         self.Blocks[block.GetId()] = block
   843         self.Blocks[block.GetId()] = block
   814         
   844 
   815     def AddWire(self, wire):
   845     def AddWire(self, wire):
   816         self.wire_id += 1
   846         self.wire_id += 1
   817         self.Wires[wire] = self.wire_id
   847         self.Wires[wire] = self.wire_id
   818         
   848 
   819     def AddComment(self, comment):
   849     def AddComment(self, comment):
   820         self.Comments[comment.GetId()] = comment
   850         self.Comments[comment.GetId()] = comment
   821 
   851 
   822     def IsBlock(self, block):
   852     def IsBlock(self, block):
   823         if block is not None:
   853         if block is not None:
   824             return self.Blocks.get(block.GetId(), False)
   854             return self.Blocks.get(block.GetId(), False)
   825         return False
   855         return False
   826         
   856 
   827     def IsWire(self, wire):
   857     def IsWire(self, wire):
   828         return self.Wires.get(wire, False)
   858         return self.Wires.get(wire, False)
   829         
   859 
   830     def IsComment(self, comment):
   860     def IsComment(self, comment):
   831         if comment is not None:
   861         if comment is not None:
   832             return self.Comments.get(comment.GetId(), False)
   862             return self.Comments.get(comment.GetId(), False)
   833         return False
   863         return False
   834 
   864 
   835     def RemoveBlock(self, block):
   865     def RemoveBlock(self, block):
   836         self.Blocks.pop(block.GetId())
   866         self.Blocks.pop(block.GetId())
   837         
   867 
   838     def RemoveWire(self, wire):
   868     def RemoveWire(self, wire):
   839         self.Wires.pop(wire)
   869         self.Wires.pop(wire)
   840         
   870 
   841     def RemoveComment(self, comment):
   871     def RemoveComment(self, comment):
   842         self.Comments.pop(comment.GetId())
   872         self.Comments.pop(comment.GetId())
   843 
   873 
   844     def GetElements(self, sort_blocks=False, sort_wires=False, sort_comments=False):
   874     def GetElements(self, sort_blocks=False, sort_wires=False, sort_comments=False):
   845         blocks = self.Blocks.values()
   875         blocks = self.Blocks.values()
   858             if isinstance(block, FBD_Connector) and\
   888             if isinstance(block, FBD_Connector) and\
   859                block.GetType() == CONNECTOR and\
   889                block.GetType() == CONNECTOR and\
   860                block.GetName() == name:
   890                block.GetName() == name:
   861                 return block
   891                 return block
   862         return None
   892         return None
   863     
   893 
   864     def RefreshVisibleElements(self, xp = None, yp = None):
   894     def RefreshVisibleElements(self, xp = None, yp = None):
   865         x, y = self.Editor.CalcUnscrolledPosition(0, 0)
   895         x, y = self.Editor.CalcUnscrolledPosition(0, 0)
   866         if xp is not None:
   896         if xp is not None:
   867             x = xp * self.Editor.GetScrollPixelsPerUnit()[0]
   897             x = xp * self.Editor.GetScrollPixelsPerUnit()[0]
   868         if yp is not None:
   898         if yp is not None:
   874             comment.TestVisible(screen)
   904             comment.TestVisible(screen)
   875         for wire in self.Wires.iterkeys():
   905         for wire in self.Wires.iterkeys():
   876             wire.TestVisible(screen)
   906             wire.TestVisible(screen)
   877         for block in self.Blocks.itervalues():
   907         for block in self.Blocks.itervalues():
   878             block.TestVisible(screen)
   908             block.TestVisible(screen)
   879     
   909 
   880     def GetElementIECPath(self, element):
   910     def GetElementIECPath(self, element):
   881         iec_path = None
   911         iec_path = None
   882         instance_path = self.GetInstancePath(True)
   912         instance_path = self.GetInstancePath(True)
   883         if isinstance(element, (Wire, Connector)):
   913         if isinstance(element, (Wire, Connector)):
   884             if isinstance(element, Wire):
   914             if isinstance(element, Wire):
   910             connectors = element.GetConnectors()
   940             connectors = element.GetConnectors()
   911             previous_steps = self.GetPreviousSteps(connectors["inputs"])
   941             previous_steps = self.GetPreviousSteps(connectors["inputs"])
   912             next_steps = self.GetNextSteps(connectors["outputs"])
   942             next_steps = self.GetNextSteps(connectors["outputs"])
   913             iec_path = "%s.%s->%s"%(instance_path, ",".join(previous_steps), ",".join(next_steps))
   943             iec_path = "%s.%s->%s"%(instance_path, ",".join(previous_steps), ",".join(next_steps))
   914         return iec_path
   944         return iec_path
   915     
   945 
   916     def GetWireModifier(self, wire):
   946     def GetWireModifier(self, wire):
   917         connector = wire.EndConnected
   947         connector = wire.EndConnected
   918         block = connector.GetParentBlock()
   948         block = connector.GetParentBlock()
   919         if isinstance(block, FBD_Connector):
   949         if isinstance(block, FBD_Connector):
   920             connection = self.GetConnectorByName(block.GetName())
   950             connection = self.GetConnectorByName(block.GetName())
   926             if connector.IsNegated():
   956             if connector.IsNegated():
   927                 return "negated"
   957                 return "negated"
   928             else:
   958             else:
   929                 return connector.GetEdge()
   959                 return connector.GetEdge()
   930         return "none"
   960         return "none"
   931         
   961 
   932 #-------------------------------------------------------------------------------
   962 #-------------------------------------------------------------------------------
   933 #                              Reset functions
   963 #                              Reset functions
   934 #-------------------------------------------------------------------------------
   964 #-------------------------------------------------------------------------------
   935 
   965 
   936     # Resets Viewer lists
   966     # Resets Viewer lists
   940         self.Comments = {}
   970         self.Comments = {}
   941         self.Subscribed = {}
   971         self.Subscribed = {}
   942         self.SelectedElement = None
   972         self.SelectedElement = None
   943         self.HighlightedElement = None
   973         self.HighlightedElement = None
   944         self.ToolTipElement = None
   974         self.ToolTipElement = None
   945     
   975 
   946     def Flush(self):
   976     def Flush(self):
   947         self.UnsubscribeAllDataConsumers(tick=False)
   977         self.UnsubscribeAllDataConsumers(tick=False)
   948         for block in self.Blocks.itervalues():
   978         for block in self.Blocks.itervalues():
   949             block.Flush()
   979             block.Flush()
   950         
   980 
   951     # Remove all elements
   981     # Remove all elements
   952     def CleanView(self):
   982     def CleanView(self):
   953         for block in self.Blocks.itervalues():
   983         for block in self.Blocks.itervalues():
   954             block.Clean()
   984             block.Clean()
   955         self.ResetView()
   985         self.ResetView()
   956     
   986 
   957     # Changes Viewer mode
   987     # Changes Viewer mode
   958     def SetMode(self, mode):
   988     def SetMode(self, mode):
   959         if self.Mode != mode or mode == MODE_SELECTION:    
   989         if self.Mode != mode or mode == MODE_SELECTION:
   960             if self.Mode == MODE_MOTION:
   990             if self.Mode == MODE_MOTION:
   961                 wx.CallAfter(self.Editor.SetCursor, wx.NullCursor)
   991                 wx.CallAfter(self.Editor.SetCursor, wx.NullCursor)
   962             self.Mode = mode
   992             self.Mode = mode
   963             self.SavedMode = False
   993             self.SavedMode = False
   964         else:
   994         else:
   968             self.SelectedElement.SetSelected(False)
   998             self.SelectedElement.SetSelected(False)
   969             self.SelectedElement = None
   999             self.SelectedElement = None
   970         if self.Mode == MODE_MOTION:
  1000         if self.Mode == MODE_MOTION:
   971             wx.CallAfter(self.Editor.SetCursor, wx.StockCursor(wx.CURSOR_HAND))
  1001             wx.CallAfter(self.Editor.SetCursor, wx.StockCursor(wx.CURSOR_HAND))
   972             self.SavedMode = True
  1002             self.SavedMode = True
   973         
  1003 
   974     # Return current drawing mode
  1004     # Return current drawing mode
   975     def GetDrawingMode(self):
  1005     def GetDrawingMode(self):
   976         return self.ParentWindow.GetDrawingMode()
  1006         return self.ParentWindow.GetDrawingMode()
   977     
  1007 
   978     # Buffer the last model state
  1008     # Buffer the last model state
   979     def RefreshBuffer(self):
  1009     def RefreshBuffer(self):
   980         self.Controler.BufferProject()
  1010         self.Controler.BufferProject()
   981         if self.ParentWindow:
  1011         if self.ParentWindow:
   982             self.ParentWindow.RefreshTitle()
  1012             self.ParentWindow.RefreshTitle()
   983             self.ParentWindow.RefreshFileMenu()
  1013             self.ParentWindow.RefreshFileMenu()
   984             self.ParentWindow.RefreshEditMenu()
  1014             self.ParentWindow.RefreshEditMenu()
   985     
  1015 
   986     def StartBuffering(self):
  1016     def StartBuffering(self):
   987         if not self.Buffering:
  1017         if not self.Buffering:
   988             self.Buffering = True
  1018             self.Buffering = True
   989             self.Controler.StartBuffering()
  1019             self.Controler.StartBuffering()
   990             if self.ParentWindow:
  1020             if self.ParentWindow:
   991                 self.ParentWindow.RefreshTitle()
  1021                 self.ParentWindow.RefreshTitle()
   992                 self.ParentWindow.RefreshFileMenu()
  1022                 self.ParentWindow.RefreshFileMenu()
   993                 self.ParentWindow.RefreshEditMenu()
  1023                 self.ParentWindow.RefreshEditMenu()
   994     
  1024 
   995     def ResetBuffer(self):
  1025     def ResetBuffer(self):
   996         if self.Buffering:
  1026         if self.Buffering:
   997             self.Controler.EndBuffering()
  1027             self.Controler.EndBuffering()
   998             self.Buffering = False
  1028             self.Buffering = False
   999     
  1029 
  1000     def GetBufferState(self):
  1030     def GetBufferState(self):
  1001         if not self.Debug:
  1031         if not self.Debug:
  1002             return self.Controler.GetBufferState()
  1032             return self.Controler.GetBufferState()
  1003         return False, False
  1033         return False, False
  1004     
  1034 
  1005     def Undo(self):
  1035     def Undo(self):
  1006         if not self.Debug:
  1036         if not self.Debug:
  1007             self.Controler.LoadPrevious()
  1037             self.Controler.LoadPrevious()
  1008             self.ParentWindow.CloseTabsWithoutModel()
  1038             self.ParentWindow.CloseTabsWithoutModel()
  1009             
  1039 
  1010     def Redo(self):
  1040     def Redo(self):
  1011         if not self.Debug:
  1041         if not self.Debug:
  1012             self.Controler.LoadNext()
  1042             self.Controler.LoadNext()
  1013             self.ParentWindow.CloseTabsWithoutModel()
  1043             self.ParentWindow.CloseTabsWithoutModel()
  1014         
  1044 
  1015     def HasNoModel(self):
  1045     def HasNoModel(self):
  1016         if not self.Debug:
  1046         if not self.Debug:
  1017             return self.Controler.GetEditedElement(self.TagName) is None
  1047             return self.Controler.GetEditedElement(self.TagName) is None
  1018         return False
  1048         return False
  1019     
  1049 
  1020     # Refresh the current scaling
  1050     # Refresh the current scaling
  1021     def RefreshScaling(self, refresh=True):
  1051     def RefreshScaling(self, refresh=True):
  1022         properties = self.Controler.GetProjectProperties(self.Debug)
  1052         properties = self.Controler.GetProjectProperties(self.Debug)
  1023         scaling = properties["scaling"][self.CurrentLanguage]
  1053         scaling = properties["scaling"][self.CurrentLanguage]
  1024         if scaling[0] != 0 and scaling[1] != 0:
  1054         if scaling[0] != 0 and scaling[1] != 0:
  1046             self.PageSize = None
  1076             self.PageSize = None
  1047             self.PagePen = wx.TRANSPARENT_PEN
  1077             self.PagePen = wx.TRANSPARENT_PEN
  1048         if refresh:
  1078         if refresh:
  1049             self.RefreshVisibleElements()
  1079             self.RefreshVisibleElements()
  1050             self.Editor.Refresh(False)
  1080             self.Editor.Refresh(False)
  1051         
  1081 
  1052         
  1082 
  1053 #-------------------------------------------------------------------------------
  1083 #-------------------------------------------------------------------------------
  1054 #                          Refresh functions
  1084 #                          Refresh functions
  1055 #-------------------------------------------------------------------------------
  1085 #-------------------------------------------------------------------------------
  1056     
  1086 
  1057     VALUE_TRANSLATION = {True: _("Active"), False: _("Inactive")}
  1087     VALUE_TRANSLATION = {True: _("Active"), False: _("Inactive")}
  1058 
  1088 
  1059     def SetValue(self, value):
  1089     def SetValue(self, value):
  1060         if self.Value != value:
  1090         if self.Value != value:
  1061             self.Value = value
  1091             self.Value = value
  1062             
  1092 
  1063             xstart, ystart = self.GetViewStart()
  1093             xstart, ystart = self.GetViewStart()
  1064             window_size = self.Editor.GetClientSize()
  1094             window_size = self.Editor.GetClientSize()
  1065             refresh_rect = self.GetRedrawRect()
  1095             refresh_rect = self.GetRedrawRect()
  1066             if (xstart * SCROLLBAR_UNIT <= refresh_rect.x + refresh_rect.width and 
  1096             if (xstart * SCROLLBAR_UNIT <= refresh_rect.x + refresh_rect.width and
  1067                 xstart * SCROLLBAR_UNIT + window_size[0] >= refresh_rect.x and
  1097                 xstart * SCROLLBAR_UNIT + window_size[0] >= refresh_rect.x and
  1068                 ystart * SCROLLBAR_UNIT <= refresh_rect.y + refresh_rect.height and 
  1098                 ystart * SCROLLBAR_UNIT <= refresh_rect.y + refresh_rect.height and
  1069                 ystart * SCROLLBAR_UNIT + window_size[1] >= refresh_rect.y):
  1099                 ystart * SCROLLBAR_UNIT + window_size[1] >= refresh_rect.y):
  1070                 self.ElementNeedRefresh(self)
  1100                 self.ElementNeedRefresh(self)
  1071     
  1101 
  1072     def GetRedrawRect(self):
  1102     def GetRedrawRect(self):
  1073         dc = self.GetLogicalDC()
  1103         dc = self.GetLogicalDC()
  1074         ipw, iph = dc.GetTextExtent(_("Debug: %s") % self.InstancePath)
  1104         ipw, iph = dc.GetTextExtent(_("Debug: %s") % self.InstancePath)
  1075         vw, vh = 0, 0
  1105         vw, vh = 0, 0
  1076         for value in self.VALUE_TRANSLATION.itervalues():
  1106         for value in self.VALUE_TRANSLATION.itervalues():
  1077             w, h = dc.GetTextExtent("(%s)" % value)
  1107             w, h = dc.GetTextExtent("(%s)" % value)
  1078             vw = max(vw, w)
  1108             vw = max(vw, w)
  1079             vh = max(vh, h)
  1109             vh = max(vh, h)
  1080         return wx.Rect(ipw + 4, 2, vw, vh)
  1110         return wx.Rect(ipw + 4, 2, vw, vh)
  1081     
  1111 
  1082     def ElementNeedRefresh(self, element):
  1112     def ElementNeedRefresh(self, element):
  1083         self.ElementRefreshList_lock.acquire()
  1113         self.ElementRefreshList_lock.acquire()
  1084         self.ElementRefreshList.append(element)
  1114         self.ElementRefreshList.append(element)
  1085         self.ElementRefreshList_lock.release()
  1115         self.ElementRefreshList_lock.release()
  1086         
  1116 
  1087     def NewDataAvailable(self, ticks, *args, **kwargs):
  1117     def NewDataAvailable(self, ticks, *args, **kwargs):
  1088         if self.IsShown():
  1118         if self.IsShown():
  1089             refresh_rect = None
  1119             refresh_rect = None
  1090             self.ElementRefreshList_lock.acquire()
  1120             self.ElementRefreshList_lock.acquire()
  1091             for element in self.ElementRefreshList:
  1121             for element in self.ElementRefreshList:
  1093                     refresh_rect = element.GetRedrawRect()
  1123                     refresh_rect = element.GetRedrawRect()
  1094                 else:
  1124                 else:
  1095                     refresh_rect.Union(element.GetRedrawRect())
  1125                     refresh_rect.Union(element.GetRedrawRect())
  1096             self.ElementRefreshList = []
  1126             self.ElementRefreshList = []
  1097             self.ElementRefreshList_lock.release()
  1127             self.ElementRefreshList_lock.release()
  1098             
  1128 
  1099             if refresh_rect is not None:
  1129             if refresh_rect is not None:
  1100                 self.RefreshRect(self.GetScrolledRect(refresh_rect), False)
  1130                 self.RefreshRect(self.GetScrolledRect(refresh_rect), False)
  1101         
  1131 
  1102     def SubscribeAllDataConsumers(self):
  1132     def SubscribeAllDataConsumers(self):
  1103         self.RefreshView()
  1133         self.RefreshView()
  1104         DebugViewer.SubscribeAllDataConsumers(self)
  1134         DebugViewer.SubscribeAllDataConsumers(self)
  1105         
  1135 
  1106     # Refresh Viewer elements
  1136     # Refresh Viewer elements
  1107     def RefreshView(self, variablepanel=True, selection=None):
  1137     def RefreshView(self, variablepanel=True, selection=None):
  1108         EditorPanel.RefreshView(self, variablepanel)
  1138         EditorPanel.RefreshView(self, variablepanel)
  1109         
  1139 
  1110         if self.TagName.split("::")[0] == "A" and self.Debug:
  1140         if self.TagName.split("::")[0] == "A" and self.Debug:
  1111             self.AddDataConsumer("%s.Q" % self.InstancePath.upper(), self)
  1141             self.AddDataConsumer("%s.Q" % self.InstancePath.upper(), self)
  1112         
  1142 
  1113         if self.ToolTipElement is not None:
  1143         if self.ToolTipElement is not None:
  1114             self.ToolTipElement.DestroyToolTip()
  1144             self.ToolTipElement.DestroyToolTip()
  1115             self.ToolTipElement = None
  1145             self.ToolTipElement = None
  1116         
  1146 
  1117         self.Inhibit(True)
  1147         self.Inhibit(True)
  1118         self.current_id = 0
  1148         self.current_id = 0
  1119         # Start by reseting Viewer
  1149         # Start by reseting Viewer
  1120         self.Flush()
  1150         self.Flush()
  1121         self.ResetView()
  1151         self.ResetView()
  1124         # List of ids of already loaded blocks
  1154         # List of ids of already loaded blocks
  1125         instances = self.Controler.GetEditedElementInstancesInfos(self.TagName, debug = self.Debug)
  1155         instances = self.Controler.GetEditedElementInstancesInfos(self.TagName, debug = self.Debug)
  1126         # Load Blocks until they are all loaded
  1156         # Load Blocks until they are all loaded
  1127         while len(instances) > 0:
  1157         while len(instances) > 0:
  1128             self.loadInstance(instances.popitem(0)[1], instances, selection)
  1158             self.loadInstance(instances.popitem(0)[1], instances, selection)
  1129         
  1159 
  1130         if (selection is not None and 
  1160         if (selection is not None and
  1131             isinstance(self.SelectedElement, Graphic_Group)):
  1161             isinstance(self.SelectedElement, Graphic_Group)):
  1132             self.SelectedElement.RefreshWireExclusion()
  1162             self.SelectedElement.RefreshWireExclusion()
  1133             self.SelectedElement.RefreshBoundingBox()
  1163             self.SelectedElement.RefreshBoundingBox()
  1134         
  1164 
  1135         self.RefreshScrollBars()
  1165         self.RefreshScrollBars()
  1136         
  1166 
  1137         for wire in self.Wires:
  1167         for wire in self.Wires:
  1138             if not wire.IsConnectedCompatible():
  1168             if not wire.IsConnectedCompatible():
  1139                 wire.SetValid(False)
  1169                 wire.SetValid(False)
  1140             if self.Debug:
  1170             if self.Debug:
  1141                 iec_path = self.GetElementIECPath(wire)
  1171                 iec_path = self.GetElementIECPath(wire)
  1164 
  1194 
  1165         self.Inhibit(False)
  1195         self.Inhibit(False)
  1166         self.RefreshVisibleElements()
  1196         self.RefreshVisibleElements()
  1167         self.ShowHighlights()
  1197         self.ShowHighlights()
  1168         self.Editor.Refresh(False)
  1198         self.Editor.Refresh(False)
  1169     
  1199 
  1170     def GetPreviousSteps(self, connectors):
  1200     def GetPreviousSteps(self, connectors):
  1171         steps = []
  1201         steps = []
  1172         for connector in connectors:
  1202         for connector in connectors:
  1173             for wire, handle in connector.GetWires():
  1203             for wire, handle in connector.GetWires():
  1174                 previous = wire.GetOtherConnected(connector).GetParentBlock()
  1204                 previous = wire.GetOtherConnected(connector).GetParentBlock()
  1176                     steps.append(previous.GetName())
  1206                     steps.append(previous.GetName())
  1177                 elif isinstance(previous, SFC_Divergence) and previous.GetType() in [SIMULTANEOUS_CONVERGENCE, SELECTION_DIVERGENCE]:
  1207                 elif isinstance(previous, SFC_Divergence) and previous.GetType() in [SIMULTANEOUS_CONVERGENCE, SELECTION_DIVERGENCE]:
  1178                     connectors = previous.GetConnectors()
  1208                     connectors = previous.GetConnectors()
  1179                     steps.extend(self.GetPreviousSteps(connectors["inputs"]))
  1209                     steps.extend(self.GetPreviousSteps(connectors["inputs"]))
  1180         return steps
  1210         return steps
  1181     
  1211 
  1182     def GetNextSteps(self, connectors):
  1212     def GetNextSteps(self, connectors):
  1183         steps = []
  1213         steps = []
  1184         for connector in connectors:
  1214         for connector in connectors:
  1185             for wire, handle in connector.GetWires():
  1215             for wire, handle in connector.GetWires():
  1186                 next = wire.GetOtherConnected(connector).GetParentBlock()
  1216                 next = wire.GetOtherConnected(connector).GetParentBlock()
  1190                     steps.append(next.GetTarget())
  1220                     steps.append(next.GetTarget())
  1191                 elif isinstance(next, SFC_Divergence) and next.GetType() in [SIMULTANEOUS_DIVERGENCE, SELECTION_CONVERGENCE]:
  1221                 elif isinstance(next, SFC_Divergence) and next.GetType() in [SIMULTANEOUS_DIVERGENCE, SELECTION_CONVERGENCE]:
  1192                     connectors = next.GetConnectors()
  1222                     connectors = next.GetConnectors()
  1193                     steps.extend(self.GetNextSteps(connectors["outputs"]))
  1223                     steps.extend(self.GetNextSteps(connectors["outputs"]))
  1194         return steps
  1224         return steps
  1195     
  1225 
  1196     def GetMaxSize(self):
  1226     def GetMaxSize(self):
  1197         maxx = maxy = 0
  1227         maxx = maxy = 0
  1198         for element in self.GetElements():
  1228         for element in self.GetElements():
  1199             bbox = element.GetBoundingBox()
  1229             bbox = element.GetBoundingBox()
  1200             maxx = max(maxx, bbox.x + bbox.width)
  1230             maxx = max(maxx, bbox.x + bbox.width)
  1201             maxy = max(maxy, bbox.y + bbox.height)
  1231             maxy = max(maxy, bbox.y + bbox.height)
  1202         return maxx, maxy
  1232         return maxx, maxy
  1203     
  1233 
  1204     def RefreshScrollBars(self, width_incr=0, height_incr=0):
  1234     def RefreshScrollBars(self, width_incr=0, height_incr=0):
  1205         xstart, ystart = self.GetViewStart()
  1235         xstart, ystart = self.GetViewStart()
  1206         window_size = self.Editor.GetClientSize()
  1236         window_size = self.Editor.GetClientSize()
  1207         maxx, maxy = self.GetMaxSize()
  1237         maxx, maxy = self.GetMaxSize()
  1208         maxx = max(maxx + WINDOW_BORDER, (xstart * SCROLLBAR_UNIT + window_size[0]) / self.ViewScale[0])
  1238         maxx = max(maxx + WINDOW_BORDER, (xstart * SCROLLBAR_UNIT + window_size[0]) / self.ViewScale[0])
  1211             extent = self.rubberBand.GetCurrentExtent()
  1241             extent = self.rubberBand.GetCurrentExtent()
  1212             maxx = max(maxx, extent.x + extent.width)
  1242             maxx = max(maxx, extent.x + extent.width)
  1213             maxy = max(maxy, extent.y + extent.height)
  1243             maxy = max(maxy, extent.y + extent.height)
  1214         maxx = int(maxx * self.ViewScale[0])
  1244         maxx = int(maxx * self.ViewScale[0])
  1215         maxy = int(maxy * self.ViewScale[1])
  1245         maxy = int(maxy * self.ViewScale[1])
  1216         self.Editor.SetScrollbars(SCROLLBAR_UNIT, SCROLLBAR_UNIT, 
  1246         self.Editor.SetScrollbars(SCROLLBAR_UNIT, SCROLLBAR_UNIT,
  1217             round(maxx / SCROLLBAR_UNIT) + width_incr, round(maxy / SCROLLBAR_UNIT) + height_incr, 
  1247             round(maxx / SCROLLBAR_UNIT) + width_incr, round(maxy / SCROLLBAR_UNIT) + height_incr,
  1218             xstart, ystart, True)
  1248             xstart, ystart, True)
  1219     
  1249 
  1220     def EnsureVisible(self, block):
  1250     def EnsureVisible(self, block):
  1221         xstart, ystart = self.GetViewStart()
  1251         xstart, ystart = self.GetViewStart()
  1222         window_size = self.Editor.GetClientSize()
  1252         window_size = self.Editor.GetClientSize()
  1223         block_bbx = block.GetBoundingBox()
  1253         block_bbx = block.GetBoundingBox()
  1224         
  1254 
  1225         screen_minx, screen_miny = xstart * SCROLLBAR_UNIT, ystart * SCROLLBAR_UNIT
  1255         screen_minx, screen_miny = xstart * SCROLLBAR_UNIT, ystart * SCROLLBAR_UNIT
  1226         screen_maxx, screen_maxy = screen_minx + window_size[0], screen_miny + window_size[1]
  1256         screen_maxx, screen_maxy = screen_minx + window_size[0], screen_miny + window_size[1]
  1227         block_minx = int(block_bbx.x * self.ViewScale[0]) 
  1257         block_minx = int(block_bbx.x * self.ViewScale[0])
  1228         block_miny = int(block_bbx.y * self.ViewScale[1])
  1258         block_miny = int(block_bbx.y * self.ViewScale[1])
  1229         block_maxx = int(round((block_bbx.x + block_bbx.width) * self.ViewScale[0]))
  1259         block_maxx = int(round((block_bbx.x + block_bbx.width) * self.ViewScale[0]))
  1230         block_maxy = int(round((block_bbx.y + block_bbx.height) * self.ViewScale[1]))
  1260         block_maxy = int(round((block_bbx.y + block_bbx.height) * self.ViewScale[1]))
  1231         
  1261 
  1232         xpos, ypos = xstart, ystart
  1262         xpos, ypos = xstart, ystart
  1233         if block_minx < screen_minx and block_maxx < screen_maxx:
  1263         if block_minx < screen_minx and block_maxx < screen_maxx:
  1234             xpos -= (screen_minx - block_minx) / SCROLLBAR_UNIT + 1
  1264             xpos -= (screen_minx - block_minx) / SCROLLBAR_UNIT + 1
  1235         elif block_maxx > screen_maxx and block_minx > screen_minx:
  1265         elif block_maxx > screen_maxx and block_minx > screen_minx:
  1236             xpos += (block_maxx - screen_maxx) / SCROLLBAR_UNIT + 1
  1266             xpos += (block_maxx - screen_maxx) / SCROLLBAR_UNIT + 1
  1237         if block_miny < screen_miny and block_maxy < screen_maxy:
  1267         if block_miny < screen_miny and block_maxy < screen_maxy:
  1238             ypos -= (screen_miny - block_miny) / SCROLLBAR_UNIT + 1
  1268             ypos -= (screen_miny - block_miny) / SCROLLBAR_UNIT + 1
  1239         elif block_maxy > screen_maxy and block_miny > screen_miny:
  1269         elif block_maxy > screen_maxy and block_miny > screen_miny:
  1240             ypos += (block_maxy - screen_maxy) / SCROLLBAR_UNIT + 1
  1270             ypos += (block_maxy - screen_maxy) / SCROLLBAR_UNIT + 1
  1241         self.Scroll(xpos, ypos)
  1271         self.Scroll(xpos, ypos)
  1242     
  1272 
  1243     def SelectInGroup(self, element):
  1273     def SelectInGroup(self, element):
  1244         element.SetSelected(True)
  1274         element.SetSelected(True)
  1245         if self.SelectedElement is None:
  1275         if self.SelectedElement is None:
  1246             self.SelectedElement = element
  1276             self.SelectedElement = element
  1247         elif isinstance(self.SelectedElement, Graphic_Group):
  1277         elif isinstance(self.SelectedElement, Graphic_Group):
  1249         else:
  1279         else:
  1250             group = Graphic_Group(self)
  1280             group = Graphic_Group(self)
  1251             group.AddElement(self.SelectedElement)
  1281             group.AddElement(self.SelectedElement)
  1252             group.AddElement(element)
  1282             group.AddElement(element)
  1253             self.SelectedElement = group
  1283             self.SelectedElement = group
  1254         
  1284 
  1255     # Load instance from given informations
  1285     # Load instance from given informations
  1256     def loadInstance(self, instance, remaining_instances, selection):
  1286     def loadInstance(self, instance, remaining_instances, selection):
  1257         self.current_id = max(self.current_id, instance.id)
  1287         self.current_id = max(self.current_id, instance.id)
  1258         creation_function = ElementCreationFunctions.get(instance.type, None)
  1288         creation_function = ElementCreationFunctions.get(instance.type, None)
  1259         connectors = {"inputs" : [], "outputs" : []}
  1289         connectors = {"inputs" : [], "outputs" : []}
  1293                 executionControl = True
  1323                 executionControl = True
  1294             if len(connectors["outputs"]) > 0 and connectors["outputs"][0][0] == "ENO":
  1324             if len(connectors["outputs"]) > 0 and connectors["outputs"][0][0] == "ENO":
  1295                 connectors["outputs"].pop(0)
  1325                 connectors["outputs"].pop(0)
  1296                 executionControl = True
  1326                 executionControl = True
  1297             block_name = specific_values.name if specific_values.name is not None else ""
  1327             block_name = specific_values.name if specific_values.name is not None else ""
  1298             element = FBD_Block(self, instance.type, block_name, 
  1328             element = FBD_Block(self, instance.type, block_name,
  1299                       instance.id, len(connectors["inputs"]), 
  1329                       instance.id, len(connectors["inputs"]),
  1300                       connectors=connectors, executionControl=executionControl, 
  1330                       connectors=connectors, executionControl=executionControl,
  1301                       executionOrder=specific_values.execution_order)
  1331                       executionOrder=specific_values.execution_order)
  1302         if isinstance(element, Comment):
  1332         if isinstance(element, Comment):
  1303             self.AddComment(element)
  1333             self.AddComment(element)
  1304         else:
  1334         else:
  1305             self.AddBlock(element)
  1335             self.AddBlock(element)
  1349         for link in links:
  1379         for link in links:
  1350             refLocalId = link.refLocalId
  1380             refLocalId = link.refLocalId
  1351             if refLocalId is None:
  1381             if refLocalId is None:
  1352                 links_connected = False
  1382                 links_connected = False
  1353                 continue
  1383                 continue
  1354             
  1384 
  1355             new_instance = remaining_instances.pop(refLocalId, None)
  1385             new_instance = remaining_instances.pop(refLocalId, None)
  1356             if new_instance is not None:
  1386             if new_instance is not None:
  1357                 self.loadInstance(new_instance, remaining_instances, selection)
  1387                 self.loadInstance(new_instance, remaining_instances, selection)
  1358             
  1388 
  1359             connected = self.FindElementById(refLocalId)
  1389             connected = self.FindElementById(refLocalId)
  1360             if connected is None:
  1390             if connected is None:
  1361                 links_connected = False
  1391                 links_connected = False
  1362                 continue
  1392                 continue
  1363             
  1393 
  1364             points = link.points
  1394             points = link.points
  1365             end_connector = connected.GetConnector(
  1395             end_connector = connected.GetConnector(
  1366                 wx.Point(points[-1].x, points[-1].y)
  1396                 wx.Point(points[-1].x, points[-1].y)
  1367                 if len(points) > 0 else wx.Point(0, 0), 
  1397                 if len(points) > 0 else wx.Point(0, 0),
  1368                 link.formalParameter)
  1398                 link.formalParameter)
  1369             if end_connector is not None:
  1399             if end_connector is not None:
  1370                 if len(points) > 0:
  1400                 if len(points) > 0:
  1371                     wire = Wire(self)
  1401                     wire = Wire(self)
  1372                     wire.SetPoints(points)
  1402                     wire.SetPoints(points)
  1373                 else:
  1403                 else:
  1374                     wire = Wire(self,
  1404                     wire = Wire(self,
  1375                         [wx.Point(*start_connector.GetPosition()), 
  1405                         [wx.Point(*start_connector.GetPosition()),
  1376                          start_connector.GetDirection()],
  1406                          start_connector.GetDirection()],
  1377                         [wx.Point(*end_connector.GetPosition()),
  1407                         [wx.Point(*end_connector.GetPosition()),
  1378                          end_connector.GetDirection()])
  1408                          end_connector.GetDirection()])
  1379                 start_connector.Wires.append((wire, 0))
  1409                 start_connector.Wires.append((wire, 0))
  1380                 end_connector.Wires.append((wire, -1))
  1410                 end_connector.Wires.append((wire, -1))
  1386                    selection[1].get((id, refLocalId), False) or \
  1416                    selection[1].get((id, refLocalId), False) or \
  1387                    selection[1].get((refLocalId, id), False)):
  1417                    selection[1].get((refLocalId, id), False)):
  1388                     self.SelectInGroup(wire)
  1418                     self.SelectInGroup(wire)
  1389             else:
  1419             else:
  1390                 links_connected = False
  1420                 links_connected = False
  1391         
  1421 
  1392         return links_connected
  1422         return links_connected
  1393                         
  1423 
  1394     def IsOfType(self, type, reference):
  1424     def IsOfType(self, type, reference):
  1395         return self.Controler.IsOfType(type, reference, self.Debug)
  1425         return self.Controler.IsOfType(type, reference, self.Debug)
  1396     
  1426 
  1397     def IsEndType(self, type):
  1427     def IsEndType(self, type):
  1398         return self.Controler.IsEndType(type)
  1428         return self.Controler.IsEndType(type)
  1399 
  1429 
  1400     def GetBlockType(self, type, inputs = None):
  1430     def GetBlockType(self, type, inputs = None):
  1401         return self.Controler.GetBlockType(type, inputs, self.Debug)
  1431         return self.Controler.GetBlockType(type, inputs, self.Debug)
  1409         pos = event.GetLogicalPosition(dc)
  1439         pos = event.GetLogicalPosition(dc)
  1410         for block in self.Blocks.itervalues():
  1440         for block in self.Blocks.itervalues():
  1411             if block.HitTest(pos) or block.TestHandle(event) != (0, 0):
  1441             if block.HitTest(pos) or block.TestHandle(event) != (0, 0):
  1412                 return block
  1442                 return block
  1413         return None
  1443         return None
  1414     
  1444 
  1415     def FindWire(self, event):
  1445     def FindWire(self, event):
  1416         dc = self.GetLogicalDC()
  1446         dc = self.GetLogicalDC()
  1417         pos = event.GetLogicalPosition(dc)
  1447         pos = event.GetLogicalPosition(dc)
  1418         for wire in self.Wires:
  1448         for wire in self.Wires:
  1419             if wire.HitTest(pos) or wire.TestHandle(event) != (0, 0):
  1449             if wire.HitTest(pos) or wire.TestHandle(event) != (0, 0):
  1420                 return wire
  1450                 return wire
  1421         return None
  1451         return None
  1422     
  1452 
  1423     def FindElement(self, event, exclude_group = False, connectors = True):
  1453     def FindElement(self, event, exclude_group = False, connectors = True):
  1424         dc = self.GetLogicalDC()
  1454         dc = self.GetLogicalDC()
  1425         pos = event.GetLogicalPosition(dc)
  1455         pos = event.GetLogicalPosition(dc)
  1426         if self.SelectedElement and not (exclude_group and isinstance(self.SelectedElement, Graphic_Group)):
  1456         if self.SelectedElement and not (exclude_group and isinstance(self.SelectedElement, Graphic_Group)):
  1427             if self.SelectedElement.HitTest(pos, connectors) or self.SelectedElement.TestHandle(event) != (0, 0):
  1457             if self.SelectedElement.HitTest(pos, connectors) or self.SelectedElement.TestHandle(event) != (0, 0):
  1428                 return self.SelectedElement
  1458                 return self.SelectedElement
  1429         for element in self.GetElements():
  1459         for element in self.GetElements():
  1430             if element.HitTest(pos, connectors) or element.TestHandle(event) != (0, 0):
  1460             if element.HitTest(pos, connectors) or element.TestHandle(event) != (0, 0):
  1431                 return element
  1461                 return element
  1432         return None
  1462         return None
  1433     
  1463 
  1434     def FindBlockConnector(self, pos, direction = None, exclude = None):
  1464     def FindBlockConnector(self, pos, direction = None, exclude = None):
  1435         for block in self.Blocks.itervalues():
  1465         for block in self.Blocks.itervalues():
  1436             result = block.TestConnector(pos, direction, exclude)
  1466             result = block.TestConnector(pos, direction, exclude)
  1437             if result:
  1467             if result:
  1438                 return result
  1468                 return result
  1439         return None
  1469         return None
  1440     
  1470 
  1441     def FindElementById(self, id):
  1471     def FindElementById(self, id):
  1442         block = self.Blocks.get(id, None)
  1472         block = self.Blocks.get(id, None)
  1443         if block is not None:
  1473         if block is not None:
  1444             return block
  1474             return block
  1445         comment = self.Comments.get(id, None)
  1475         comment = self.Comments.get(id, None)
  1446         if comment is not None:
  1476         if comment is not None:
  1447             return comment
  1477             return comment
  1448         return None
  1478         return None
  1449     
  1479 
  1450     def SearchElements(self, bbox):
  1480     def SearchElements(self, bbox):
  1451         elements = []
  1481         elements = []
  1452         for element in self.GetElements():
  1482         for element in self.GetElements():
  1453             if element.IsInSelection(bbox):
  1483             if element.IsInSelection(bbox):
  1454                 elements.append(element)
  1484                 elements.append(element)
  1458         if self.SelectedElement is not None:
  1488         if self.SelectedElement is not None:
  1459             self.SelectedElement.SetSelected(False)
  1489             self.SelectedElement.SetSelected(False)
  1460         self.SelectedElement = Graphic_Group(self)
  1490         self.SelectedElement = Graphic_Group(self)
  1461         self.SelectedElement.SetElements(self.GetElements())
  1491         self.SelectedElement.SetElements(self.GetElements())
  1462         self.SelectedElement.SetSelected(True)
  1492         self.SelectedElement.SetSelected(True)
  1463     
  1493 
  1464 #-------------------------------------------------------------------------------
  1494 #-------------------------------------------------------------------------------
  1465 #                           Popup menu functions
  1495 #                           Popup menu functions
  1466 #-------------------------------------------------------------------------------
  1496 #-------------------------------------------------------------------------------
  1467 
  1497 
  1468     def GetForceVariableMenuFunction(self, iec_path, element):
  1498     def GetForceVariableMenuFunction(self, iec_path, element):
  1514         else:
  1544         else:
  1515             edit = self.SelectedElement.GetType() in self.Controler.GetProjectPouNames(self.Debug)
  1545             edit = self.SelectedElement.GetType() in self.Controler.GetProjectPouNames(self.Debug)
  1516             self.AddDefaultMenuItems(menu, block=True, edit=edit)
  1546             self.AddDefaultMenuItems(menu, block=True, edit=edit)
  1517         self.Editor.PopupMenu(menu)
  1547         self.Editor.PopupMenu(menu)
  1518         menu.Destroy()
  1548         menu.Destroy()
  1519     
  1549 
  1520     def PopupVariableMenu(self):
  1550     def PopupVariableMenu(self):
  1521         menu = wx.Menu(title='')
  1551         menu = wx.Menu(title='')
  1522         variable_type = self.SelectedElement.GetType()
  1552         variable_type = self.SelectedElement.GetType()
  1523         for type_label, type in [(_("Input"), INPUT),
  1553         for type_label, type in [(_("Input"), INPUT),
  1524                                  (_("Output"), OUTPUT),
  1554                                  (_("Output"), OUTPUT),
  1530                 menu.Check(new_id, True)
  1560                 menu.Check(new_id, True)
  1531         menu.AppendSeparator()
  1561         menu.AppendSeparator()
  1532         self.AddDefaultMenuItems(menu, block=True)
  1562         self.AddDefaultMenuItems(menu, block=True)
  1533         self.Editor.PopupMenu(menu)
  1563         self.Editor.PopupMenu(menu)
  1534         menu.Destroy()
  1564         menu.Destroy()
  1535     
  1565 
  1536     def PopupConnectionMenu(self):
  1566     def PopupConnectionMenu(self):
  1537         menu = wx.Menu(title='')
  1567         menu = wx.Menu(title='')
  1538         connection_type = self.SelectedElement.GetType()
  1568         connection_type = self.SelectedElement.GetType()
  1539         for type_label, type in [(_("Connector"), CONNECTOR),
  1569         for type_label, type in [(_("Connector"), CONNECTOR),
  1540                                  (_("Continuation"), CONTINUATION)]:
  1570                                  (_("Continuation"), CONTINUATION)]:
  1545                 menu.Check(new_id, True)
  1575                 menu.Check(new_id, True)
  1546         menu.AppendSeparator()
  1576         menu.AppendSeparator()
  1547         self.AddDefaultMenuItems(menu, block=True)
  1577         self.AddDefaultMenuItems(menu, block=True)
  1548         self.Editor.PopupMenu(menu)
  1578         self.Editor.PopupMenu(menu)
  1549         menu.Destroy()
  1579         menu.Destroy()
  1550     
  1580 
  1551     def PopupWireMenu(self, delete=True):
  1581     def PopupWireMenu(self, delete=True):
  1552         menu = wx.Menu(title='')
  1582         menu = wx.Menu(title='')
  1553         
  1583 
  1554         # If Check that wire can be replace by connections or abort
  1584         # If Check that wire can be replace by connections or abort
  1555         connected = self.SelectedElement.GetConnected()
  1585         connected = self.SelectedElement.GetConnected()
  1556         start_connector = (
  1586         start_connector = (
  1557             self.SelectedElement.GetEndConnected()
  1587             self.SelectedElement.GetEndConnected()
  1558             if self.SelectedElement.GetStartConnected() in connected
  1588             if self.SelectedElement.GetStartConnected() in connected
  1559             else self.SelectedElement.GetStartConnected())
  1589             else self.SelectedElement.GetStartConnected())
  1560         
  1590 
  1561         self.AddWireMenuItems(menu, delete,
  1591         self.AddWireMenuItems(menu, delete,
  1562             start_connector.GetDirection() == EAST and 
  1592             start_connector.GetDirection() == EAST and
  1563             not isinstance(start_connector.GetParentBlock(), SFC_Step))
  1593             not isinstance(start_connector.GetParentBlock(), SFC_Step))
  1564         
  1594 
  1565         menu.AppendSeparator()
  1595         menu.AppendSeparator()
  1566         self.AddDefaultMenuItems(menu, block=True)
  1596         self.AddDefaultMenuItems(menu, block=True)
  1567         self.Editor.PopupMenu(menu)
  1597         self.Editor.PopupMenu(menu)
  1568         menu.Destroy()
  1598         menu.Destroy()
  1569         
  1599 
  1570     def PopupDivergenceMenu(self, connector):
  1600     def PopupDivergenceMenu(self, connector):
  1571         menu = wx.Menu(title='')
  1601         menu = wx.Menu(title='')
  1572         self.AddDivergenceMenuItems(menu, connector)
  1602         self.AddDivergenceMenuItems(menu, connector)
  1573         menu.AppendSeparator()
  1603         menu.AppendSeparator()
  1574         self.AddDefaultMenuItems(menu, block=True)
  1604         self.AddDefaultMenuItems(menu, block=True)
  1575         self.Editor.PopupMenu(menu)
  1605         self.Editor.PopupMenu(menu)
  1576         menu.Destroy()
  1606         menu.Destroy()
  1577     
  1607 
  1578     def PopupGroupMenu(self):
  1608     def PopupGroupMenu(self):
  1579         menu = wx.Menu(title='')
  1609         menu = wx.Menu(title='')
  1580         align_menu = wx.Menu(title='')
  1610         align_menu = wx.Menu(title='')
  1581         self.AddAlignmentMenuItems(align_menu)
  1611         self.AddAlignmentMenuItems(align_menu)
  1582         menu.AppendMenu(-1, _(u'Alignment'), align_menu)
  1612         menu.AppendMenu(-1, _(u'Alignment'), align_menu)
  1583         menu.AppendSeparator()
  1613         menu.AppendSeparator()
  1584         self.AddDefaultMenuItems(menu, block=True)
  1614         self.AddDefaultMenuItems(menu, block=True)
  1585         self.Editor.PopupMenu(menu)
  1615         self.Editor.PopupMenu(menu)
  1586         menu.Destroy()
  1616         menu.Destroy()
  1587         
  1617 
  1588     def PopupDefaultMenu(self, block=True):
  1618     def PopupDefaultMenu(self, block=True):
  1589         menu = wx.Menu(title='')
  1619         menu = wx.Menu(title='')
  1590         self.AddDefaultMenuItems(menu, block=block)
  1620         self.AddDefaultMenuItems(menu, block=block)
  1591         self.Editor.PopupMenu(menu)
  1621         self.Editor.PopupMenu(menu)
  1592         menu.Destroy()
  1622         menu.Destroy()
  1598     def OnAlignLeftMenu(self, event):
  1628     def OnAlignLeftMenu(self, event):
  1599         if self.SelectedElement is not None and isinstance(self.SelectedElement, Graphic_Group):
  1629         if self.SelectedElement is not None and isinstance(self.SelectedElement, Graphic_Group):
  1600             self.SelectedElement.AlignElements(ALIGN_LEFT, None)
  1630             self.SelectedElement.AlignElements(ALIGN_LEFT, None)
  1601             self.RefreshBuffer()
  1631             self.RefreshBuffer()
  1602             self.Editor.Refresh(False)
  1632             self.Editor.Refresh(False)
  1603     
  1633 
  1604     def OnAlignCenterMenu(self, event):
  1634     def OnAlignCenterMenu(self, event):
  1605         if self.SelectedElement is not None and isinstance(self.SelectedElement, Graphic_Group):
  1635         if self.SelectedElement is not None and isinstance(self.SelectedElement, Graphic_Group):
  1606             self.SelectedElement.AlignElements(ALIGN_CENTER, None)
  1636             self.SelectedElement.AlignElements(ALIGN_CENTER, None)
  1607             self.RefreshBuffer()
  1637             self.RefreshBuffer()
  1608             self.Editor.Refresh(False)
  1638             self.Editor.Refresh(False)
  1609     
  1639 
  1610     def OnAlignRightMenu(self, event):
  1640     def OnAlignRightMenu(self, event):
  1611         if self.SelectedElement is not None and isinstance(self.SelectedElement, Graphic_Group):
  1641         if self.SelectedElement is not None and isinstance(self.SelectedElement, Graphic_Group):
  1612             self.SelectedElement.AlignElements(ALIGN_RIGHT, None)
  1642             self.SelectedElement.AlignElements(ALIGN_RIGHT, None)
  1613             self.RefreshBuffer()
  1643             self.RefreshBuffer()
  1614             self.Editor.Refresh(False)
  1644             self.Editor.Refresh(False)
  1615     
  1645 
  1616     def OnAlignTopMenu(self, event):
  1646     def OnAlignTopMenu(self, event):
  1617         if self.SelectedElement is not None and isinstance(self.SelectedElement, Graphic_Group):
  1647         if self.SelectedElement is not None and isinstance(self.SelectedElement, Graphic_Group):
  1618             self.SelectedElement.AlignElements(None, ALIGN_TOP)
  1648             self.SelectedElement.AlignElements(None, ALIGN_TOP)
  1619             self.RefreshBuffer()
  1649             self.RefreshBuffer()
  1620             self.Editor.Refresh(False)
  1650             self.Editor.Refresh(False)
  1621     
  1651 
  1622     def OnAlignMiddleMenu(self, event):
  1652     def OnAlignMiddleMenu(self, event):
  1623         if self.SelectedElement is not None and isinstance(self.SelectedElement, Graphic_Group):
  1653         if self.SelectedElement is not None and isinstance(self.SelectedElement, Graphic_Group):
  1624             self.SelectedElement.AlignElements(None, ALIGN_MIDDLE)
  1654             self.SelectedElement.AlignElements(None, ALIGN_MIDDLE)
  1625             self.RefreshBuffer()
  1655             self.RefreshBuffer()
  1626             self.Editor.Refresh(False)
  1656             self.Editor.Refresh(False)
  1627     
  1657 
  1628     def OnAlignBottomMenu(self, event):
  1658     def OnAlignBottomMenu(self, event):
  1629         if self.SelectedElement is not None and isinstance(self.SelectedElement, Graphic_Group):
  1659         if self.SelectedElement is not None and isinstance(self.SelectedElement, Graphic_Group):
  1630             self.SelectedElement.AlignElements(None, ALIGN_BOTTOM)
  1660             self.SelectedElement.AlignElements(None, ALIGN_BOTTOM)
  1631             self.RefreshBuffer()
  1661             self.RefreshBuffer()
  1632             self.Editor.Refresh(False)
  1662             self.Editor.Refresh(False)
  1633         
  1663 
  1634     def OnNoModifierMenu(self, event):
  1664     def OnNoModifierMenu(self, event):
  1635         if self.SelectedElement is not None and self.IsBlock(self.SelectedElement):
  1665         if self.SelectedElement is not None and self.IsBlock(self.SelectedElement):
  1636             self.SelectedElement.SetConnectorNegated(False)
  1666             self.SelectedElement.SetConnectorNegated(False)
  1637             self.SelectedElement.Refresh()
  1667             self.SelectedElement.Refresh()
  1638             self.RefreshBuffer()
  1668             self.RefreshBuffer()
  1639     
  1669 
  1640     def OnNegatedMenu(self, event):
  1670     def OnNegatedMenu(self, event):
  1641         if self.SelectedElement is not None and self.IsBlock(self.SelectedElement):
  1671         if self.SelectedElement is not None and self.IsBlock(self.SelectedElement):
  1642             self.SelectedElement.SetConnectorNegated(True)
  1672             self.SelectedElement.SetConnectorNegated(True)
  1643             self.SelectedElement.Refresh()
  1673             self.SelectedElement.Refresh()
  1644             self.RefreshBuffer()
  1674             self.RefreshBuffer()
  1662 
  1692 
  1663     def OnDeleteSegmentMenu(self, event):
  1693     def OnDeleteSegmentMenu(self, event):
  1664         if self.SelectedElement is not None and self.IsWire(self.SelectedElement):
  1694         if self.SelectedElement is not None and self.IsWire(self.SelectedElement):
  1665             self.SelectedElement.DeleteSegment()
  1695             self.SelectedElement.DeleteSegment()
  1666             self.SelectedElement.Refresh()
  1696             self.SelectedElement.Refresh()
  1667     
  1697 
  1668     def OnReplaceWireMenu(self, event):
  1698     def OnReplaceWireMenu(self, event):
  1669         # Check that selected element is a wire before applying replace
  1699         # Check that selected element is a wire before applying replace
  1670         if (self.SelectedElement is not None and 
  1700         if (self.SelectedElement is not None and
  1671             self.IsWire(self.SelectedElement)):
  1701             self.IsWire(self.SelectedElement)):
  1672             
  1702 
  1673             # Get wire redraw bbox to erase it from screen
  1703             # Get wire redraw bbox to erase it from screen
  1674             wire = self.SelectedElement
  1704             wire = self.SelectedElement
  1675             redraw_rect = wire.GetRedrawRect()
  1705             redraw_rect = wire.GetRedrawRect()
  1676             
  1706 
  1677             # Get connector at both ends of wire
  1707             # Get connector at both ends of wire
  1678             connected = wire.GetConnected()
  1708             connected = wire.GetConnected()
  1679             if wire.GetStartConnected() in connected:
  1709             if wire.GetStartConnected() in connected:
  1680                 start_connector = wire.GetEndConnected()
  1710                 start_connector = wire.GetEndConnected()
  1681                 end_connector = wire.GetStartConnected()
  1711                 end_connector = wire.GetStartConnected()
  1684             else:
  1714             else:
  1685                 start_connector = wire.GetStartConnected()
  1715                 start_connector = wire.GetStartConnected()
  1686                 end_connector = wire.GetEndConnected()
  1716                 end_connector = wire.GetEndConnected()
  1687                 wire.UnConnectEndPoint()
  1717                 wire.UnConnectEndPoint()
  1688                 point_to_connect = -1
  1718                 point_to_connect = -1
  1689             
  1719 
  1690             # Get a new default connection name
  1720             # Get a new default connection name
  1691             connection_name = self.Controler.GenerateNewName(
  1721             connection_name = self.Controler.GenerateNewName(
  1692                     self.TagName, None, "Connection%d", 0)
  1722                     self.TagName, None, "Connection%d", 0)
  1693             
  1723 
  1694             # Create a connector to connect to wire
  1724             # Create a connector to connect to wire
  1695             id = self.GetNewId()
  1725             id = self.GetNewId()
  1696             connection = FBD_Connector(self, CONNECTOR, connection_name, id)
  1726             connection = FBD_Connector(self, CONNECTOR, connection_name, id)
  1697             connection.SetSize(*self.GetScaledSize(*connection.GetMinSize()))
  1727             connection.SetSize(*self.GetScaledSize(*connection.GetMinSize()))
  1698             
  1728 
  1699             # Calculate position of connector at the right of start connector 
  1729             # Calculate position of connector at the right of start connector
  1700             connector = connection.GetConnectors()["inputs"][0]
  1730             connector = connection.GetConnectors()["inputs"][0]
  1701             rel_pos = connector.GetRelPosition()
  1731             rel_pos = connector.GetRelPosition()
  1702             direction = connector.GetDirection()
  1732             direction = connector.GetDirection()
  1703             start_point = start_connector.GetPosition(False)
  1733             start_point = start_connector.GetPosition(False)
  1704             end_point = (start_point[0] + LD_WIRE_SIZE, start_point[1])
  1734             end_point = (start_point[0] + LD_WIRE_SIZE, start_point[1])
  1705             connection.SetPosition(end_point[0] - rel_pos[0], 
  1735             connection.SetPosition(end_point[0] - rel_pos[0],
  1706                                    end_point[1] - rel_pos[1])
  1736                                    end_point[1] - rel_pos[1])
  1707             
  1737 
  1708             # Connect connector to wire
  1738             # Connect connector to wire
  1709             connector.Connect((wire, point_to_connect))
  1739             connector.Connect((wire, point_to_connect))
  1710             if point_to_connect == 0:
  1740             if point_to_connect == 0:
  1711                 wire.SetPoints([end_point, start_point])
  1741                 wire.SetPoints([end_point, start_point])
  1712             else:
  1742             else:
  1713                 wire.SetPoints([start_point, end_point])
  1743                 wire.SetPoints([start_point, end_point])
  1714             # Update redraw bbox with new wire trace so that it will be redraw
  1744             # Update redraw bbox with new wire trace so that it will be redraw
  1715             # on screen
  1745             # on screen
  1716             redraw_rect.Union(wire.GetRedrawRect())
  1746             redraw_rect.Union(wire.GetRedrawRect())
  1717             
  1747 
  1718             # Add connector to Viewer and model
  1748             # Add connector to Viewer and model
  1719             self.AddBlock(connection)
  1749             self.AddBlock(connection)
  1720             self.Controler.AddEditedElementConnection(self.TagName, id, 
  1750             self.Controler.AddEditedElementConnection(self.TagName, id,
  1721                                                       CONNECTOR)
  1751                                                       CONNECTOR)
  1722             connection.RefreshModel()
  1752             connection.RefreshModel()
  1723             # Update redraw bbox with new connector bbox so that it will be
  1753             # Update redraw bbox with new connector bbox so that it will be
  1724             # drawn on screen
  1754             # drawn on screen
  1725             redraw_rect.Union(connection.GetRedrawRect())
  1755             redraw_rect.Union(connection.GetRedrawRect())
  1726             
  1756 
  1727             # Add new continuation
  1757             # Add new continuation
  1728             id = self.GetNewId()
  1758             id = self.GetNewId()
  1729             connection = FBD_Connector(self, CONTINUATION, connection_name, id)
  1759             connection = FBD_Connector(self, CONTINUATION, connection_name, id)
  1730             connection.SetSize(*self.GetScaledSize(*connection.GetMinSize()))
  1760             connection.SetSize(*self.GetScaledSize(*connection.GetMinSize()))
  1731             
  1761 
  1732             # Calculate position of connection at the left of end connector
  1762             # Calculate position of connection at the left of end connector
  1733             connector = connection.GetConnectors()["outputs"][0]
  1763             connector = connection.GetConnectors()["outputs"][0]
  1734             rel_pos = connector.GetRelPosition()
  1764             rel_pos = connector.GetRelPosition()
  1735             direction = connector.GetDirection()
  1765             direction = connector.GetDirection()
  1736             end_point = end_connector.GetPosition(False)
  1766             end_point = end_connector.GetPosition(False)
  1737             start_point = (end_point[0] - LD_WIRE_SIZE, end_point[1])
  1767             start_point = (end_point[0] - LD_WIRE_SIZE, end_point[1])
  1738             connection.SetPosition(start_point[0] - rel_pos[0], 
  1768             connection.SetPosition(start_point[0] - rel_pos[0],
  1739                                    start_point[1] - rel_pos[1])
  1769                                    start_point[1] - rel_pos[1])
  1740             
  1770 
  1741             # Add Wire to Viewer and connect it to blocks
  1771             # Add Wire to Viewer and connect it to blocks
  1742             new_wire = Wire(self, 
  1772             new_wire = Wire(self,
  1743                 [wx.Point(*start_point), connector.GetDirection()], 
  1773                 [wx.Point(*start_point), connector.GetDirection()],
  1744                 [wx.Point(*end_point), end_connector.GetDirection()])
  1774                 [wx.Point(*end_point), end_connector.GetDirection()])
  1745             self.AddWire(new_wire)
  1775             self.AddWire(new_wire)
  1746             connector.Connect((new_wire, 0), False)
  1776             connector.Connect((new_wire, 0), False)
  1747             end_connector.Connect((new_wire, -1), False)
  1777             end_connector.Connect((new_wire, -1), False)
  1748             new_wire.ConnectStartPoint(None, connector)
  1778             new_wire.ConnectStartPoint(None, connector)
  1749             new_wire.ConnectEndPoint(None, end_connector)
  1779             new_wire.ConnectEndPoint(None, end_connector)
  1750             # Update redraw bbox with new wire bbox so that it will be drawn on
  1780             # Update redraw bbox with new wire bbox so that it will be drawn on
  1751             # screen
  1781             # screen
  1752             redraw_rect.Union(new_wire.GetRedrawRect())
  1782             redraw_rect.Union(new_wire.GetRedrawRect())
  1753             
  1783 
  1754             # Add connection to Viewer and model
  1784             # Add connection to Viewer and model
  1755             self.AddBlock(connection)
  1785             self.AddBlock(connection)
  1756             self.Controler.AddEditedElementConnection(self.TagName, id, 
  1786             self.Controler.AddEditedElementConnection(self.TagName, id,
  1757                                                       CONTINUATION)
  1787                                                       CONTINUATION)
  1758             connection.RefreshModel()
  1788             connection.RefreshModel()
  1759             # Update redraw bbox with new connection bbox so that it will be
  1789             # Update redraw bbox with new connection bbox so that it will be
  1760             # drawn on screen
  1790             # drawn on screen
  1761             redraw_rect.Union(connection.GetRedrawRect())
  1791             redraw_rect.Union(connection.GetRedrawRect())
  1762             
  1792 
  1763             # Refresh model for new wire
  1793             # Refresh model for new wire
  1764             end_connector.RefreshParentBlock()
  1794             end_connector.RefreshParentBlock()
  1765             
  1795 
  1766             # Redraw 
  1796             # Redraw
  1767             self.RefreshBuffer()
  1797             self.RefreshBuffer()
  1768             self.RefreshScrollBars()
  1798             self.RefreshScrollBars()
  1769             self.RefreshVisibleElements()
  1799             self.RefreshVisibleElements()
  1770             self.RefreshRect(self.GetScrolledRect(redraw_rect), False)
  1800             self.RefreshRect(self.GetScrolledRect(redraw_rect), False)
  1771             
  1801 
  1772     def OnAddBranchMenu(self, event):
  1802     def OnAddBranchMenu(self, event):
  1773         if self.SelectedElement is not None and self.IsBlock(self.SelectedElement):
  1803         if self.SelectedElement is not None and self.IsBlock(self.SelectedElement):
  1774             self.AddDivergenceBranch(self.SelectedElement)
  1804             self.AddDivergenceBranch(self.SelectedElement)
  1775 
  1805 
  1776     def OnDeleteBranchMenu(self, event):
  1806     def OnDeleteBranchMenu(self, event):
  1797 
  1827 
  1798     def OnClearExecutionOrderMenu(self, event):
  1828     def OnClearExecutionOrderMenu(self, event):
  1799         self.Controler.ClearEditedElementExecutionOrder(self.TagName)
  1829         self.Controler.ClearEditedElementExecutionOrder(self.TagName)
  1800         self.RefreshBuffer()
  1830         self.RefreshBuffer()
  1801         self.RefreshView()
  1831         self.RefreshView()
  1802         
  1832 
  1803     def OnResetExecutionOrderMenu(self, event):
  1833     def OnResetExecutionOrderMenu(self, event):
  1804         self.Controler.ResetEditedElementExecutionOrder(self.TagName)
  1834         self.Controler.ResetEditedElementExecutionOrder(self.TagName)
  1805         self.RefreshBuffer()
  1835         self.RefreshBuffer()
  1806         self.RefreshView()
  1836         self.RefreshView()
  1807 
  1837 
  1846                 tooltip_pos = self.Editor.ClientToScreen(event.GetPosition())
  1876                 tooltip_pos = self.Editor.ClientToScreen(event.GetPosition())
  1847                 tooltip_pos.x += 10
  1877                 tooltip_pos.x += 10
  1848                 tooltip_pos.y += 10
  1878                 tooltip_pos.y += 10
  1849                 self.ToolTipElement.DisplayToolTip(tooltip_pos)
  1879                 self.ToolTipElement.DisplayToolTip(tooltip_pos)
  1850         event.Skip()
  1880         event.Skip()
  1851     
  1881 
  1852     def OnViewerLeftDown(self, event):
  1882     def OnViewerLeftDown(self, event):
  1853         self.Editor.CaptureMouse()
  1883         self.Editor.CaptureMouse()
  1854         self.StartMousePos = event.GetPosition()
  1884         self.StartMousePos = event.GetPosition()
  1855         if self.Mode == MODE_SELECTION:
  1885         if self.Mode == MODE_SELECTION:
  1856             dc = self.GetLogicalDC()
  1886             dc = self.GetLogicalDC()
  1909                         EAST: [EAST, WEST],
  1939                         EAST: [EAST, WEST],
  1910                         WEST: [WEST, EAST],
  1940                         WEST: [WEST, EAST],
  1911                         NORTH: [NORTH, SOUTH],
  1941                         NORTH: [NORTH, SOUTH],
  1912                         SOUTH: [SOUTH, NORTH]}[connector.GetDirection()]
  1942                         SOUTH: [SOUTH, NORTH]}[connector.GetDirection()]
  1913                     wire = Wire(self, *map(list, zip(
  1943                     wire = Wire(self, *map(list, zip(
  1914                                            [wx.Point(pos.x, pos.y), 
  1944                                            [wx.Point(pos.x, pos.y),
  1915                                             wx.Point(scaled_pos.x, scaled_pos.y)],
  1945                                             wx.Point(scaled_pos.x, scaled_pos.y)],
  1916                                            directions)))
  1946                                            directions)))
  1917                     wire.oldPos = scaled_pos
  1947                     wire.oldPos = scaled_pos
  1918                     wire.Handle = (HANDLE_POINT, 0)
  1948                     wire.Handle = (HANDLE_POINT, 0)
  1919                     wire.ProcessDragging(0, 0, event, None)
  1949                     wire.ProcessDragging(0, 0, event, None)
  1940                             self.SelectedElement.OnLeftDown(event, dc, self.Scaling)
  1970                             self.SelectedElement.OnLeftDown(event, dc, self.Scaling)
  1941                         self.SelectedElement.Refresh()
  1971                         self.SelectedElement.Refresh()
  1942                     else:
  1972                     else:
  1943                         self.rubberBand.Reset()
  1973                         self.rubberBand.Reset()
  1944                         self.rubberBand.OnLeftDown(event, dc, self.Scaling)
  1974                         self.rubberBand.OnLeftDown(event, dc, self.Scaling)
  1945         elif self.Mode in [MODE_BLOCK, MODE_VARIABLE, MODE_CONNECTION, MODE_COMMENT, 
  1975         elif self.Mode in [MODE_BLOCK, MODE_VARIABLE, MODE_CONNECTION, MODE_COMMENT,
  1946                            MODE_CONTACT, MODE_COIL, MODE_POWERRAIL, MODE_INITIALSTEP, 
  1976                            MODE_CONTACT, MODE_COIL, MODE_POWERRAIL, MODE_INITIALSTEP,
  1947                            MODE_STEP, MODE_TRANSITION, MODE_DIVERGENCE, MODE_JUMP, MODE_ACTION]:
  1977                            MODE_STEP, MODE_TRANSITION, MODE_DIVERGENCE, MODE_JUMP, MODE_ACTION]:
  1948             self.rubberBand.Reset()
  1978             self.rubberBand.Reset()
  1949             self.rubberBand.OnLeftDown(event, self.GetLogicalDC(), self.Scaling)
  1979             self.rubberBand.OnLeftDown(event, self.GetLogicalDC(), self.Scaling)
  1950         elif self.Mode == MODE_MOTION:
  1980         elif self.Mode == MODE_MOTION:
  1951             self.StartScreenPos = self.GetScrollPos(wx.HORIZONTAL), self.GetScrollPos(wx.VERTICAL)
  1981             self.StartScreenPos = self.GetScrollPos(wx.HORIZONTAL), self.GetScrollPos(wx.VERTICAL)
  1972                     self.SelectedElement = Graphic_Group(self)
  2002                     self.SelectedElement = Graphic_Group(self)
  1973                     self.SelectedElement.SetElements(new_elements)
  2003                     self.SelectedElement.SetElements(new_elements)
  1974                     self.SelectedElement.SetSelected(True)
  2004                     self.SelectedElement.SetSelected(True)
  1975             else:
  2005             else:
  1976                 bbox = self.rubberBand.GetCurrentExtent()
  2006                 bbox = self.rubberBand.GetCurrentExtent()
  1977                 self.rubberBand.OnLeftUp(event, self.GetLogicalDC(), self.Scaling)                
  2007                 self.rubberBand.OnLeftUp(event, self.GetLogicalDC(), self.Scaling)
  1978                 if self.Mode == MODE_BLOCK:
  2008                 if self.Mode == MODE_BLOCK:
  1979                     wx.CallAfter(self.AddNewBlock, bbox)
  2009                     wx.CallAfter(self.AddNewBlock, bbox)
  1980                 elif self.Mode == MODE_VARIABLE:
  2010                 elif self.Mode == MODE_VARIABLE:
  1981                     wx.CallAfter(self.AddNewVariable, bbox)
  2011                     wx.CallAfter(self.AddNewVariable, bbox)
  1982                 elif self.Mode == MODE_CONNECTION:
  2012                 elif self.Mode == MODE_CONNECTION:
  2018                     self.SelectedElement.HighlightPoint(pos)
  2048                     self.SelectedElement.HighlightPoint(pos)
  2019                     self.RefreshBuffer()
  2049                     self.RefreshBuffer()
  2020                 elif connector is None or self.SelectedElement.GetDragging():
  2050                 elif connector is None or self.SelectedElement.GetDragging():
  2021                     start_connector = self.SelectedElement.GetStartConnected()
  2051                     start_connector = self.SelectedElement.GetStartConnected()
  2022                     start_direction = start_connector.GetDirection()
  2052                     start_direction = start_connector.GetDirection()
  2023                     
  2053 
  2024                     items = []
  2054                     items = []
  2025                     
  2055 
  2026                     if self.CurrentLanguage == "SFC" and start_direction == SOUTH:
  2056                     if self.CurrentLanguage == "SFC" and start_direction == SOUTH:
  2027                         items.extend([
  2057                         items.extend([
  2028                             (_(u'Initial Step'), self.GetAddToWireMenuCallBack(self.AddNewStep, True)),
  2058                             (_(u'Initial Step'), self.GetAddToWireMenuCallBack(self.AddNewStep, True)),
  2029                             (_(u'Step'), self.GetAddToWireMenuCallBack(self.AddNewStep, False)),
  2059                             (_(u'Step'), self.GetAddToWireMenuCallBack(self.AddNewStep, False)),
  2030                             (_(u'Transition'), self.GetAddToWireMenuCallBack(self.AddNewTransition, False)),
  2060                             (_(u'Transition'), self.GetAddToWireMenuCallBack(self.AddNewTransition, False)),
  2031                             (_(u'Divergence'), self.GetAddToWireMenuCallBack(self.AddNewDivergence)),
  2061                             (_(u'Divergence'), self.GetAddToWireMenuCallBack(self.AddNewDivergence)),
  2032                             (_(u'Jump'), self.GetAddToWireMenuCallBack(self.AddNewJump)),
  2062                             (_(u'Jump'), self.GetAddToWireMenuCallBack(self.AddNewJump)),
  2033                         ])
  2063                         ])
  2034                     
  2064 
  2035                     elif start_direction == EAST:
  2065                     elif start_direction == EAST:
  2036                         
  2066 
  2037                         if isinstance(start_connector.GetParentBlock(), SFC_Step):
  2067                         if isinstance(start_connector.GetParentBlock(), SFC_Step):
  2038                             items.append(
  2068                             items.append(
  2039                                 (_(u'Action Block'), self.GetAddToWireMenuCallBack(self.AddNewActionBlock))
  2069                                 (_(u'Action Block'), self.GetAddToWireMenuCallBack(self.AddNewActionBlock))
  2040                             )
  2070                             )
  2041                         else:
  2071                         else:
  2042                             items.extend([
  2072                             items.extend([
  2043                                 (_(u'Block'), self.GetAddToWireMenuCallBack(self.AddNewBlock)),
  2073                                 (_(u'Block'), self.GetAddToWireMenuCallBack(self.AddNewBlock)),
  2044                                 (_(u'Variable'), self.GetAddToWireMenuCallBack(self.AddNewVariable, True)),
  2074                                 (_(u'Variable'), self.GetAddToWireMenuCallBack(self.AddNewVariable, True)),
  2045                                 (_(u'Connection'), self.GetAddToWireMenuCallBack(self.AddNewConnection)),
  2075                                 (_(u'Connection'), self.GetAddToWireMenuCallBack(self.AddNewConnection)),
  2046                             ])
  2076                             ])
  2047                             
  2077 
  2048                             if self.CurrentLanguage != "FBD":
  2078                             if self.CurrentLanguage != "FBD":
  2049                                 items.append(
  2079                                 items.append(
  2050                                     (_(u'Contact'), self.GetAddToWireMenuCallBack(self.AddNewContact))
  2080                                     (_(u'Contact'), self.GetAddToWireMenuCallBack(self.AddNewContact))
  2051                                 )
  2081                                 )
  2052                             if self.CurrentLanguage == "LD":
  2082                             if self.CurrentLanguage == "LD":
  2056                                 ])
  2086                                 ])
  2057                             if self.CurrentLanguage == "SFC":
  2087                             if self.CurrentLanguage == "SFC":
  2058                                 items.append(
  2088                                 items.append(
  2059                                     (_(u'Transition'), self.GetAddToWireMenuCallBack(self.AddNewTransition, True))
  2089                                     (_(u'Transition'), self.GetAddToWireMenuCallBack(self.AddNewTransition, True))
  2060                                 )
  2090                                 )
  2061                                 
  2091 
  2062                     if len(items) > 0:
  2092                     if len(items) > 0:
  2063                         if self.Editor.HasCapture():
  2093                         if self.Editor.HasCapture():
  2064                             self.Editor.ReleaseMouse()
  2094                             self.Editor.ReleaseMouse()
  2065                         
  2095 
  2066                         # Popup contextual menu
  2096                         # Popup contextual menu
  2067                         menu = wx.Menu()
  2097                         menu = wx.Menu()
  2068                         self.AddMenuItems(menu, 
  2098                         self.AddMenuItems(menu,
  2069                             [(wx.NewId(), wx.ITEM_NORMAL, text, '', callback)
  2099                             [(wx.NewId(), wx.ITEM_NORMAL, text, '', callback)
  2070                              for text, callback in items])
  2100                              for text, callback in items])
  2071                         self.PopupMenu(menu)
  2101                         self.PopupMenu(menu)
  2072                     
  2102 
  2073                     self.SelectedElement.StartConnected.HighlightParentBlock(False)
  2103                     self.SelectedElement.StartConnected.HighlightParentBlock(False)
  2074                     if self.DrawingWire:
  2104                     if self.DrawingWire:
  2075                         self.DrawingWire = False
  2105                         self.DrawingWire = False
  2076                         rect = self.SelectedElement.GetRedrawRect()
  2106                         rect = self.SelectedElement.GetRedrawRect()
  2077                         wire = self.SelectedElement
  2107                         wire = self.SelectedElement
  2095         if self.Mode != MODE_SELECTION and not self.SavedMode:
  2125         if self.Mode != MODE_SELECTION and not self.SavedMode:
  2096             wx.CallAfter(self.ParentWindow.ResetCurrentMode)
  2126             wx.CallAfter(self.ParentWindow.ResetCurrentMode)
  2097         if self.Editor.HasCapture():
  2127         if self.Editor.HasCapture():
  2098             self.Editor.ReleaseMouse()
  2128             self.Editor.ReleaseMouse()
  2099         event.Skip()
  2129         event.Skip()
  2100     
  2130 
  2101     def OnViewerMiddleDown(self, event):
  2131     def OnViewerMiddleDown(self, event):
  2102         self.Editor.CaptureMouse()
  2132         self.Editor.CaptureMouse()
  2103         self.StartMousePos = event.GetPosition()
  2133         self.StartMousePos = event.GetPosition()
  2104         self.StartScreenPos = self.GetScrollPos(wx.HORIZONTAL), self.GetScrollPos(wx.VERTICAL)
  2134         self.StartScreenPos = self.GetScrollPos(wx.HORIZONTAL), self.GetScrollPos(wx.VERTICAL)
  2105         event.Skip()
  2135         event.Skip()
  2106         
  2136 
  2107     def OnViewerMiddleUp(self, event):
  2137     def OnViewerMiddleUp(self, event):
  2108         self.StartMousePos = None
  2138         self.StartMousePos = None
  2109         self.StartScreenPos = None
  2139         self.StartScreenPos = None
  2110         if self.Editor.HasCapture():
  2140         if self.Editor.HasCapture():
  2111             self.Editor.ReleaseMouse()
  2141             self.Editor.ReleaseMouse()
  2112         event.Skip()
  2142         event.Skip()
  2113     
  2143 
  2114     def OnViewerRightDown(self, event):
  2144     def OnViewerRightDown(self, event):
  2115         self.Editor.CaptureMouse()
  2145         self.Editor.CaptureMouse()
  2116         if self.Mode == MODE_SELECTION:
  2146         if self.Mode == MODE_SELECTION:
  2117             element = self.FindElement(event)
  2147             element = self.FindElement(event)
  2118             if self.SelectedElement is not None and self.SelectedElement != element:
  2148             if self.SelectedElement is not None and self.SelectedElement != element:
  2124                     Graphic_Element.OnRightDown(self.SelectedElement, event, self.GetLogicalDC(), self.Scaling)
  2154                     Graphic_Element.OnRightDown(self.SelectedElement, event, self.GetLogicalDC(), self.Scaling)
  2125                 else:
  2155                 else:
  2126                     self.SelectedElement.OnRightDown(event, self.GetLogicalDC(), self.Scaling)
  2156                     self.SelectedElement.OnRightDown(event, self.GetLogicalDC(), self.Scaling)
  2127                 self.SelectedElement.Refresh()
  2157                 self.SelectedElement.Refresh()
  2128         event.Skip()
  2158         event.Skip()
  2129     
  2159 
  2130     def OnViewerRightUp(self, event):
  2160     def OnViewerRightUp(self, event):
  2131         dc = self.GetLogicalDC()
  2161         dc = self.GetLogicalDC()
  2132         self.rubberBand.Reset()
  2162         self.rubberBand.Reset()
  2133         self.rubberBand.OnLeftDown(event, dc, self.Scaling)
  2163         self.rubberBand.OnLeftDown(event, dc, self.Scaling)
  2134         self.rubberBand.OnLeftUp(event, dc, self.Scaling)
  2164         self.rubberBand.OnLeftUp(event, dc, self.Scaling)
  2141         elif not self.Debug:
  2171         elif not self.Debug:
  2142             self.PopupDefaultMenu(False)
  2172             self.PopupDefaultMenu(False)
  2143         if self.Editor.HasCapture():
  2173         if self.Editor.HasCapture():
  2144             self.Editor.ReleaseMouse()
  2174             self.Editor.ReleaseMouse()
  2145         event.Skip()
  2175         event.Skip()
  2146     
  2176 
  2147     def OnViewerLeftDClick(self, event):
  2177     def OnViewerLeftDClick(self, event):
  2148         element = self.FindElement(event)
  2178         element = self.FindElement(event)
  2149         if self.Mode == MODE_SELECTION and element is not None:
  2179         if self.Mode == MODE_SELECTION and element is not None:
  2150             if self.SelectedElement is not None and self.SelectedElement != element:
  2180             if self.SelectedElement is not None and self.SelectedElement != element:
  2151                 self.SelectedElement.SetSelected(False)
  2181                 self.SelectedElement.SetSelected(False)
  2152             if self.HighlightedElement is not None and self.HighlightedElement != element:
  2182             if self.HighlightedElement is not None and self.HighlightedElement != element:
  2153                 self.HighlightedElement.SetHighlighted(False)
  2183                 self.HighlightedElement.SetHighlighted(False)
  2154                     
  2184 
  2155             self.SelectedElement = element
  2185             self.SelectedElement = element
  2156             self.HighlightedElement = element
  2186             self.HighlightedElement = element
  2157             self.SelectedElement.SetHighlighted(True)
  2187             self.SelectedElement.SetHighlighted(True)
  2158             
  2188 
  2159             if self.Debug:
  2189             if self.Debug:
  2160                 if isinstance(self.SelectedElement, FBD_Block):
  2190                 if isinstance(self.SelectedElement, FBD_Block):
  2161                     dc = self.GetLogicalDC()
  2191                     dc = self.GetLogicalDC()
  2162                     pos = event.GetLogicalPosition(dc)
  2192                     pos = event.GetLogicalPosition(dc)
  2163                     connector = self.SelectedElement.TestConnector(pos, EAST)
  2193                     connector = self.SelectedElement.TestConnector(pos, EAST)
  2171                         pou_type = {
  2201                         pou_type = {
  2172                             "program": ITEM_PROGRAM,
  2202                             "program": ITEM_PROGRAM,
  2173                             "functionBlock": ITEM_FUNCTIONBLOCK,
  2203                             "functionBlock": ITEM_FUNCTIONBLOCK,
  2174                         }.get(self.Controler.GetPouType(instance_type))
  2204                         }.get(self.Controler.GetPouType(instance_type))
  2175                         if pou_type is not None and instance_type in self.Controler.GetProjectPouNames(self.Debug):
  2205                         if pou_type is not None and instance_type in self.Controler.GetProjectPouNames(self.Debug):
  2176                             self.ParentWindow.OpenDebugViewer(pou_type, 
  2206                             self.ParentWindow.OpenDebugViewer(pou_type,
  2177                                 "%s.%s"%(self.GetInstancePath(True), self.SelectedElement.GetName()),
  2207                                 "%s.%s"%(self.GetInstancePath(True), self.SelectedElement.GetName()),
  2178                                 self.Controler.ComputePouName(instance_type))
  2208                                 self.Controler.ComputePouName(instance_type))
  2179                 else:
  2209                 else:
  2180                     iec_path = self.GetElementIECPath(self.SelectedElement)
  2210                     iec_path = self.GetElementIECPath(self.SelectedElement)
  2181                     if iec_path is not None:
  2211                     if iec_path is not None:
  2182                         if isinstance(self.SelectedElement, Wire):
  2212                         if isinstance(self.SelectedElement, Wire):
  2183                             if self.SelectedElement.EndConnected is not None:
  2213                             if self.SelectedElement.EndConnected is not None:
  2184                                 self.ParentWindow.OpenDebugViewer(ITEM_VAR_LOCAL, iec_path, 
  2214                                 self.ParentWindow.OpenDebugViewer(ITEM_VAR_LOCAL, iec_path,
  2185                                         self.SelectedElement.EndConnected.GetType())
  2215                                         self.SelectedElement.EndConnected.GetType())
  2186                         else:
  2216                         else:
  2187                             self.ParentWindow.OpenDebugViewer(ITEM_VAR_LOCAL, iec_path, "BOOL")
  2217                             self.ParentWindow.OpenDebugViewer(ITEM_VAR_LOCAL, iec_path, "BOOL")
  2188             elif event.ControlDown() and not event.ShiftDown():
  2218             elif event.ControlDown() and not event.ShiftDown():
  2189                 if not isinstance(self.SelectedElement, Graphic_Group):
  2219                 if not isinstance(self.SelectedElement, Graphic_Group):
  2190                     if isinstance(self.SelectedElement, FBD_Block):
  2220                     if isinstance(self.SelectedElement, FBD_Block):
  2191                         instance_type = self.SelectedElement.GetType()
  2221                         instance_type = self.SelectedElement.GetType()
  2192                     else:
  2222                     else:
  2193                         instance_type = None
  2223                         instance_type = None
  2194                     if instance_type in self.Controler.GetProjectPouNames(self.Debug):
  2224                     if instance_type in self.Controler.GetProjectPouNames(self.Debug):
  2195                         self.ParentWindow.EditProjectElement(ITEM_POU, 
  2225                         self.ParentWindow.EditProjectElement(ITEM_POU,
  2196                                 self.Controler.ComputePouName(instance_type))
  2226                                 self.Controler.ComputePouName(instance_type))
  2197                     else:
  2227                     else:
  2198                         self.SelectedElement.OnLeftDClick(event, self.GetLogicalDC(), self.Scaling)
  2228                         self.SelectedElement.OnLeftDClick(event, self.GetLogicalDC(), self.Scaling)
  2199             elif event.ControlDown() and event.ShiftDown():
  2229             elif event.ControlDown() and event.ShiftDown():
  2200                 movex, movey = self.SelectedElement.SetBestSize(self.Scaling)
  2230                 movex, movey = self.SelectedElement.SetBestSize(self.Scaling)
  2202                 self.RefreshBuffer()
  2232                 self.RefreshBuffer()
  2203                 self.RefreshRect(self.GetScrolledRect(self.SelectedElement.GetRedrawRect(movex, movey)), False)
  2233                 self.RefreshRect(self.GetScrolledRect(self.SelectedElement.GetRedrawRect(movex, movey)), False)
  2204             else:
  2234             else:
  2205                 self.SelectedElement.OnLeftDClick(event, self.GetLogicalDC(), self.Scaling)
  2235                 self.SelectedElement.OnLeftDClick(event, self.GetLogicalDC(), self.Scaling)
  2206         event.Skip()
  2236         event.Skip()
  2207     
  2237 
  2208     def OnViewerMotion(self, event):
  2238     def OnViewerMotion(self, event):
  2209         if self.Editor.HasCapture() and not event.Dragging():
  2239         if self.Editor.HasCapture() and not event.Dragging():
  2210             return
  2240             return
  2211         refresh = False
  2241         refresh = False
  2212         dc = self.GetLogicalDC()
  2242         dc = self.GetLogicalDC()
  2227                 self.RefreshVisibleElements()
  2257                 self.RefreshVisibleElements()
  2228         else:
  2258         else:
  2229             if (not event.Dragging() and
  2259             if (not event.Dragging() and
  2230                 gettime() - self.LastHighlightCheckTime > REFRESH_PERIOD):
  2260                 gettime() - self.LastHighlightCheckTime > REFRESH_PERIOD):
  2231                 self.LastHighlightCheckTime = gettime()
  2261                 self.LastHighlightCheckTime = gettime()
  2232                 highlighted = self.FindElement(event, connectors=False) 
  2262                 highlighted = self.FindElement(event, connectors=False)
  2233                 if self.HighlightedElement is not None and self.HighlightedElement != highlighted:
  2263                 if self.HighlightedElement is not None and self.HighlightedElement != highlighted:
  2234                     self.HighlightedElement.SetHighlighted(False)
  2264                     self.HighlightedElement.SetHighlighted(False)
  2235                     self.HighlightedElement = None
  2265                     self.HighlightedElement = None
  2236                 if highlighted is not None:
  2266                 if highlighted is not None:
  2237                     if not self.Debug and isinstance(highlighted, (Wire, Graphic_Group)):
  2267                     if not self.Debug and isinstance(highlighted, (Wire, Graphic_Group)):
  2261                 if abs(self.StartMousePos.x - pos.x) > 5 or abs(self.StartMousePos.y - pos.y) > 5:
  2291                 if abs(self.StartMousePos.x - pos.x) > 5 or abs(self.StartMousePos.y - pos.y) > 5:
  2262                     element = self.SelectedElement
  2292                     element = self.SelectedElement
  2263                     if isinstance(self.SelectedElement, FBD_Block):
  2293                     if isinstance(self.SelectedElement, FBD_Block):
  2264                         dc = self.GetLogicalDC()
  2294                         dc = self.GetLogicalDC()
  2265                         connector = self.SelectedElement.TestConnector(
  2295                         connector = self.SelectedElement.TestConnector(
  2266                             wx.Point(dc.DeviceToLogicalX(self.StartMousePos.x), 
  2296                             wx.Point(dc.DeviceToLogicalX(self.StartMousePos.x),
  2267                                      dc.DeviceToLogicalY(self.StartMousePos.y)))
  2297                                      dc.DeviceToLogicalY(self.StartMousePos.y)))
  2268                         if connector is not None:
  2298                         if connector is not None:
  2269                             element = connector
  2299                             element = connector
  2270                     iec_path = self.GetElementIECPath(element)
  2300                     iec_path = self.GetElementIECPath(element)
  2271                     if iec_path is not None:
  2301                     if iec_path is not None:
  2352                 self.RefreshVisibleElements()
  2382                 self.RefreshVisibleElements()
  2353             elif not self.Debug and self.SelectedElement is not None:
  2383             elif not self.Debug and self.SelectedElement is not None:
  2354                 movex, movey = move
  2384                 movex, movey = move
  2355                 if not event.AltDown() or event.ShiftDown():
  2385                 if not event.AltDown() or event.ShiftDown():
  2356                     movex *= scaling[0]
  2386                     movex *= scaling[0]
  2357                     movey *= scaling[1] 
  2387                     movey *= scaling[1]
  2358                     if event.ShiftDown() and not event.AltDown():
  2388                     if event.ShiftDown() and not event.AltDown():
  2359                         movex *= 10
  2389                         movex *= 10
  2360                         movey *= 10
  2390                         movey *= 10
  2361                 self.SelectedElement.Move(movex, movey)
  2391                 self.SelectedElement.Move(movex, movey)
  2362                 self.StartBuffering()
  2392                 self.StartBuffering()
  2418     def GetScaledSize(self, width, height):
  2448     def GetScaledSize(self, width, height):
  2419         if self.Scaling is not None:
  2449         if self.Scaling is not None:
  2420             width = round(float(width) / float(self.Scaling[0]) + 0.4) * self.Scaling[0]
  2450             width = round(float(width) / float(self.Scaling[0]) + 0.4) * self.Scaling[0]
  2421             height = round(float(height) / float(self.Scaling[1]) + 0.4) * self.Scaling[1]
  2451             height = round(float(height) / float(self.Scaling[1]) + 0.4) * self.Scaling[1]
  2422         return width, height
  2452         return width, height
  2423     
  2453 
  2424     def AddNewElement(self, element, bbox, wire=None, connector=None):
  2454     def AddNewElement(self, element, bbox, wire=None, connector=None):
  2425         min_width, min_height = (element.GetMinSize(True)
  2455         min_width, min_height = (element.GetMinSize(True)
  2426                                  if isinstance(element, (LD_PowerRail,
  2456                                  if isinstance(element, (LD_PowerRail,
  2427                                                          SFC_Divergence))
  2457                                                          SFC_Divergence))
  2428                                  else element.GetMinSize())
  2458                                  else element.GetMinSize())
  2447         element.RefreshModel()
  2477         element.RefreshModel()
  2448         self.RefreshBuffer()
  2478         self.RefreshBuffer()
  2449         self.RefreshScrollBars()
  2479         self.RefreshScrollBars()
  2450         self.RefreshVisibleElements()
  2480         self.RefreshVisibleElements()
  2451         element.Refresh()
  2481         element.Refresh()
  2452     
  2482 
  2453     def AddNewBlock(self, bbox, wire=None):
  2483     def AddNewBlock(self, bbox, wire=None):
  2454         dialog = FBDBlockDialog(self.ParentWindow, self.Controler, self.TagName)
  2484         dialog = FBDBlockDialog(self.ParentWindow, self.Controler, self.TagName)
  2455         dialog.SetPreviewFont(self.GetFont())
  2485         dialog.SetPreviewFont(self.GetFont())
  2456         dialog.SetMinElementSize((bbox.width, bbox.height))
  2486         dialog.SetMinElementSize((bbox.width, bbox.height))
  2457         if dialog.ShowModal() == wx.ID_OK:
  2487         if dialog.ShowModal() == wx.ID_OK:
  2458             id = self.GetNewId()
  2488             id = self.GetNewId()
  2459             values = dialog.GetValues()
  2489             values = dialog.GetValues()
  2460             values.setdefault("name", "")
  2490             values.setdefault("name", "")
  2461             block = FBD_Block(self, values["type"], values["name"], id, 
  2491             block = FBD_Block(self, values["type"], values["name"], id,
  2462                     values["extension"], values["inputs"], 
  2492                     values["extension"], values["inputs"],
  2463                     executionControl = values["executionControl"],
  2493                     executionControl = values["executionControl"],
  2464                     executionOrder = values["executionOrder"])
  2494                     executionOrder = values["executionOrder"])
  2465             self.Controler.AddEditedElementBlock(self.TagName, id, values["type"], values.get("name", None))
  2495             self.Controler.AddEditedElementBlock(self.TagName, id, values["type"], values.get("name", None))
  2466             connector = None
  2496             connector = None
  2467             if wire is not None:
  2497             if wire is not None:
  2470                             wire.GetStartConnectedType()):
  2500                             wire.GetStartConnectedType()):
  2471                         connector = input_connector
  2501                         connector = input_connector
  2472                         break
  2502                         break
  2473             self.AddNewElement(block, bbox, wire, connector)
  2503             self.AddNewElement(block, bbox, wire, connector)
  2474         dialog.Destroy()
  2504         dialog.Destroy()
  2475     
  2505 
  2476     def AddNewVariable(self, bbox, exclude_input=False, wire=None):
  2506     def AddNewVariable(self, bbox, exclude_input=False, wire=None):
  2477         dialog = FBDVariableDialog(self.ParentWindow, self.Controler, self.TagName, exclude_input)
  2507         dialog = FBDVariableDialog(self.ParentWindow, self.Controler, self.TagName, exclude_input)
  2478         dialog.SetPreviewFont(self.GetFont())
  2508         dialog.SetPreviewFont(self.GetFont())
  2479         dialog.SetMinElementSize((bbox.width, bbox.height))
  2509         dialog.SetMinElementSize((bbox.width, bbox.height))
  2480         if dialog.ShowModal() == wx.ID_OK:
  2510         if dialog.ShowModal() == wx.ID_OK:
  2503         if values is not None:
  2533         if values is not None:
  2504             id = self.GetNewId()
  2534             id = self.GetNewId()
  2505             connection = FBD_Connector(self, values["type"], values["name"], id)
  2535             connection = FBD_Connector(self, values["type"], values["name"], id)
  2506             self.Controler.AddEditedElementConnection(self.TagName, id, values["type"])
  2536             self.Controler.AddEditedElementConnection(self.TagName, id, values["type"])
  2507             self.AddNewElement(connection, bbox, wire)
  2537             self.AddNewElement(connection, bbox, wire)
  2508     
  2538 
  2509     def AddNewComment(self, bbox):
  2539     def AddNewComment(self, bbox):
  2510         dialog = wx.TextEntryDialog(self.ParentWindow, 
  2540         dialog = wx.TextEntryDialog(self.ParentWindow,
  2511                                     _("Edit comment"), 
  2541                                     _("Edit comment"),
  2512                                     _("Please enter comment text"), 
  2542                                     _("Please enter comment text"),
  2513                                     "", wx.OK|wx.CANCEL|wx.TE_MULTILINE)
  2543                                     "", wx.OK|wx.CANCEL|wx.TE_MULTILINE)
  2514         dialog.SetClientSize(wx.Size(400, 200))
  2544         dialog.SetClientSize(wx.Size(400, 200))
  2515         if dialog.ShowModal() == wx.ID_OK:
  2545         if dialog.ShowModal() == wx.ID_OK:
  2516             value = dialog.GetValue()
  2546             value = dialog.GetValue()
  2517             id = self.GetNewId()
  2547             id = self.GetNewId()
  2590         if values is not None:
  2620         if values is not None:
  2591             id = self.GetNewId()
  2621             id = self.GetNewId()
  2592             step = SFC_Step(self, values["name"], initial, id)
  2622             step = SFC_Step(self, values["name"], initial, id)
  2593             self.Controler.AddEditedElementStep(self.TagName, id)
  2623             self.Controler.AddEditedElementStep(self.TagName, id)
  2594             for connector in ["input", "output", "action"]:
  2624             for connector in ["input", "output", "action"]:
  2595                 getattr(step, ("Add" 
  2625                 getattr(step, ("Add"
  2596                                if values[connector] 
  2626                                if values[connector]
  2597                                else "Remove") + connector.capitalize())()
  2627                                else "Remove") + connector.capitalize())()
  2598             self.AddNewElement(step, bbox, wire)
  2628             self.AddNewElement(step, bbox, wire)
  2599     
  2629 
  2600     def AddNewTransition(self, bbox, connection=False, wire=None):
  2630     def AddNewTransition(self, bbox, connection=False, wire=None):
  2601         if wire is not None and connection:
  2631         if wire is not None and connection:
  2602             values = {
  2632             values = {
  2603                 "type": "connection",
  2633                 "type": "connection",
  2604                 "value": None,
  2634                 "value": None,
  2618             if connection:
  2648             if connection:
  2619                 connector = transition.GetConditionConnector()
  2649                 connector = transition.GetConditionConnector()
  2620             else:
  2650             else:
  2621                 connector = transition.GetConnectors()["inputs"][0]
  2651                 connector = transition.GetConnectors()["inputs"][0]
  2622             self.AddNewElement(transition, bbox, wire, connector)
  2652             self.AddNewElement(transition, bbox, wire, connector)
  2623     
  2653 
  2624     def AddNewDivergence(self, bbox, wire=None):
  2654     def AddNewDivergence(self, bbox, wire=None):
  2625         dialog = SFCDivergenceDialog(self.ParentWindow, self.Controler, self.TagName)
  2655         dialog = SFCDivergenceDialog(self.ParentWindow, self.Controler, self.TagName)
  2626         dialog.SetPreviewFont(self.GetFont())
  2656         dialog.SetPreviewFont(self.GetFont())
  2627         dialog.SetMinElementSize((bbox.width, bbox.height))
  2657         dialog.SetMinElementSize((bbox.width, bbox.height))
  2628         if dialog.ShowModal() == wx.ID_OK:
  2658         if dialog.ShowModal() == wx.ID_OK:
  2636     def AddNewJump(self, bbox, wire=None):
  2666     def AddNewJump(self, bbox, wire=None):
  2637         choices = []
  2667         choices = []
  2638         for block in self.Blocks.itervalues():
  2668         for block in self.Blocks.itervalues():
  2639             if isinstance(block, SFC_Step):
  2669             if isinstance(block, SFC_Step):
  2640                 choices.append(block.GetName())
  2670                 choices.append(block.GetName())
  2641         dialog = wx.SingleChoiceDialog(self.ParentWindow, 
  2671         dialog = wx.SingleChoiceDialog(self.ParentWindow,
  2642               _("Add a new jump"), _("Please choose a target"), 
  2672               _("Add a new jump"), _("Please choose a target"),
  2643               choices, wx.DEFAULT_DIALOG_STYLE|wx.OK|wx.CANCEL)
  2673               choices, wx.DEFAULT_DIALOG_STYLE|wx.OK|wx.CANCEL)
  2644         if dialog.ShowModal() == wx.ID_OK:
  2674         if dialog.ShowModal() == wx.ID_OK:
  2645             id = self.GetNewId()
  2675             id = self.GetNewId()
  2646             jump = SFC_Jump(self, dialog.GetStringSelection(), id)
  2676             jump = SFC_Jump(self, dialog.GetStringSelection(), id)
  2647             self.Controler.AddEditedElementJump(self.TagName, id)
  2677             self.Controler.AddEditedElementJump(self.TagName, id)
  2666 
  2696 
  2667     def EditBlockContent(self, block):
  2697     def EditBlockContent(self, block):
  2668         dialog = FBDBlockDialog(self.ParentWindow, self.Controler, self.TagName)
  2698         dialog = FBDBlockDialog(self.ParentWindow, self.Controler, self.TagName)
  2669         dialog.SetPreviewFont(self.GetFont())
  2699         dialog.SetPreviewFont(self.GetFont())
  2670         dialog.SetMinElementSize(block.GetSize())
  2700         dialog.SetMinElementSize(block.GetSize())
  2671         old_values = {"name" : block.GetName(), 
  2701         old_values = {"name" : block.GetName(),
  2672                       "type" : block.GetType(), 
  2702                       "type" : block.GetType(),
  2673                       "extension" : block.GetExtension(), 
  2703                       "extension" : block.GetExtension(),
  2674                       "inputs" : block.GetInputTypes(), 
  2704                       "inputs" : block.GetInputTypes(),
  2675                       "executionControl" : block.GetExecutionControl(), 
  2705                       "executionControl" : block.GetExecutionControl(),
  2676                       "executionOrder" : block.GetExecutionOrder()}
  2706                       "executionOrder" : block.GetExecutionOrder()}
  2677         dialog.SetValues(old_values)
  2707         dialog.SetValues(old_values)
  2678         if dialog.ShowModal() == wx.ID_OK:
  2708         if dialog.ShowModal() == wx.ID_OK:
  2679             new_values = dialog.GetValues()
  2709             new_values = dialog.GetValues()
  2680             rect = block.GetRedrawRect(1, 1)
  2710             rect = block.GetRedrawRect(1, 1)
  2700 
  2730 
  2701     def EditVariableContent(self, variable):
  2731     def EditVariableContent(self, variable):
  2702         dialog = FBDVariableDialog(self.ParentWindow, self.Controler, self.TagName)
  2732         dialog = FBDVariableDialog(self.ParentWindow, self.Controler, self.TagName)
  2703         dialog.SetPreviewFont(self.GetFont())
  2733         dialog.SetPreviewFont(self.GetFont())
  2704         dialog.SetMinElementSize(variable.GetSize())
  2734         dialog.SetMinElementSize(variable.GetSize())
  2705         old_values = {"expression" : variable.GetName(), "class" : variable.GetType(), 
  2735         old_values = {"expression" : variable.GetName(), "class" : variable.GetType(),
  2706                       "executionOrder" : variable.GetExecutionOrder()}
  2736                       "executionOrder" : variable.GetExecutionOrder()}
  2707         dialog.SetValues(old_values)
  2737         dialog.SetValues(old_values)
  2708         if dialog.ShowModal() == wx.ID_OK:
  2738         if dialog.ShowModal() == wx.ID_OK:
  2709             new_values = dialog.GetValues()
  2739             new_values = dialog.GetValues()
  2710             rect = variable.GetRedrawRect(1, 1)
  2740             rect = variable.GetRedrawRect(1, 1)
  2756             else:
  2786             else:
  2757                 self.RefreshBuffer()
  2787                 self.RefreshBuffer()
  2758                 self.RefreshScrollBars()
  2788                 self.RefreshScrollBars()
  2759                 self.RefreshVisibleElements()
  2789                 self.RefreshVisibleElements()
  2760                 connection.Refresh(rect)
  2790                 connection.Refresh(rect)
  2761         
  2791 
  2762     def EditContactContent(self, contact):
  2792     def EditContactContent(self, contact):
  2763         dialog = LDElementDialog(self.ParentWindow, self.Controler, self.TagName, "contact")
  2793         dialog = LDElementDialog(self.ParentWindow, self.Controler, self.TagName, "contact")
  2764         dialog.SetPreviewFont(self.GetFont())
  2794         dialog.SetPreviewFont(self.GetFont())
  2765         dialog.SetMinElementSize(contact.GetSize())
  2795         dialog.SetMinElementSize(contact.GetSize())
  2766         dialog.SetValues({"variable" : contact.GetName(), 
  2796         dialog.SetValues({"variable" : contact.GetName(),
  2767                           "modifier" : contact.GetType()})
  2797                           "modifier" : contact.GetType()})
  2768         if dialog.ShowModal() == wx.ID_OK:
  2798         if dialog.ShowModal() == wx.ID_OK:
  2769             values = dialog.GetValues()
  2799             values = dialog.GetValues()
  2770             rect = contact.GetRedrawRect(1, 1)
  2800             rect = contact.GetRedrawRect(1, 1)
  2771             contact.SetName(values["variable"])
  2801             contact.SetName(values["variable"])
  2781 
  2811 
  2782     def EditCoilContent(self, coil):
  2812     def EditCoilContent(self, coil):
  2783         dialog = LDElementDialog(self.ParentWindow, self.Controler, self.TagName, "coil")
  2813         dialog = LDElementDialog(self.ParentWindow, self.Controler, self.TagName, "coil")
  2784         dialog.SetPreviewFont(self.GetFont())
  2814         dialog.SetPreviewFont(self.GetFont())
  2785         dialog.SetMinElementSize(coil.GetSize())
  2815         dialog.SetMinElementSize(coil.GetSize())
  2786         dialog.SetValues({"variable" : coil.GetName(), 
  2816         dialog.SetValues({"variable" : coil.GetName(),
  2787                           "modifier" : coil.GetType()})
  2817                           "modifier" : coil.GetType()})
  2788         if dialog.ShowModal() == wx.ID_OK:
  2818         if dialog.ShowModal() == wx.ID_OK:
  2789             values = dialog.GetValues()
  2819             values = dialog.GetValues()
  2790             rect = coil.GetRedrawRect(1, 1)
  2820             rect = coil.GetRedrawRect(1, 1)
  2791             coil.SetName(values["variable"])
  2821             coil.SetName(values["variable"])
  2846             if values["output"]:
  2876             if values["output"]:
  2847                 step.AddOutput()
  2877                 step.AddOutput()
  2848             else:
  2878             else:
  2849                 step.RemoveOutput()
  2879                 step.RemoveOutput()
  2850             if values["action"]:
  2880             if values["action"]:
  2851                 step.AddAction()    
  2881                 step.AddAction()
  2852             else:
  2882             else:
  2853                 step.RemoveAction()
  2883                 step.RemoveAction()
  2854             step.UpdateSize(*self.GetScaledSize(values["width"], values["height"]))
  2884             step.UpdateSize(*self.GetScaledSize(values["width"], values["height"]))
  2855             rect = rect.Union(step.GetRedrawRect())
  2885             rect = rect.Union(step.GetRedrawRect())
  2856             self.RefreshStepModel(step)
  2886             self.RefreshStepModel(step)
  2857             self.RefreshBuffer()
  2887             self.RefreshBuffer()
  2858             self.RefreshScrollBars()
  2888             self.RefreshScrollBars()
  2859             self.RefreshVisibleElements()
  2889             self.RefreshVisibleElements()
  2860             step.Refresh(rect)
  2890             step.Refresh(rect)
  2861         
  2891 
  2862     def EditTransitionContent(self, transition):
  2892     def EditTransitionContent(self, transition):
  2863         dialog = SFCTransitionDialog(self.ParentWindow, self.Controler, self.TagName, self.GetDrawingMode() == FREEDRAWING_MODE)
  2893         dialog = SFCTransitionDialog(self.ParentWindow, self.Controler, self.TagName, self.GetDrawingMode() == FREEDRAWING_MODE)
  2864         dialog.SetPreviewFont(self.GetFont())
  2894         dialog.SetPreviewFont(self.GetFont())
  2865         dialog.SetMinElementSize(transition.GetSize())
  2895         dialog.SetMinElementSize(transition.GetSize())
  2866         dialog.SetValues({"type":transition.GetType(),"value":transition.GetCondition(), "priority":transition.GetPriority()})
  2896         dialog.SetValues({"type":transition.GetType(),"value":transition.GetCondition(), "priority":transition.GetPriority()})
  2880     def EditJumpContent(self, jump):
  2910     def EditJumpContent(self, jump):
  2881         choices = []
  2911         choices = []
  2882         for block in self.Blocks.itervalues():
  2912         for block in self.Blocks.itervalues():
  2883             if isinstance(block, SFC_Step):
  2913             if isinstance(block, SFC_Step):
  2884                 choices.append(block.GetName())
  2914                 choices.append(block.GetName())
  2885         dialog = wx.SingleChoiceDialog(self.ParentWindow, 
  2915         dialog = wx.SingleChoiceDialog(self.ParentWindow,
  2886               _("Edit jump target"), _("Please choose a target"), 
  2916               _("Edit jump target"), _("Please choose a target"),
  2887               choices, wx.DEFAULT_DIALOG_STYLE|wx.OK|wx.CANCEL)
  2917               choices, wx.DEFAULT_DIALOG_STYLE|wx.OK|wx.CANCEL)
  2888         dialog.SetSelection(choices.index(jump.GetTarget()))
  2918         dialog.SetSelection(choices.index(jump.GetTarget()))
  2889         if dialog.ShowModal() == wx.ID_OK:
  2919         if dialog.ShowModal() == wx.ID_OK:
  2890             value = dialog.GetStringSelection()
  2920             value = dialog.GetStringSelection()
  2891             rect = jump.GetRedrawRect(1, 1)
  2921             rect = jump.GetRedrawRect(1, 1)
  2916             self.RefreshVisibleElements()
  2946             self.RefreshVisibleElements()
  2917             actionblock.Refresh(rect)
  2947             actionblock.Refresh(rect)
  2918         dialog.Destroy()
  2948         dialog.Destroy()
  2919 
  2949 
  2920     def EditCommentContent(self, comment):
  2950     def EditCommentContent(self, comment):
  2921         dialog = wx.TextEntryDialog(self.ParentWindow, 
  2951         dialog = wx.TextEntryDialog(self.ParentWindow,
  2922                                     _("Edit comment"), 
  2952                                     _("Edit comment"),
  2923                                     _("Please enter comment text"), 
  2953                                     _("Please enter comment text"),
  2924                                     comment.GetContent(), 
  2954                                     comment.GetContent(),
  2925                                     wx.OK|wx.CANCEL|wx.TE_MULTILINE)
  2955                                     wx.OK|wx.CANCEL|wx.TE_MULTILINE)
  2926         dialog.SetClientSize(wx.Size(400, 200))
  2956         dialog.SetClientSize(wx.Size(400, 200))
  2927         if dialog.ShowModal() == wx.ID_OK:
  2957         if dialog.ShowModal() == wx.ID_OK:
  2928             value = dialog.GetValue()
  2958             value = dialog.GetValue()
  2929             rect = comment.GetRedrawRect(1, 1)
  2959             rect = comment.GetRedrawRect(1, 1)
  2950             infos["executionOrder"] = block.GetExecutionOrder()
  2980             infos["executionOrder"] = block.GetExecutionOrder()
  2951         infos["x"], infos["y"] = block.GetPosition()
  2981         infos["x"], infos["y"] = block.GetPosition()
  2952         infos["width"], infos["height"] = block.GetSize()
  2982         infos["width"], infos["height"] = block.GetSize()
  2953         infos["connectors"] = block.GetConnectors()
  2983         infos["connectors"] = block.GetConnectors()
  2954         self.Controler.SetEditedElementBlockInfos(self.TagName, blockid, infos)
  2984         self.Controler.SetEditedElementBlockInfos(self.TagName, blockid, infos)
  2955     
  2985 
  2956     def ChangeVariableType(self, variable, new_type):
  2986     def ChangeVariableType(self, variable, new_type):
  2957         old_type = variable.GetType()
  2987         old_type = variable.GetType()
  2958         rect = variable.GetRedrawRect(1, 1)
  2988         rect = variable.GetRedrawRect(1, 1)
  2959         if old_type != new_type:
  2989         if old_type != new_type:
  2960             variable.SetType(new_type, variable.GetValueType())
  2990             variable.SetType(new_type, variable.GetValueType())
  2964             self.RefreshVariableModel(variable)
  2994             self.RefreshVariableModel(variable)
  2965             self.RefreshBuffer()
  2995             self.RefreshBuffer()
  2966             self.RefreshVisibleElements()
  2996             self.RefreshVisibleElements()
  2967             self.RefreshScrollBars()
  2997             self.RefreshScrollBars()
  2968             variable.Refresh(rect.Union(variable.GetRedrawRect()))
  2998             variable.Refresh(rect.Union(variable.GetRedrawRect()))
  2969     
  2999 
  2970     def RefreshVariableModel(self, variable):
  3000     def RefreshVariableModel(self, variable):
  2971         variableid = variable.GetId()
  3001         variableid = variable.GetId()
  2972         infos = {}
  3002         infos = {}
  2973         infos["name"] = variable.GetName()
  3003         infos["name"] = variable.GetName()
  2974         if self.CurrentLanguage == "FBD":
  3004         if self.CurrentLanguage == "FBD":
  3103         self.Controler.RemoveEditedElementInstance(self.TagName, block.GetId())
  3133         self.Controler.RemoveEditedElementInstance(self.TagName, block.GetId())
  3104         for element in elements:
  3134         for element in elements:
  3105             element.RefreshModel()
  3135             element.RefreshModel()
  3106         wx.CallAfter(self.RefreshVariablePanel)
  3136         wx.CallAfter(self.RefreshVariablePanel)
  3107         wx.CallAfter(self.ParentWindow.RefreshPouInstanceVariablesPanel)
  3137         wx.CallAfter(self.ParentWindow.RefreshPouInstanceVariablesPanel)
  3108         
  3138 
  3109     def DeleteVariable(self, variable):
  3139     def DeleteVariable(self, variable):
  3110         connectors = variable.GetConnectors()
  3140         connectors = variable.GetConnectors()
  3111         if len(connectors["outputs"]) > 0:
  3141         if len(connectors["outputs"]) > 0:
  3112             elements = connectors["outputs"][0].GetConnectedBlocks()
  3142             elements = connectors["outputs"][0].GetConnectedBlocks()
  3113         else:
  3143         else:
  3188         step.Clean()
  3218         step.Clean()
  3189         self.RemoveBlock(step)
  3219         self.RemoveBlock(step)
  3190         self.Controler.RemoveEditedElementInstance(self.TagName, step.GetId())
  3220         self.Controler.RemoveEditedElementInstance(self.TagName, step.GetId())
  3191         for element in elements:
  3221         for element in elements:
  3192             element.RefreshModel()
  3222             element.RefreshModel()
  3193             
  3223 
  3194     def DeleteTransition(self, transition):
  3224     def DeleteTransition(self, transition):
  3195         elements = []
  3225         elements = []
  3196         connectors = transition.GetConnectors()
  3226         connectors = transition.GetConnectors()
  3197         for element in connectors["outputs"][0].GetConnectedBlocks():
  3227         for element in connectors["outputs"][0].GetConnectedBlocks():
  3198             if element not in elements:
  3228             if element not in elements:
  3213         divergence.Clean()
  3243         divergence.Clean()
  3214         self.RemoveBlock(divergence)
  3244         self.RemoveBlock(divergence)
  3215         self.Controler.RemoveEditedElementInstance(self.TagName, divergence.GetId())
  3245         self.Controler.RemoveEditedElementInstance(self.TagName, divergence.GetId())
  3216         for element in elements:
  3246         for element in elements:
  3217             element.RefreshModel()
  3247             element.RefreshModel()
  3218     
  3248 
  3219     def DeleteJump(self, jump):
  3249     def DeleteJump(self, jump):
  3220         jump.Clean()
  3250         jump.Clean()
  3221         self.RemoveBlock(jump)
  3251         self.RemoveBlock(jump)
  3222         self.Controler.RemoveEditedElementInstance(self.TagName, jump.GetId())
  3252         self.Controler.RemoveEditedElementInstance(self.TagName, jump.GetId())
  3223     
  3253 
  3224     def DeleteActionBlock(self, actionblock):
  3254     def DeleteActionBlock(self, actionblock):
  3225         actionblock.Clean()
  3255         actionblock.Clean()
  3226         self.RemoveBlock(actionblock)
  3256         self.RemoveBlock(actionblock)
  3227         self.Controler.RemoveEditedElementInstance(self.TagName, actionblock.GetId())
  3257         self.Controler.RemoveEditedElementInstance(self.TagName, actionblock.GetId())
  3228 
  3258 
  3229 
  3259 
  3230 #-------------------------------------------------------------------------------
  3260 #-------------------------------------------------------------------------------
  3231 #                            Editing functions
  3261 #                            Editing functions
  3232 #-------------------------------------------------------------------------------
  3262 #-------------------------------------------------------------------------------
  3233     
  3263 
  3234     def Cut(self):
  3264     def Cut(self):
  3235         if not self.Debug and (self.IsBlock(self.SelectedElement) or self.IsComment(self.SelectedElement) or isinstance(self.SelectedElement, Graphic_Group)):
  3265         if not self.Debug and (self.IsBlock(self.SelectedElement) or self.IsComment(self.SelectedElement) or isinstance(self.SelectedElement, Graphic_Group)):
  3236             blocks, wires = self.SelectedElement.GetDefinition()
  3266             blocks, wires = self.SelectedElement.GetDefinition()
  3237             text = self.Controler.GetEditedElementInstancesCopy(self.TagName, blocks, wires, self.Debug)
  3267             text = self.Controler.GetEditedElementInstancesCopy(self.TagName, blocks, wires, self.Debug)
  3238             self.ParentWindow.SetCopyBuffer(text)
  3268             self.ParentWindow.SetCopyBuffer(text)
  3242             self.RefreshBuffer()
  3272             self.RefreshBuffer()
  3243             self.RefreshScrollBars()
  3273             self.RefreshScrollBars()
  3244             self.RefreshVariablePanel()
  3274             self.RefreshVariablePanel()
  3245             self.ParentWindow.RefreshPouInstanceVariablesPanel()
  3275             self.ParentWindow.RefreshPouInstanceVariablesPanel()
  3246             self.RefreshRect(self.GetScrolledRect(rect), False)
  3276             self.RefreshRect(self.GetScrolledRect(rect), False)
  3247         
  3277 
  3248     def Copy(self):
  3278     def Copy(self):
  3249         if not self.Debug and (self.IsBlock(self.SelectedElement) or self.IsComment(self.SelectedElement) or isinstance(self.SelectedElement, Graphic_Group)):
  3279         if not self.Debug and (self.IsBlock(self.SelectedElement) or self.IsComment(self.SelectedElement) or isinstance(self.SelectedElement, Graphic_Group)):
  3250             blocks, wires = self.SelectedElement.GetDefinition()
  3280             blocks, wires = self.SelectedElement.GetDefinition()
  3251             text = self.Controler.GetEditedElementInstancesCopy(self.TagName, blocks, wires, self.Debug)
  3281             text = self.Controler.GetEditedElementInstancesCopy(self.TagName, blocks, wires, self.Debug)
  3252             self.ParentWindow.SetCopyBuffer(text)
  3282             self.ParentWindow.SetCopyBuffer(text)
  3253             
  3283 
  3254     def Paste(self, bbx=None):
  3284     def Paste(self, bbx=None):
  3255         if not self.Debug:
  3285         if not self.Debug:
  3256             element = self.ParentWindow.GetCopyBuffer()
  3286             element = self.ParentWindow.GetCopyBuffer()
  3257             if bbx is None:
  3287             if bbx is None:
  3258                 mouse_pos = self.Editor.ScreenToClient(wx.GetMousePosition())
  3288                 mouse_pos = self.Editor.ScreenToClient(wx.GetMousePosition())
  3294             if element is not None:
  3324             if element is not None:
  3295                 blocktype = element.GetType()
  3325                 blocktype = element.GetType()
  3296             if blocktype is None:
  3326             if blocktype is None:
  3297                 blocktype = "Block"
  3327                 blocktype = "Block"
  3298             format = "%s%%d" % blocktype
  3328             format = "%s%%d" % blocktype
  3299         return self.Controler.GenerateNewName(self.TagName, 
  3329         return self.Controler.GenerateNewName(self.TagName,
  3300                                               None, 
  3330                                               None,
  3301                                               format, 
  3331                                               format,
  3302                                               exclude=exclude, 
  3332                                               exclude=exclude,
  3303                                               debug=self.Debug)
  3333                                               debug=self.Debug)
  3304 
  3334 
  3305     def IsNamedElement(self, element):
  3335     def IsNamedElement(self, element):
  3306         return isinstance(element, FBD_Block) and element.GetName() != "" or isinstance(element, SFC_Step)
  3336         return isinstance(element, FBD_Block) and element.GetName() != "" or isinstance(element, SFC_Step)
  3307 
  3337 
  3316             else:
  3346             else:
  3317                 name = None
  3347                 name = None
  3318                 block = element.Clone(self, new_id, pos=pos)
  3348                 block = element.Clone(self, new_id, pos=pos)
  3319             self.AddBlockInModel(block)
  3349             self.AddBlockInModel(block)
  3320         return block
  3350         return block
  3321     
  3351 
  3322     def AddBlockInModel(self, block):
  3352     def AddBlockInModel(self, block):
  3323         if isinstance(block, Comment):
  3353         if isinstance(block, Comment):
  3324             self.AddComment(block)
  3354             self.AddComment(block)
  3325             self.Controler.AddEditedElementComment(self.TagName, block.GetId())
  3355             self.Controler.AddEditedElementComment(self.TagName, block.GetId())
  3326             self.RefreshCommentModel(block)
  3356             self.RefreshCommentModel(block)
  3344             elif isinstance(block, LD_PowerRail):
  3374             elif isinstance(block, LD_PowerRail):
  3345                 self.Controler.AddEditedElementPowerRail(self.TagName, block.GetId(), block.GetType())
  3375                 self.Controler.AddEditedElementPowerRail(self.TagName, block.GetId(), block.GetType())
  3346                 self.RefreshPowerRailModel(block)
  3376                 self.RefreshPowerRailModel(block)
  3347             elif isinstance(block, SFC_Step):
  3377             elif isinstance(block, SFC_Step):
  3348                 self.Controler.AddEditedElementStep(self.TagName, block.GetId())
  3378                 self.Controler.AddEditedElementStep(self.TagName, block.GetId())
  3349                 self.RefreshStepModel(block)    
  3379                 self.RefreshStepModel(block)
  3350             elif isinstance(block, SFC_Transition):
  3380             elif isinstance(block, SFC_Transition):
  3351                 self.Controler.AddEditedElementTransition(self.TagName, block.GetId())
  3381                 self.Controler.AddEditedElementTransition(self.TagName, block.GetId())
  3352                 self.RefreshTransitionModel(block)       
  3382                 self.RefreshTransitionModel(block)
  3353             elif isinstance(block, SFC_Divergence):
  3383             elif isinstance(block, SFC_Divergence):
  3354                 self.Controler.AddEditedElementDivergence(self.TagName, block.GetId(), block.GetType())
  3384                 self.Controler.AddEditedElementDivergence(self.TagName, block.GetId(), block.GetType())
  3355                 self.RefreshDivergenceModel(block)
  3385                 self.RefreshDivergenceModel(block)
  3356             elif isinstance(block, SFC_Jump):
  3386             elif isinstance(block, SFC_Jump):
  3357                 self.Controler.AddEditedElementJump(self.TagName, block.GetId())
  3387                 self.Controler.AddEditedElementJump(self.TagName, block.GetId())
  3358                 self.RefreshJumpModel(block)       
  3388                 self.RefreshJumpModel(block)
  3359             elif isinstance(block, SFC_ActionBlock):
  3389             elif isinstance(block, SFC_ActionBlock):
  3360                 self.Controler.AddEditedElementActionBlock(self.TagName, block.GetId())
  3390                 self.Controler.AddEditedElementActionBlock(self.TagName, block.GetId())
  3361                 self.RefreshActionBlockModel(block)
  3391                 self.RefreshActionBlockModel(block)
  3362 
  3392 
  3363 #-------------------------------------------------------------------------------
  3393 #-------------------------------------------------------------------------------
  3365 #-------------------------------------------------------------------------------
  3395 #-------------------------------------------------------------------------------
  3366 
  3396 
  3367     def Find(self, direction, search_params):
  3397     def Find(self, direction, search_params):
  3368         if self.SearchParams != search_params:
  3398         if self.SearchParams != search_params:
  3369             self.ClearHighlights(SEARCH_RESULT_HIGHLIGHT)
  3399             self.ClearHighlights(SEARCH_RESULT_HIGHLIGHT)
  3370             
  3400 
  3371             self.SearchParams = search_params
  3401             self.SearchParams = search_params
  3372             criteria = {
  3402             criteria = {
  3373                 "raw_pattern": search_params["find_pattern"], 
  3403                 "raw_pattern": search_params["find_pattern"],
  3374                 "pattern": re.compile(search_params["find_pattern"]),
  3404                 "pattern": re.compile(search_params["find_pattern"]),
  3375                 "case_sensitive": search_params["case_sensitive"],
  3405                 "case_sensitive": search_params["case_sensitive"],
  3376                 "regular_expression": search_params["regular_expression"],
  3406                 "regular_expression": search_params["regular_expression"],
  3377                 "filter": "all"}
  3407                 "filter": "all"}
  3378             
  3408 
  3379             self.SearchResults = []
  3409             self.SearchResults = []
  3380             blocks = []
  3410             blocks = []
  3381             for infos, start, end, text in self.Controler.SearchInPou(self.TagName, criteria, self.Debug):
  3411             for infos, start, end, text in self.Controler.SearchInPou(self.TagName, criteria, self.Debug):
  3382                 if infos[1] in ["var_local", "var_input", "var_output", "var_inout"]:
  3412                 if infos[1] in ["var_local", "var_input", "var_output", "var_inout"]:
  3383                     self.SearchResults.append((infos[1:], start, end, SEARCH_RESULT_HIGHLIGHT))
  3413                     self.SearchResults.append((infos[1:], start, end, SEARCH_RESULT_HIGHLIGHT))
  3386                     if block is not None:
  3416                     if block is not None:
  3387                         blocks.append((block, (infos[1:], start, end, SEARCH_RESULT_HIGHLIGHT)))
  3417                         blocks.append((block, (infos[1:], start, end, SEARCH_RESULT_HIGHLIGHT)))
  3388             blocks.sort(sort_blocks)
  3418             blocks.sort(sort_blocks)
  3389             self.SearchResults.extend([infos for block, infos in blocks])
  3419             self.SearchResults.extend([infos for block, infos in blocks])
  3390             self.CurrentFindHighlight = None
  3420             self.CurrentFindHighlight = None
  3391         
  3421 
  3392         if len(self.SearchResults) > 0:
  3422         if len(self.SearchResults) > 0:
  3393             if self.CurrentFindHighlight is not None:
  3423             if self.CurrentFindHighlight is not None:
  3394                 old_idx = self.SearchResults.index(self.CurrentFindHighlight)
  3424                 old_idx = self.SearchResults.index(self.CurrentFindHighlight)
  3395                 if self.SearchParams["wrap"]:
  3425                 if self.SearchParams["wrap"]:
  3396                     idx = (old_idx + direction) % len(self.SearchResults)
  3426                     idx = (old_idx + direction) % len(self.SearchResults)
  3401                     self.CurrentFindHighlight = self.SearchResults[idx]
  3431                     self.CurrentFindHighlight = self.SearchResults[idx]
  3402                     self.AddHighlight(*self.CurrentFindHighlight)
  3432                     self.AddHighlight(*self.CurrentFindHighlight)
  3403             else:
  3433             else:
  3404                 self.CurrentFindHighlight = self.SearchResults[0]
  3434                 self.CurrentFindHighlight = self.SearchResults[0]
  3405                 self.AddHighlight(*self.CurrentFindHighlight)
  3435                 self.AddHighlight(*self.CurrentFindHighlight)
  3406             
  3436 
  3407         else:
  3437         else:
  3408             if self.CurrentFindHighlight is not None:
  3438             if self.CurrentFindHighlight is not None:
  3409                 self.RemoveHighlight(*self.CurrentFindHighlight)
  3439                 self.RemoveHighlight(*self.CurrentFindHighlight)
  3410             self.CurrentFindHighlight = None
  3440             self.CurrentFindHighlight = None
  3411         
  3441 
  3412 #-------------------------------------------------------------------------------
  3442 #-------------------------------------------------------------------------------
  3413 #                        Highlights showing functions
  3443 #                        Highlights showing functions
  3414 #-------------------------------------------------------------------------------
  3444 #-------------------------------------------------------------------------------
  3415 
  3445 
  3416     def OnRefreshHighlightsTimer(self, event):
  3446     def OnRefreshHighlightsTimer(self, event):
  3417         self.RefreshView()
  3447         self.RefreshView()
  3418         event.Skip()
  3448         event.Skip()
  3419 
  3449 
  3420     def ClearHighlights(self, highlight_type=None):
  3450     def ClearHighlights(self, highlight_type=None):
  3421         EditorPanel.ClearHighlights(self, highlight_type)
  3451         EditorPanel.ClearHighlights(self, highlight_type)
  3422         
  3452 
  3423         if highlight_type is None:
  3453         if highlight_type is None:
  3424             self.Highlights = []
  3454             self.Highlights = []
  3425         else:
  3455         else:
  3426             self.Highlights = [(infos, start, end, highlight) for (infos, start, end, highlight) in self.Highlights if highlight != highlight_type]
  3456             self.Highlights = [(infos, start, end, highlight) for (infos, start, end, highlight) in self.Highlights if highlight != highlight_type]
  3427         self.RefreshView()
  3457         self.RefreshView()
  3428 
  3458 
  3429     def AddHighlight(self, infos, start, end, highlight_type):
  3459     def AddHighlight(self, infos, start, end, highlight_type):
  3430         EditorPanel.AddHighlight(self, infos, start, end, highlight_type)
  3460         EditorPanel.AddHighlight(self, infos, start, end, highlight_type)
  3431         
  3461 
  3432         self.Highlights.append((infos, start, end, highlight_type))
  3462         self.Highlights.append((infos, start, end, highlight_type))
  3433         if infos[0] not in ["var_local", "var_input", "var_output", "var_inout"]:
  3463         if infos[0] not in ["var_local", "var_input", "var_output", "var_inout"]:
  3434             block = self.Blocks.get(infos[1])
  3464             block = self.Blocks.get(infos[1])
  3435             if block is not None:
  3465             if block is not None:
  3436                 self.EnsureVisible(block)
  3466                 self.EnsureVisible(block)
  3437             self.RefreshHighlightsTimer.Start(int(REFRESH_HIGHLIGHT_PERIOD * 1000), oneShot=True)
  3467             self.RefreshHighlightsTimer.Start(int(REFRESH_HIGHLIGHT_PERIOD * 1000), oneShot=True)
  3438     
  3468 
  3439     def RemoveHighlight(self, infos, start, end, highlight_type):
  3469     def RemoveHighlight(self, infos, start, end, highlight_type):
  3440         EditorPanel.RemoveHighlight(self, infos, start, end, highlight_type)
  3470         EditorPanel.RemoveHighlight(self, infos, start, end, highlight_type)
  3441         
  3471 
  3442         if (infos, start, end, highlight_type) in self.Highlights:
  3472         if (infos, start, end, highlight_type) in self.Highlights:
  3443             self.Highlights.remove((infos, start, end, highlight_type))
  3473             self.Highlights.remove((infos, start, end, highlight_type))
  3444             self.RefreshHighlightsTimer.Start(int(REFRESH_HIGHLIGHT_PERIOD * 1000), oneShot=True)
  3474             self.RefreshHighlightsTimer.Start(int(REFRESH_HIGHLIGHT_PERIOD * 1000), oneShot=True)
  3445     
  3475 
  3446     def ShowHighlights(self):
  3476     def ShowHighlights(self):
  3447         for infos, start, end, highlight_type in self.Highlights:
  3477         for infos, start, end, highlight_type in self.Highlights:
  3448             if infos[0] in ["comment", "io_variable", "block", "connector", "coil", "contact", "step", "transition", "jump", "action_block"]:
  3478             if infos[0] in ["comment", "io_variable", "block", "connector", "coil", "contact", "step", "transition", "jump", "action_block"]:
  3449                 block = self.FindElementById(infos[1])
  3479                 block = self.FindElementById(infos[1])
  3450                 if block is not None:
  3480                 if block is not None:
  3451                     block.AddHighlight(infos[2:], start, end, highlight_type)
  3481                     block.AddHighlight(infos[2:], start, end, highlight_type)
  3452         
  3482 
  3453 #-------------------------------------------------------------------------------
  3483 #-------------------------------------------------------------------------------
  3454 #                            Drawing functions
  3484 #                            Drawing functions
  3455 #-------------------------------------------------------------------------------
  3485 #-------------------------------------------------------------------------------
  3456 
  3486 
  3457     def OnScrollWindow(self, event):
  3487     def OnScrollWindow(self, event):
  3463             wx.CallAfter(self.Editor.Thaw)
  3493             wx.CallAfter(self.Editor.Thaw)
  3464         elif event.GetOrientation() == wx.HORIZONTAL:
  3494         elif event.GetOrientation() == wx.HORIZONTAL:
  3465             self.RefreshVisibleElements(xp = event.GetPosition())
  3495             self.RefreshVisibleElements(xp = event.GetPosition())
  3466         else:
  3496         else:
  3467             self.RefreshVisibleElements(yp = event.GetPosition())
  3497             self.RefreshVisibleElements(yp = event.GetPosition())
  3468         
  3498 
  3469         # Handle scroll in debug to fully redraw area and ensuring
  3499         # Handle scroll in debug to fully redraw area and ensuring
  3470         # instance path is fully draw without flickering
  3500         # instance path is fully draw without flickering
  3471         if self.Debug and wx.Platform != '__WXMSW__':
  3501         if self.Debug and wx.Platform != '__WXMSW__':
  3472             x, y = self.GetViewStart()
  3502             x, y = self.GetViewStart()
  3473             if event.GetOrientation() == wx.HORIZONTAL:
  3503             if event.GetOrientation() == wx.HORIZONTAL:
  3496             else:
  3526             else:
  3497                 x, y = self.GetViewStart()
  3527                 x, y = self.GetViewStart()
  3498                 yp = max(0, min(y - rotation * 3, self.Editor.GetVirtualSize()[1] / self.Editor.GetScrollPixelsPerUnit()[1]))
  3528                 yp = max(0, min(y - rotation * 3, self.Editor.GetVirtualSize()[1] / self.Editor.GetScrollPixelsPerUnit()[1]))
  3499                 self.RefreshVisibleElements(yp = yp)
  3529                 self.RefreshVisibleElements(yp = yp)
  3500                 self.Scroll(x, yp)
  3530                 self.Scroll(x, yp)
  3501             
  3531 
  3502     def OnMoveWindow(self, event):
  3532     def OnMoveWindow(self, event):
  3503         client_size = self.GetClientSize()
  3533         client_size = self.GetClientSize()
  3504         if self.LastClientSize != client_size:
  3534         if self.LastClientSize != client_size:
  3505             self.LastClientSize = client_size
  3535             self.LastClientSize = client_size
  3506             self.RefreshScrollBars()
  3536             self.RefreshScrollBars()
  3530         if self.PageSize is not None and not printing:
  3560         if self.PageSize is not None and not printing:
  3531             dc.SetPen(self.PagePen)
  3561             dc.SetPen(self.PagePen)
  3532             xstart, ystart = self.GetViewStart()
  3562             xstart, ystart = self.GetViewStart()
  3533             window_size = self.Editor.GetClientSize()
  3563             window_size = self.Editor.GetClientSize()
  3534             for x in xrange(self.PageSize[0] - (xstart * SCROLLBAR_UNIT) % self.PageSize[0], int(window_size[0] / self.ViewScale[0]), self.PageSize[0]):
  3564             for x in xrange(self.PageSize[0] - (xstart * SCROLLBAR_UNIT) % self.PageSize[0], int(window_size[0] / self.ViewScale[0]), self.PageSize[0]):
  3535                 dc.DrawLine(xstart * SCROLLBAR_UNIT + x + 1, int(ystart * SCROLLBAR_UNIT / self.ViewScale[0]), 
  3565                 dc.DrawLine(xstart * SCROLLBAR_UNIT + x + 1, int(ystart * SCROLLBAR_UNIT / self.ViewScale[0]),
  3536                             xstart * SCROLLBAR_UNIT + x + 1, int((ystart * SCROLLBAR_UNIT + window_size[1]) / self.ViewScale[0]))
  3566                             xstart * SCROLLBAR_UNIT + x + 1, int((ystart * SCROLLBAR_UNIT + window_size[1]) / self.ViewScale[0]))
  3537             for y in xrange(self.PageSize[1] - (ystart * SCROLLBAR_UNIT) % self.PageSize[1], int(window_size[1] / self.ViewScale[1]), self.PageSize[1]):
  3567             for y in xrange(self.PageSize[1] - (ystart * SCROLLBAR_UNIT) % self.PageSize[1], int(window_size[1] / self.ViewScale[1]), self.PageSize[1]):
  3538                 dc.DrawLine(int(xstart * SCROLLBAR_UNIT / self.ViewScale[0]), ystart * SCROLLBAR_UNIT + y + 1, 
  3568                 dc.DrawLine(int(xstart * SCROLLBAR_UNIT / self.ViewScale[0]), ystart * SCROLLBAR_UNIT + y + 1,
  3539                             int((xstart * SCROLLBAR_UNIT + window_size[0]) / self.ViewScale[1]), ystart * SCROLLBAR_UNIT + y + 1)
  3569                             int((xstart * SCROLLBAR_UNIT + window_size[0]) / self.ViewScale[1]), ystart * SCROLLBAR_UNIT + y + 1)
  3540         
  3570 
  3541         # Draw all elements
  3571         # Draw all elements
  3542         for comment in self.Comments.itervalues():
  3572         for comment in self.Comments.itervalues():
  3543             if comment != self.SelectedElement and (comment.IsVisible() or printing):
  3573             if comment != self.SelectedElement and (comment.IsVisible() or printing):
  3544                 comment.Draw(dc)
  3574                 comment.Draw(dc)
  3545         for wire in self.Wires.iterkeys():
  3575         for wire in self.Wires.iterkeys():
  3551                 if wire != self.SelectedElement and (wire.IsVisible() or printing) and wire.GetValue() == True:
  3581                 if wire != self.SelectedElement and (wire.IsVisible() or printing) and wire.GetValue() == True:
  3552                     wire.Draw(dc)
  3582                     wire.Draw(dc)
  3553         for block in self.Blocks.itervalues():
  3583         for block in self.Blocks.itervalues():
  3554             if block != self.SelectedElement and (block.IsVisible() or printing):
  3584             if block != self.SelectedElement and (block.IsVisible() or printing):
  3555                 block.Draw(dc)
  3585                 block.Draw(dc)
  3556         
  3586 
  3557         if self.SelectedElement is not None and (self.SelectedElement.IsVisible() or printing):
  3587         if self.SelectedElement is not None and (self.SelectedElement.IsVisible() or printing):
  3558             self.SelectedElement.Draw(dc)
  3588             self.SelectedElement.Draw(dc)
  3559         
  3589 
  3560         if not printing:
  3590         if not printing:
  3561             if self.Debug:
  3591             if self.Debug:
  3562                 scalex, scaley = dc.GetUserScale()
  3592                 scalex, scaley = dc.GetUserScale()
  3563                 dc.SetUserScale(1, 1)
  3593                 dc.SetUserScale(1, 1)
  3564                 
  3594 
  3565                 is_action = self.TagName.split("::")[0] == "A"
  3595                 is_action = self.TagName.split("::")[0] == "A"
  3566                 text = _("Debug: %s") % self.InstancePath
  3596                 text = _("Debug: %s") % self.InstancePath
  3567                 if is_action and self.Value is not None:
  3597                 if is_action and self.Value is not None:
  3568                     text += " ("
  3598                     text += " ("
  3569                 text_offset_x, text_offset_y = self.CalcUnscrolledPosition(2, 2)
  3599                 text_offset_x, text_offset_y = self.CalcUnscrolledPosition(2, 2)
  3576                     dc.DrawText(value_text, text_offset_x + tw, text_offset_y)
  3606                     dc.DrawText(value_text, text_offset_x + tw, text_offset_y)
  3577                     if self.Value:
  3607                     if self.Value:
  3578                         dc.SetTextForeground(wx.BLACK)
  3608                         dc.SetTextForeground(wx.BLACK)
  3579                     vw, vh = dc.GetTextExtent(value_text)
  3609                     vw, vh = dc.GetTextExtent(value_text)
  3580                     dc.DrawText(")", text_offset_x + tw + vw + 2, text_offset_y)
  3610                     dc.DrawText(")", text_offset_x + tw + vw + 2, text_offset_y)
  3581                 
  3611 
  3582                 dc.SetUserScale(scalex, scaley)
  3612                 dc.SetUserScale(scalex, scaley)
  3583                 
  3613 
  3584             if self.rubberBand.IsShown():
  3614             if self.rubberBand.IsShown():
  3585                 self.rubberBand.Draw(dc)
  3615                 self.rubberBand.Draw(dc)
  3586             dc.EndDrawing()
  3616             dc.EndDrawing()
  3587 
  3617 
  3588     def OnPaint(self, event):
  3618     def OnPaint(self, event):