# HG changeset patch # User lbessard # Date 1170952901 -3600 # Node ID 86ccc89d7b0ba3e992eab88bc3f437a3475d71fb # Parent 93bc4c2cf376523a5826e1ed402c439d3e29996d FBD Blocks and Variables can now be modified and wires can't be unconnected on both sides diff -r 93bc4c2cf376 -r 86ccc89d7b0b FBDViewer.py --- a/FBDViewer.py Wed Feb 07 18:43:32 2007 +0100 +++ b/FBDViewer.py Thu Feb 08 17:41:41 2007 +0100 @@ -77,16 +77,24 @@ self.rubberBand.OnLeftDown(event, self.Scaling) elif self.Mode == MODE_WIRE: pos = GetScaledEventPosition(event, self.Scaling) - wire = Wire(self, [wxPoint(pos.x, pos.y), EAST], [wxPoint(pos.x, pos.y), WEST]) - wire.oldPos = pos - wire.Handle = (HANDLE_POINT, 0) - wire.ProcessDragging(0, 0) - wire.Handle = (HANDLE_POINT, 1) - self.Wires.append(wire) - self.Elements.append(wire) - if self.SelectedElement: + connector = self.FindBlockConnector(pos) + if connector: + if (connector.GetDirection() == EAST): + wire = Wire(self, [wxPoint(pos.x, pos.y), EAST], [wxPoint(pos.x, pos.y), WEST]) + else: + wire = Wire(self, [wxPoint(pos.x, pos.y), WEST], [wxPoint(pos.x, pos.y), EAST]) + wire.oldPos = pos + wire.Handle = (HANDLE_POINT, 0) + wire.ProcessDragging(0, 0) + wire.Handle = (HANDLE_POINT, 1) + self.Wires.append(wire) + self.Elements.append(wire) + if self.SelectedElement: + self.SelectedElement.SetSelected(False) + self.SelectedElement = wire + elif self.SelectedElement: self.SelectedElement.SetSelected(False) - self.SelectedElement = wire + self.SelectedElement = None self.Refresh() event.Skip() @@ -122,12 +130,20 @@ self.ReleaseMouse() self.Refresh() elif self.Mode == MODE_WIRE and self.SelectedElement: - self.SelectedElement.ResetPoints() - self.SelectedElement.OnMotion(event, self.Scaling) - self.SelectedElement.GeneratePoints() - self.SelectedElement.RefreshModel() - self.SelectedElement.SetSelected(True) - self.Refresh() + pos = GetScaledEventPosition(event, self.Scaling) + connector = self.FindBlockConnector(pos, False) + if connector and connector != self.SelectedElement.StartConnected: + self.SelectedElement.ResetPoints() + self.SelectedElement.OnMotion(event, self.Scaling) + self.SelectedElement.GeneratePoints() + self.SelectedElement.RefreshModel() + self.SelectedElement.SetSelected(True) + else: + self.SelectedElement.Delete() + self.SelectedElement = None + self.Refresh() + if not self.SavedMode: + wxCallAfter(self.Parent.ResetCurrentMode) event.Skip() def OnViewerRightUp(self, event): @@ -157,10 +173,13 @@ self.SelectedElement.OnMotion(event, self.Scaling) self.Refresh() elif self.Mode == MODE_WIRE and self.SelectedElement: - self.SelectedElement.ResetPoints() - self.SelectedElement.OnMotion(event, self.Scaling) - self.SelectedElement.GeneratePoints() - self.Refresh() + pos = GetScaledEventPosition(event, self.Scaling) + connector = self.FindBlockConnector(pos, False) + if not connector or self.SelectedElement.EndConnected == None: + self.SelectedElement.ResetPoints() + self.SelectedElement.OnMotion(event, self.Scaling) + self.SelectedElement.GeneratePoints() + self.Refresh() event.Skip() #------------------------------------------------------------------------------- @@ -209,7 +228,6 @@ self.Elements.append(block) self.Controler.AddCurrentElementEditingBlock(id) self.RefreshBlockModel(block) - self.Parent.RefreshProjectTree() self.Refresh() dialog.Destroy() @@ -235,7 +253,6 @@ self.Elements.append(variable) self.Controler.AddCurrentElementEditingVariable(id, values["type"]) self.RefreshVariableModel(variable) - self.Parent.RefreshProjectTree() self.Refresh() dialog.Destroy() @@ -252,7 +269,6 @@ self.Elements.append(connection) self.Controler.AddCurrentElementEditingConnection(id, values["type"]) self.RefreshConnectionModel(connection) - self.Parent.RefreshProjectTree() self.Refresh() dialog.Destroy() @@ -285,11 +301,10 @@ self.Controler.RemoveCurrentElementEditingInstance(block.GetId()) for wire in wires: wire.RefreshModel() - self.Parent.RefreshProjectTree() def DeleteVariable(self, variable): wires = [] - if self.SelectedElement.GetType() == INPUT: + if variable.GetType() == INPUT: connector = variable.GetConnector() wires.extend([wire[0] for wire in connector.GetWires()]) variable.Clean() @@ -298,11 +313,10 @@ self.Controler.RemoveCurrentElementEditingInstance(variable.GetId()) for wire in wires: wire.RefreshModel() - self.Parent.RefreshProjectTree() def DeleteConnection(self, connection): wires = [] - if self.SelectedElement.GetType() == CONTINUATION: + if connection.GetType() == CONTINUATION: connector = connection.GetConnector() wires.extend([wire[0] for wire in connector.GetWires()]) connection.Clean() @@ -311,7 +325,6 @@ self.Controler.RemoveCurrentElementEditingInstance(connection.GetId()) for wire in wires: wire.RefreshModel() - self.Parent.RefreshProjectTree() def DeleteComment(self, comment): self.Elements.remove(comment) @@ -319,7 +332,7 @@ def DeleteWire(self, wire): connected = wire.GetConnected() - self.SelectedElement.Clean() + wire.Clean() self.Wires.remove(wire) self.Elements.remove(wire) for connector in connected: @@ -343,6 +356,35 @@ block.SetExtension(values["extension"]) block.SetSize(values["width"], values["height"]) block.SetType(values["type"]) + self.RefreshBlockModel(block) + self.Refresh() + dialog.Destroy() + + def EditVariableContent(self, variable): + dialog = VariablePropertiesDialog(self.Parent) + dialog.SetMinVariableSize(variable.GetSize()) + varlist = [] + vars = self.Controler.GetCurrentElementEditingInterfaceVars() + if vars: + for var in vars: + varlist.append((var["Name"], var["Class"], var["Type"])) + returntype = self.Controler.GetCurrentElementEditingInterfaceReturnType() + if returntype: + varlist.append((self.Controler.GetCurrentElementEditingName(), "Output", returntype)) + dialog.SetVariables(varlist) + values = {"name" : variable.GetName(), "type" : variable.GetType()} + dialog.SetValues(values) + if dialog.ShowModal() == wxID_OK: + old_type = variable.GetType() + values = dialog.GetValues() + variable.SetName(values["name"]) + variable.SetType(values["type"], values["value_type"]) + variable.SetSize(values["width"], values["height"]) + if old_type != values["type"]: + id = variable.GetId() + self.Controler.RemoveCurrentElementEditingInstance(id) + self.Controler.AddCurrentElementEditingVariable(id, values["type"]) + self.RefreshVariableModel(variable) self.Refresh() dialog.Destroy() @@ -659,6 +701,19 @@ def SetVariables(self, vars): self.VarList = vars self.RefreshNameList() + + def SetValues(self, values): + for name, value in values.items(): + if name == "type": + if value == INPUT: + self.Class.SetStringSelection("Input") + if value == OUTPUT: + self.Class.SetStringSelection("Output") + if value == INOUT: + self.Class.SetStringSelection("InOut") + elif name == "name": + self.Name.SetStringSelection(value) + self.RefreshPreview() def GetValues(self): values = {} diff -r 93bc4c2cf376 -r 86ccc89d7b0b PLCOpenEditor.py --- a/PLCOpenEditor.py Wed Feb 07 18:43:32 2007 +0100 +++ b/PLCOpenEditor.py Thu Feb 08 17:41:41 2007 +0100 @@ -441,23 +441,21 @@ self.Bind(wx.EVT_TOOL, self.OnLDBranchTool, id=wxID_PLCOPENEDITORLDTOOLBARITEMS4) - def init_toolbars(self, parent): + def init_toolbars(self): self.DefaultToolBar = wxToolBar(id=wxID_PLCOPENEDITORDEFAULTTOOLBAR, name='DefaultToolBar', - parent=parent, pos=wx.Point(0, 27), size=wx.Size(0, 0), + parent=self, pos=wx.Point(0, 27), size=wx.Size(0, 0), style=wxTB_HORIZONTAL | wxNO_BORDER) - self.Bind(wx.EVT_LEFT_DCLICK, self.OnDefaultToolDCLick, - id=wxID_PLCOPENEDITORDEFAULTTOOLBAR) self.SFCToolBar = wxToolBar(id=wxID_PLCOPENEDITORSFCTOOLBAR, name='SFCToolBar', - parent=parent, pos=wx.Point(0, 27), size=wx.Size(0, 0), + parent=self, pos=wx.Point(0, 27), size=wx.Size(0, 0), style=wxTB_HORIZONTAL | wxNO_BORDER) self.FBDToolBar = wxToolBar(id=wxID_PLCOPENEDITORFBDTOOLBAR, name='FBDToolBar', - parent=parent, pos=wx.Point(0, 27), size=wx.Size(0, 0), + parent=self, pos=wx.Point(0, 27), size=wx.Size(0, 0), style=wxTB_HORIZONTAL | wxNO_BORDER) self.LDToolBar = wxToolBar(id=wxID_PLCOPENEDITORLDTOOLBAR, name='LDToolBar', - parent=parent, pos=wx.Point(0, 27), size=wx.Size(0, 0), + parent=self, pos=wx.Point(0, 27), size=wx.Size(0, 0), style=wxTB_HORIZONTAL | wxNO_BORDER) self.init_coll_DefaultToolBar_Items(self.DefaultToolBar) @@ -467,22 +465,18 @@ def __init__(self, parent): self._init_ctrls(parent) - self.init_toolbars(self) + self.init_toolbars() self.Controler = PLCControler() if fileOpen: self.Controler.OpenXMLFile(fileOpen) self.RefreshProjectTree() - + self.RefreshFileMenu() self.RefreshEditMenu() self.RefreshToolBar() - def OnDefaultToolDCLick(self, event): - print "Default ToolBar DClick" - event.Skip() - def RefreshFileMenu(self): if self.Controler.HasOpenedProject(): if self.TabsOpened.GetPageCount() > 0: @@ -621,6 +615,20 @@ self.Close() event.Skip() + def ResetCurrentMode(self): + selected = self.TabsOpened.GetSelection() + if selected != -1: + self.TabsOpened.GetPage(selected).SetMode(MODE_SELECTION) + language = self.Controler.GetCurrentElementEditingBodyType() + if language == "SFC": + self.SFCToolBar.ToggleTool(wxID_PLCOPENEDITORSFCTOOLBARITEMS0, True) + elif language == "FBD": + self.FBDToolBar.ToggleTool(wxID_PLCOPENEDITORFBDTOOLBARITEMS0, True) + elif language == "LD": + self.LDToolBar.ToggleTool(wxID_PLCOPENEDITORLDTOOLBARITEMS0, True) + else: + self.DefaultToolBar.ToggleTool(wxID_PLCOPENEDITORDEFAULTTOOLBARITEMS0, True) + def OnSelectionTool(self, event): selected = self.TabsOpened.GetSelection() if selected != -1: @@ -1005,33 +1013,30 @@ def RefreshToolBar(self): language = self.Controler.GetCurrentElementEditingBodyType() if language == "SFC": - self.SFCToolBar.ToggleTool(0, True) self.SFCToolBar.Show() self.SetToolBar(self.SFCToolBar) self.DefaultToolBar.Hide() self.FBDToolBar.Hide() self.LDToolBar.Hide() elif language == "FBD": - self.FBDToolBar.ToggleTool(0, True) self.FBDToolBar.Show() self.SetToolBar(self.FBDToolBar) self.DefaultToolBar.Hide() self.SFCToolBar.Hide() self.LDToolBar.Hide() elif language == "LD": - self.LDToolBar.ToggleTool(0, True) self.LDToolBar.Show() self.SetToolBar(self.LDToolBar) self.DefaultToolBar.Hide() self.SFCToolBar.Hide() self.FBDToolBar.Hide() else: - self.DefaultToolBar.ToggleTool(0, True) self.DefaultToolBar.Show() self.SetToolBar(self.DefaultToolBar) self.SFCToolBar.Hide() self.FBDToolBar.Hide() self.LDToolBar.Hide() + self.ResetCurrentMode() def RefreshTabsOpenedTitles(self): pous = self.Controler.GetElementsOpenedNames() diff -r 93bc4c2cf376 -r 86ccc89d7b0b Viewer.py --- a/Viewer.py Wed Feb 07 18:43:32 2007 +0100 +++ b/Viewer.py Thu Feb 08 17:41:41 2007 +0100 @@ -120,6 +120,7 @@ # Initialize Viewer mode to Selection mode self.Mode = MODE_SELECTION + self.SavedMode = False self.Parent = window self.Controler = controler @@ -155,9 +156,13 @@ # Changes Viewer mode def SetMode(self, mode): - self.Mode = mode + if self.Mode != mode or mode == MODE_SELECTION: + self.Mode = mode + self.SavedMode = False + else: + self.SavedMode = True # Reset selection - if self.SelectedElement: + if self.Mode != MODE_SELECTION and self.SelectedElement: self.SelectedElement.SetSelected(False) self.SelectedElement = None self.Refresh() @@ -463,9 +468,9 @@ return element return None - def FindBlockConnector(self, pos): + def FindBlockConnector(self, pos, exclude = True): for block in self.Blocks: - result = block.TestConnector(pos) + result = block.TestConnector(pos, exclude) if result: return result return None diff -r 93bc4c2cf376 -r 86ccc89d7b0b graphics/FBD_Objects.py --- a/graphics/FBD_Objects.py Wed Feb 07 18:43:32 2007 +0100 +++ b/graphics/FBD_Objects.py Thu Feb 08 17:41:41 2007 +0100 @@ -42,6 +42,7 @@ # Create a new block def __init__(self, parent, type, name, id = None, extension = 0, inputs = [], outputs = []): Graphic_Element.__init__(self, parent) + self.Type = None self.Name = name self.Id = id self.Extension = extension @@ -124,7 +125,7 @@ return {"inputs" : self.Inputs, "outputs" : self.Outputs} # Test if point given is on one of the block connectors - def TestConnector(self, pt, exclude=True): + def TestConnector(self, pt, exclude = True): # Test each input connector for input in self.Inputs: if input.TestPoint(pt, exclude): @@ -137,19 +138,40 @@ # Changes the block type def SetType(self, type): - self.Type = type - # Find the block definition from type given and create the corresponding - # inputs and outputs - blocktype = GetBlockType(type) - if blocktype: - inputs = [input for input in blocktype["inputs"]] - outputs = [output for output in blocktype["outputs"]] - if blocktype["extensible"]: - start = int(inputs[-1][0].replace("IN", "")) - for i in xrange(self.Extension - len(blocktype["inputs"])): - start += 1 - inputs.append(("IN%d"%start, inputs[-1][1], input[-1][2])) - self.SetConnectors(inputs, outputs) + if type != self.Type: + self.Type = type + # Find the block definition from type given and create the corresponding + # inputs and outputs + blocktype = GetBlockType(type) + if blocktype: + inputs = [input for input in blocktype["inputs"]] + outputs = [output for output in blocktype["outputs"]] + if blocktype["extensible"]: + start = int(inputs[-1][0].replace("IN", "")) + for i in xrange(self.Extension - len(blocktype["inputs"])): + start += 1 + inputs.append(("IN%d"%start, inputs[-1][1], input[-1][2])) + self.Clean() + # Extract the inputs properties and create the corresponding connector + self.Inputs = [] + for input_name, input_type, input_modifier in inputs: + connector = Connector(self, input_name, input_type, wxPoint(0, 0), WEST) + if input_modifier == "negated": + connector.SetNegated(True) + elif input_modifier != "none": + connector.SetEdge(input_modifier) + self.Inputs.append(connector) + # Extract the outputs properties and create the corresponding connector + self.Outputs = [] + for output_name, output_type, output_modifier in outputs: + connector = Connector(self, output_name, output_type, wxPoint(0, 0), EAST) + if output_modifier == "negated": + connector.SetNegated(True) + elif output_modifier != "none": + connector.SetEdge(output_modifier) + self.Outputs.append(connector) + self.RefreshConnectors() + self.RefreshBoundingBox() # Returns the block type def GetType(self): @@ -189,30 +211,6 @@ height = (max(len(self.Inputs), len(self.Outputs)) + 1) * BLOCK_LINE_SIZE return width, height - # Changes the block connectors - def SetConnectors(self, inputs, outputs): - self.Clean() - # Extract the inputs properties and create the corresponding connector - self.Inputs = [] - for input_name, input_type, input_modifier in inputs: - connector = Connector(self, input_name, input_type, wxPoint(0, 0), WEST) - if input_modifier == "negated": - connector.SetNegated(True) - elif input_modifier != "none": - connector.SetEdge(input_modifier) - self.Inputs.append(connector) - # Extract the outputs properties and create the corresponding connector - self.Outputs = [] - for output_name, output_type, output_modifier in outputs: - connector = Connector(self, output_name, output_type, wxPoint(0, 0), EAST) - if output_modifier == "negated": - connector.SetNegated(True) - elif output_modifier != "none": - connector.SetEdge(output_modifier) - self.Outputs.append(connector) - self.RefreshConnectors() - self.RefreshBoundingBox() - # Changes the negated property of the connector handled def SetConnectorNegated(self, negated): handle_type, handle = self.Handle @@ -229,7 +227,7 @@ # Method called when a LeftDClick event have been generated def OnLeftDClick(self, event, scaling): - # Edit the step properties + # Edit the block properties self.Parent.EditBlockContent(self) # Method called when a RightUp event have been generated @@ -285,17 +283,13 @@ # Create a new variable def __init__(self, parent, type, name, value_type, id = None): Graphic_Element.__init__(self, parent) - self.Type = type + self.Type = None + self.ValueType = None self.Name = name self.Id = id self.Input = None self.Output = None - # Create an input or output connector according to variable type - if self.Type != INPUT: - self.Input = Connector(self, "", value_type, wxPoint(0, 0), WEST) - if self.Type != OUTPUT: - self.Output = Connector(self, "", value_type, wxPoint(0, 0), EAST) - self.RefreshConnectors() + self.SetType(type, value_type) # Destructor def __del__(self): @@ -305,9 +299,9 @@ # Unconnect connector def Clean(self): if self.Input: - self.Input.UnConnect() + self.Input.UnConnect(delete = True) if self.Output: - self.Output.UnConnect() + self.Output.UnConnect(delete = True) # Delete this variable by calling the appropriate method def Delete(self): @@ -374,6 +368,21 @@ handle.SetNegated(negated) self.RefreshModel(False) + # Changes the variable type + def SetType(self, type, value_type): + if type != self.Type or value_type != self.ValueType: + self.Type = type + self.ValueType = value_type + self.Clean() + self.Input = None + self.Output = None + # Create an input or output connector according to variable type + if self.Type != INPUT: + self.Input = Connector(self, "", value_type, wxPoint(0, 0), WEST) + if self.Type != OUTPUT: + self.Output = Connector(self, "", value_type, wxPoint(0, 0), EAST) + self.RefreshConnectors() + # Returns the variable type def GetType(self): return self.Type @@ -392,6 +401,11 @@ text_width, text_height = dc.GetTextExtent(self.Name) return text_width + 10, text_height + 10 + # Method called when a LeftDClick event have been generated + def OnLeftDClick(self, event, scaling): + # Edit the variable properties + self.Parent.EditVariableContent(self) + # Method called when a RightUp event have been generated def OnRightUp(self, event, scaling): pos = GetScaledEventPosition(event, scaling) diff -r 93bc4c2cf376 -r 86ccc89d7b0b graphics/GraphicCommons.py --- a/graphics/GraphicCommons.py Wed Feb 07 18:43:32 2007 +0100 +++ b/graphics/GraphicCommons.py Thu Feb 08 17:41:41 2007 +0100 @@ -396,8 +396,8 @@ self.Dragging = True # If a dragging have been initiated, refreshes the element state if self.Dragging: + self.oldPos = pos self.ProcessDragging(movex, movey) - self.oldPos = pos # If cursor just pass over the element, changes the cursor if it is on a handle else: pos = event.GetPosition() @@ -639,6 +639,14 @@ return self.ParentBlock # Returns the connector name + def GetType(self): + return self.Type + + # Changes the connector name + def SetType(self, type): + self.Type = type + + # Returns the connector name def GetName(self): return self.Name @@ -1418,22 +1426,22 @@ def OnLeftDown(self, event, scaling): pos = GetScaledEventPosition(event, scaling) # Test if a point have been handled - result = self.TestPoint(pos) + #result = self.TestPoint(pos) + #if result != None: + # self.Handle = (HANDLE_POINT, result) + # self.Parent.SetCursor(wxStockCursor(wxCURSOR_HAND)) + #else: + # Test if a segment have been handled + result = self.TestSegment(pos) if result != None: - self.Handle = (HANDLE_POINT, result) - self.Parent.SetCursor(wxStockCursor(wxCURSOR_HAND)) + if result[1] in (NORTH, SOUTH): + self.Parent.SetCursor(wxStockCursor(wxCURSOR_SIZEWE)) + elif result[1] in (EAST, WEST): + self.Parent.SetCursor(wxStockCursor(wxCURSOR_SIZENS)) + self.Handle = (HANDLE_SEGMENT, result) + # Execute the default method for a graphic element else: - # Test if a segment have been handled - result = self.TestSegment(pos) - if result != None: - if result[1] in (NORTH, SOUTH): - self.Parent.SetCursor(wxStockCursor(wxCURSOR_SIZEWE)) - elif result[1] in (EAST, WEST): - self.Parent.SetCursor(wxStockCursor(wxCURSOR_SIZENS)) - self.Handle = (HANDLE_SEGMENT, result) - # Execute the default method for a graphic element - else: - Graphic_Element.OnLeftDown(self, event, scaling) + Graphic_Element.OnLeftDown(self, event, scaling) self.oldPos = pos # Method called when a RightUp event have been generated @@ -1467,17 +1475,17 @@ wxCallAfter(self.Parent.SetCursor, wxStockCursor(wxCURSOR_SIZENS)) else: # Test if a point has been handled - result = self.TestPoint(pos) - if result != None: - if result == 0 and self.StartConnected: - self.OverStart = True - elif result != 0 and self.EndConnected: - self.OverEnd = True - else: - self.OverStart = False - self.OverEnd = False - # Execute the default method for a graphic element - Graphic_Element.OnMotion(self, event, scaling) + #result = self.TestPoint(pos) + #if result != None: + # if result == 0 and self.StartConnected: + # self.OverStart = True + # elif result != 0 and self.EndConnected: + # self.OverEnd = True + #else: + # self.OverStart = False + # self.OverEnd = False + # Execute the default method for a graphic element + Graphic_Element.OnMotion(self, event, scaling) else: # Execute the default method for a graphic element Graphic_Element.OnMotion(self, event, scaling) @@ -1495,11 +1503,13 @@ connector.Connect((self, handle)) self.SetStartPointDirection(connector.GetDirection()) self.ConnectStartPoint(connector.GetPosition(), connector) + self.oldPos = connector.GetPosition() self.Dragging = False elif handle != 0 and self.StartConnected != connector: connector.Connect((self, handle)) self.SetEndPointDirection(connector.GetDirection()) self.ConnectEndPoint(connector.GetPosition(), connector) + self.oldPos = connector.GetPosition() self.Dragging = False elif handle == 0: self.MoveStartPoint(new_pos)