# HG changeset patch # User lbessard # Date 1224253335 -7200 # Node ID c4199b88cf60b161d40c0f23f779f6fc4e07ab8e # Parent a18ddbbc5c5816761bd8f929bce2ccfe4f02830c Adding support for copying a group of elements diff -r a18ddbbc5c58 -r c4199b88cf60 Viewer.py --- a/Viewer.py Mon Oct 13 16:07:52 2008 +0200 +++ b/Viewer.py Fri Oct 17 16:22:15 2008 +0200 @@ -444,11 +444,11 @@ wires = self.Wires.keys() comments = self.Comments.keys() if sort_blocks: - blocks.sort(lambda x,y:self.Blocks[x].__cmp__(self.Blocks[y])) + blocks.sort(lambda x, y: cmp(self.Blocks[x], self.Blocks[y])) if sort_wires: - wires.sort(lambda x,y:self.Wires[x].__cmp__(self.Wires[y])) + wires.sort(lambda x, y: cmp(self.Wires[x], self.Wires[y])) if sort_comments: - comments.sort(lambda x,y:self.Comments[x].__cmp__(self.Comments[y])) + comments.sort(lambda x, y: cmp(self.Comments[x], self.Comments[y])) return blocks + wires + comments def RefreshVisibleElements(self, xp = None, yp = None): @@ -2430,7 +2430,7 @@ #------------------------------------------------------------------------------- def Cut(self): - if not self.Debug and (self.IsBlock(self.SelectedElement) or self.IsComment(self.SelectedElement)): + if not self.Debug and (self.IsBlock(self.SelectedElement) or self.IsComment(self.SelectedElement) or isinstance(self.SelectedElement, Graphic_Group)): self.ParentWindow.SetCopyBuffer(self.SelectedElement.Clone(self)) rect = self.SelectedElement.GetRedrawRect(1, 1) self.SelectedElement.Delete() @@ -2442,12 +2442,12 @@ self.RefreshRect(self.GetScrolledRect(rect), False) def Copy(self): - if not self.Debug and (self.IsBlock(self.SelectedElement) or self.IsComment(self.SelectedElement)): + if not self.Debug and (self.IsBlock(self.SelectedElement) or self.IsComment(self.SelectedElement) or isinstance(self.SelectedElement, Graphic_Group)): self.ParentWindow.SetCopyBuffer(self.SelectedElement.Clone(self)) def Paste(self): element = self.ParentWindow.GetCopyBuffer() - if not self.Debug and element is not None and self.CanAddBlock(element): + if not self.Debug and element is not None and self.CanAddElement(element): block = self.CopyBlock(element, wx.Point(*self.CalcUnscrolledPosition(30, 30))) if self.SelectedElement is not None: self.SelectedElement.SetSelected(False) @@ -2458,9 +2458,15 @@ self.RefreshVisibleElements() self.ParentWindow.RefreshVariablePanel(self.TagName) self.ParentWindow.RefreshInstancesTree() - - def CanAddBlock(self, block): - if self.CurrentLanguage == "SFC": + else: + message = wx.MessageDialog(self, "You can't paste the element in buffer here!", "Error", wx.OK|wx.ICON_ERROR) + message.ShowModal() + message.Destroy() + + def CanAddElement(self, block): + if isinstance(block, Graphic_Group): + return block.CanAddBlocks(self) + elif self.CurrentLanguage == "SFC": return True elif self.CurrentLanguage == "LD" and not isinstance(block, (SFC_Step, SFC_Transition, SFC_Divergence, SFC_Jump, SFC_ActionBlock)): return True @@ -2468,63 +2474,75 @@ return True return False + def GenerateNewName(self, element): + if isinstance(element, FBD_Block): + names = [varname.upper() for varname in self.Controler.GetEditedElementVariables(self.TagName, self.Debug)] + format = "Block%d" + elif isinstance(element, SFC_Step): + names = [block.GetName().upper() for block in self.Blocks if isinstance(block, SFC_Step)] + format = "Step%d" + i = 1 + while (format%i).upper() in names: + i += 1 + return format%i + + def IsNamedElement(self, element): + return isinstance(element, FBD_Block) and element.GetName() != "" or isinstance(element, SFC_Step) + def CopyBlock(self, element, pos): id = self.GetNewId() - if isinstance(element, FBD_Block) and element.GetName() != "" or isinstance(element, SFC_Step): - if isinstance(element, FBD_Block): - names = [varname.upper() for varname in self.Controler.GetEditedElementVariables(self.TagName, self.Debug)] - format = "Block%d" - elif isinstance(element, SFC_Step): - names = [block.GetName().upper() for block in self.Blocks if isinstance(block, SFC_Step)] - format = "Step%d" - i = 1 - while (format%i).upper() in names: - i += 1 - name = format%i - block = element.Clone(self, id, name, pos) + if isinstance(element, Graphic_Group): + block = element.Clone(self, pos=pos) else: - name = None - block = element.Clone(self, id, pos=pos) + if self.IsNamedElement(element): + name = self.GenerateNewName(element) + block = element.Clone(self, id, name, pos) + else: + name = None + block = element.Clone(self, id, pos=pos) + self.AddBlockInModel(block) + return block + + def AddBlockInModel(self, block): if isinstance(block, Comment): self.AddComment(block) - self.Controler.AddEditedElementComment(self.TagName, id) + self.Controler.AddEditedElementComment(self.TagName, block.GetId()) self.RefreshCommentModel(block) else: self.AddBlock(block) if isinstance(block, FBD_Block): - self.Controler.AddEditedElementBlock(self.TagName, id, block.GetType(), name) + self.Controler.AddEditedElementBlock(self.TagName, block.GetId(), block.GetType(), block.GetName()) self.RefreshBlockModel(block) elif isinstance(block, FBD_Variable): - self.Controler.AddEditedElementVariable(self.TagName, id, block.GetType()) + self.Controler.AddEditedElementVariable(self.TagName, block.GetId(), block.GetType()) self.RefreshVariableModel(block) elif isinstance(block, FBD_Connector): - self.Controler.AddEditedElementConnection(self.TagName, id, block.GetType()) + self.Controler.AddEditedElementConnection(self.TagName, block.GetId(), block.GetType()) self.RefreshConnectionModel(block) elif isinstance(block, LD_Contact): - self.Controler.AddEditedElementContact(self.TagName, id) + self.Controler.AddEditedElementContact(self.TagName, block.GetId()) self.RefreshContactModel(block) elif isinstance(block, LD_Coil): - self.Controler.AddEditedElementCoil(self.TagName, id) + self.Controler.AddEditedElementCoil(self.TagName, block.GetId()) self.RefreshCoilModel(block) elif isinstance(block, LD_PowerRail): - self.Controler.AddEditedElementPowerRail(self.TagName, id, block.GetType()) + self.Controler.AddEditedElementPowerRail(self.TagName, block.GetId(), block.GetType()) self.RefreshPowerRailModel(block) elif isinstance(block, SFC_Step): - self.Controler.AddEditedElementStep(self.TagName, id) + self.Controler.AddEditedElementStep(self.TagName, block.GetId()) self.RefreshStepModel(block) elif isinstance(block, SFC_Transition): - self.Controler.AddEditedElementTransition(self.TagName, id) + self.Controler.AddEditedElementTransition(self.TagName, block.GetId()) self.RefreshTransitionModel(block) elif isinstance(block, SFC_Divergence): - self.Controler.AddEditedElementDivergence(self.TagName, id, block.GetType()) + self.Controler.AddEditedElementDivergence(self.TagName, block.GetId(), block.GetType()) self.RefreshDivergenceModel(block) elif isinstance(block, SFC_Jump): - self.Controler.AddEditedElementJump(self.TagName, id) + self.Controler.AddEditedElementJump(self.TagName, block.GetId()) self.RefreshJumpModel(block) elif isinstance(block, SFC_ActionBlock): - self.Controler.AddEditedElementActionBlock(self.TagName, id) + self.Controler.AddEditedElementActionBlock(self.TagName, block.GetId()) self.RefreshActionBlockModel(block) - return block #------------------------------------------------------------------------------- diff -r a18ddbbc5c58 -r c4199b88cf60 graphics/FBD_Objects.py --- a/graphics/FBD_Objects.py Mon Oct 13 16:07:52 2008 +0200 +++ b/graphics/FBD_Objects.py Fri Oct 17 16:22:15 2008 +0200 @@ -61,10 +61,15 @@ block.SetSize(self.Size[0], self.Size[1]) if pos is not None: block.SetPosition(pos.x, pos.y) + else: + block.SetPosition(self.Pos.x, self.Pos.y) block.Inputs = [input.Clone(block) for input in self.Inputs] block.Outputs = [output.Clone(block) for output in self.Outputs] return block + def GetConnectorTranslation(self, element): + return dict(zip(self.Inputs + self.Outputs, element.Inputs + element.Outputs)) + def Flush(self): for input in self.Inputs: input.Flush() @@ -440,12 +445,22 @@ variable.SetSize(self.Size[0], self.Size[1]) if pos is not None: variable.SetPosition(pos.x, pos.y) + else: + variable.SetPosition(self.Pos.x, self.Pos.y) if self.Input: variable.Input = self.Input.Clone(variable) if self.Output: variable.Output = self.Output.Clone(variable) return variable + def GetConnectorTranslation(self, element): + connectors = {} + if self.Input is not None: + connector[self.Input] = element.Input + if self.Output is not None: + connectors[self.Output] = element.Output + return connectors + def Flush(self): if self.Input is not None: self.Input.Flush() @@ -706,9 +721,14 @@ connection.SetSize(self.Size[0], self.Size[1]) if pos is not None: connection.SetPosition(pos.x, pos.y) + else: + connection.SetPosition(self.Pos.x, self.Pos.y) connection.Connector = self.Connector.Clone(connection) return connection + def GetConnectorTranslation(self, element): + return {self.Connector : element.Connector} + # Unconnect connector def Clean(self): if self.Connector: diff -r a18ddbbc5c58 -r c4199b88cf60 graphics/GraphicCommons.py --- a/graphics/GraphicCommons.py Mon Oct 13 16:07:52 2008 +0200 +++ b/graphics/GraphicCommons.py Fri Oct 17 16:22:15 2008 +0200 @@ -323,6 +323,9 @@ def SpreadCurrent(self): pass + def GetConnectorTranslation(self, element): + return {} + def IsOfType(self, type, reference): return self.Parent.IsOfType(type, reference) @@ -674,6 +677,51 @@ def __del__(self): self.Elements = [] + # Make a clone of this element + def Clone(self, parent, pos = None): + group = Graphic_Group(parent) + connectors = {} + wires = [] + if pos is not None: + dx, dy = pos.x - self.BoundingBox.x, pos.y - self.BoundingBox.y + for element in self.Elements: + if isinstance(element, Wire): + wires.append(element) + else: + if pos is not None: + x, y = element.GetPosition() + new_pos = wx.Point(x + dx, y + dy) + newid = parent.GetNewId() + if parent.IsNamedElement(element): + name = parent.GenerateNewName(element) + new_element = element.Clone(parent, newid, name, pos = new_pos) + else: + new_element = element.Clone(parent, newid, pos = new_pos) + else: + new_element = element.Clone(parent) + connectors.update(element.GetConnectorTranslation(new_element)) + group.SelectElement(new_element) + for element in wires: + if pos is not None: + new_wire = element.Clone(parent, connectors, dx, dy) + else: + new_wire = element.Clone(parent, connectors) + if new_wire is not None: + parent.AddWire(new_wire) + group.SelectElement(new_wire) + if pos is not None: + for element in group.Elements: + if not isinstance(element, Wire): + parent.AddBlockInModel(element) + return group + + def CanAddBlocks(self, parent): + valid = True + for element in self.Elements: + if not isinstance(element, Wire): + valid &= parent.CanAddElement(element) + return valid + def IsVisible(self): for element in self.Elements: if element.IsVisible(): @@ -690,16 +738,6 @@ if startblock in self.Elements and endblock in self.Elements: self.WireExcluded.append(element) - # Make a clone of this group - def Clone(self, parent): - clone = Graphic_Group(parent) - elements = [] - # Makes a clone of all the elements in this group - for element in self.Elements: - elements.append(element.Clone(parent)) - clone.SetElements(elements) - return clone - # Returns the RedrawRect def GetRedrawRect(self, movex = 0, movey = 0): rect = None @@ -1309,6 +1347,19 @@ rect = rect.Union(wx.Rect(x, y, width, height)) return rect + def Clone(self, parent, connectors = {}, dx = 0, dy = 0): + start_connector = connectors.get(self.StartConnected, None) + end_connector = connectors.get(self.EndConnected, None) + if start_connector is not None and end_connector is not None: + wire = Wire(parent) + wire.SetPoints([(point.x + dx, point.y + dy) for point in self.Points]) + start_connector.Connect((wire, 0), False) + end_connector.Connect((wire, -1), False) + wire.ConnectStartPoint(start_connector.GetPosition(), start_connector) + wire.ConnectEndPoint(end_connector.GetPosition(), end_connector) + return wire + return None + # Forbids to change the wire position def SetPosition(x, y): pass diff -r a18ddbbc5c58 -r c4199b88cf60 graphics/LD_Objects.py --- a/graphics/LD_Objects.py Mon Oct 13 16:07:52 2008 +0200 +++ b/graphics/LD_Objects.py Fri Oct 17 16:22:15 2008 +0200 @@ -61,6 +61,8 @@ powerrail.SetSize(self.Size[0], self.Size[1]) if pos is not None: powerrail.SetPosition(pos.x, pos.y) + else: + powerrail.SetPosition(self.Pos.x, self.Pos.y) powerrail.Connectors = [] for connector in self.Connectors: if connector is not None: @@ -69,6 +71,10 @@ powerrail.Connectors.append(None) return powerrail + def GetConnectorTranslation(self, element): + return dict(zip([connector for connector in self.Connectors if connector is not None], + [connector for connector in element.Connectors if connector is not None])) + # Returns the RedrawRect def GetRedrawRect(self, movex = 0, movey = 0): rect = Graphic_Element.GetRedrawRect(self, movex, movey) @@ -434,10 +440,15 @@ contact.SetSize(self.Size[0], self.Size[1]) if pos is not None: contact.SetPosition(pos.x, pos.y) + else: + contact.SetPosition(self.Pos.x, self.Pos.y) contact.Input = self.Input.Clone(contact) contact.Output = self.Output.Clone(contact) return contact + def GetConnectorTranslation(self, element): + return {self.Input : element.Input, self.Output : element.Output} + # Returns the RedrawRect def GetRedrawRect(self, movex = 0, movey = 0): rect = Graphic_Element.GetRedrawRect(self, movex, movey) @@ -714,10 +725,15 @@ coil.SetSize(self.Size[0], self.Size[1]) if pos is not None: coil.SetPosition(pos.x, pos.y) + else: + coil.SetPosition(self.Pos.x, self.Pos.y) coil.Input = self.Input.Clone(coil) coil.Output = self.Output.Clone(coil) return coil + def GetConnectorTranslation(self, element): + return {self.Input : element.Input, self.Output : element.Output} + # Returns the RedrawRect def GetRedrawRect(self, movex = 0, movey = 0): rect = Graphic_Element.GetRedrawRect(self, movex, movey) diff -r a18ddbbc5c58 -r c4199b88cf60 graphics/SFC_Objects.py --- a/graphics/SFC_Objects.py Mon Oct 13 16:07:52 2008 +0200 +++ b/graphics/SFC_Objects.py Fri Oct 17 16:22:15 2008 +0200 @@ -101,6 +101,8 @@ step.SetSize(self.Size[0], self.Size[1]) if pos is not None: step.SetPosition(pos.x, pos.y) + else: + step.SetPosition(self.Pos.x, self.Pos.y) if self.Input: step.Input = self.Input.Clone(step) if self.Output: @@ -109,6 +111,16 @@ step.Action = self.Action.Clone(step) return step + def GetConnectorTranslation(self, element): + connectors = {} + if self.Input is not None: + connector[self.Input] = element.Input + if self.Output is not None: + connectors[self.Output] = element.Output + if self.Action is not None: + connectors[self.Action] = element.Action + return connectors + # Returns the RedrawRect def GetRedrawRect(self, movex = 0, movey = 0): rect = Graphic_Element.GetRedrawRect(self, movex, movey) @@ -589,12 +601,20 @@ transition.SetSize(self.Size[0], self.Size[1]) if pos is not None: transition.SetPosition(pos.x, pos.y) + else: + transition.SetPosition(self.Pos.x, self.Pos.y) transition.Input = self.Input.Clone(transition) transition.Output = self.Output.Clone(transition) if self.Type == "connection": transition.Condition = self.Condition.Clone(transition) return transition + def GetConnectorTranslation(self, element): + connectors = {self.Input : element.Input, self.Output : element.Output} + if self.Type == "connection" and self.Condition is not None: + connectors[self.Condition] = element.Condition + return connectors + # Returns the RedrawRect def GetRedrawRect(self, movex = 0, movey = 0): rect = Graphic_Element.GetRedrawRect(self, movex, movey) @@ -1023,10 +1043,15 @@ divergence.SetSize(self.Size[0], self.Size[1]) if pos is not None: divergence.SetPosition(pos.x, pos.y) + else: + divergence.SetPosition(self.Pos.x, self.Pos.y) divergence.Inputs = [input.Clone(divergence) for input in self.Inputs] divergence.Outputs = [output.Clone(divergence) for output in self.Outputs] return divergence + def GetConnectorTranslation(self, element): + return dict(zip(self.Inputs + self.Outputs, element.Inputs + element.Outputs)) + # Returns the RedrawRect def GetRedrawRect(self, movex = 0, movey = 0): rect = Graphic_Element.GetRedrawRect(self, movex, movey) @@ -1453,9 +1478,14 @@ jump.SetSize(self.Size[0], self.Size[1]) if pos is not None: jump.SetPosition(pos.x, pos.y) + else: + jump.SetPosition(self.Pos.x, self.Pos.y) jump.Input = self.Input.Clone(jump) return jump + def GetConnectorTranslation(self, element): + return {self.Input : element.Input} + # Returns the RedrawRect def GetRedrawRect(self, movex = 0, movey = 0): rect = Graphic_Element.GetRedrawRect(self, movex, movey) @@ -1694,10 +1724,15 @@ action_block.SetSize(self.Size[0], self.Size[1]) if pos is not None: action_block.SetPosition(pos.x, pos.y) + else: + action_block.SetPosition(self.Pos.x, self.Pos.y) action_block.Input = self.Input.Clone(action_block) return action_block - # Returns the RedrawRect + def GetConnectorTranslation(self, element): + return {self.Input : element.Input} + + # Returns the RedrawRect def GetRedrawRect(self, movex = 0, movey = 0): rect = Graphic_Element.GetRedrawRect(self, movex, movey) rect = rect.Union(self.Input.GetRedrawRect(movex, movey))