From 24b35576788d87bdac80b6db61680a21c54cca87 Mon Sep 17 00:00:00 2001 From: SiboVG Date: Fri, 7 Apr 2023 17:59:37 +0200 Subject: [PATCH] [#2183] Don't track stages when doing copy-ing --- .../rocketcomponent/RocketComponent.java | 106 ++++++++++++++---- .../gui/main/OpenRocketClipboard.java | 2 +- .../sf/openrocket/gui/main/RocketActions.java | 4 +- 3 files changed, 85 insertions(+), 27 deletions(-) diff --git a/core/src/net/sf/openrocket/rocketcomponent/RocketComponent.java b/core/src/net/sf/openrocket/rocketcomponent/RocketComponent.java index 313022179..c662a976a 100644 --- a/core/src/net/sf/openrocket/rocketcomponent/RocketComponent.java +++ b/core/src/net/sf/openrocket/rocketcomponent/RocketComponent.java @@ -1668,6 +1668,22 @@ public abstract class RocketComponent implements ChangeSource, Cloneable, Iterab /////////// Children handling /////////// + /** + * Adds a child to the rocket component tree. The component is added to the end + * of the component's child list. This is a helper method that calls + * {@link #addChild(RocketComponent,int)}. + * + * @param component The component to add. + * @param trackStage If component is a stage, this check will decide whether the rocket should track that stage (add it to the stageList etc.) + * @throws IllegalArgumentException if the component is already part of some + * component tree. + * @see #addChild(RocketComponent,int) + */ + public final void addChild(RocketComponent component, boolean trackStage) { + checkState(); + addChild(component, children.size(), trackStage); + } + /** * Adds a child to the rocket component tree. The component is added to the end * of the component's child list. This is a helper method that calls @@ -1679,10 +1695,9 @@ public abstract class RocketComponent implements ChangeSource, Cloneable, Iterab * @see #addChild(RocketComponent,int) */ public final void addChild(RocketComponent component) { - checkState(); - addChild(component, children.size()); + addChild(component, true); } - + /** * Adds a child to the rocket component tree. The component is added to * the given position of the component's child list. @@ -1692,28 +1707,29 @@ public abstract class RocketComponent implements ChangeSource, Cloneable, Iterab * * @param component The component to add. * @param index Position to add component to. + * @param trackStage If component is a stage, this check will decide whether the rocket should track that stage (add it to the stageList etc.) * @throws IllegalArgumentException If the component is already part of * some component tree. */ - public void addChild(RocketComponent component, int index) { + public void addChild(RocketComponent component, int index, boolean trackStage) { checkState(); - + if (component.parent != null) { throw new IllegalArgumentException("component " + component.getComponentName() + " is already in a tree"); } - + // Ensure that the no loops are created in component tree [A -> X -> Y -> B, B.addChild(A)] if (this.getRoot().equals(component)) { throw new IllegalStateException("Component " + component.getComponentName() + " is a parent of " + this.getComponentName() + ", attempting to create cycle in tree."); } - + if (!isCompatible(component)) { throw new IllegalStateException("Component: " + component.getComponentName() + " not currently compatible with component: " + getComponentName()); } - + children.add(index, component); component.parent = this; if (this.massOverridden && this.overrideSubcomponentsMass) { @@ -1746,18 +1762,48 @@ public abstract class RocketComponent implements ChangeSource, Cloneable, Iterab child.CDOverriddenBy = component.CDOverriddenBy; } } - - if (component instanceof AxialStage) { + + if (trackStage && (component instanceof AxialStage)) { AxialStage nStage = (AxialStage) component; this.getRocket().trackStage(nStage); } - + this.checkComponentStructure(); component.checkComponentStructure(); - + fireAddRemoveEvent(component); } + /** + * Adds a child to the rocket component tree. The component is added to + * the given position of the component's child list. + *

+ * This method may be overridden to enforce more strict component addition rules. + * The tests should be performed first and then this method called. + * + * @param component The component to add. + * @param index Position to add component to. + * @throws IllegalArgumentException If the component is already part of + * some component tree. + */ + public void addChild(RocketComponent component, int index) { + addChild(component, index, true); + } + + /** + * Removes a child from the rocket component tree. + * (redirect to the removed-by-component + * + * @param n remove the n'th child. + * @param trackStage If component is a stage, this check will decide whether the rocket should track that stage (remove it to the stageList etc.) + * @throws IndexOutOfBoundsException if n is out of bounds + */ + public final void removeChild(int n, boolean trackStage) { + checkState(); + RocketComponent component = this.getChild(n); + this.removeChild(component, trackStage); + } + /** * Removes a child from the rocket component tree. * (redirect to the removed-by-component @@ -1766,9 +1812,7 @@ public abstract class RocketComponent implements ChangeSource, Cloneable, Iterab * @throws IndexOutOfBoundsException if n is out of bounds */ public final void removeChild(int n) { - checkState(); - RocketComponent component = this.getChild(n); - this.removeChild(component); + removeChild(n, true); } /** @@ -1776,9 +1820,10 @@ public abstract class RocketComponent implements ChangeSource, Cloneable, Iterab * is not present as a child. * * @param component the component to remove + * @param trackStage If component is a stage, this check will decide whether the rocket should track that stage (remove it to the stageList etc.) * @return whether the component was a child */ - public final boolean removeChild(RocketComponent component) { + public final boolean removeChild(RocketComponent component, boolean trackStage) { checkState(); component.checkComponentStructure(); @@ -1800,15 +1845,17 @@ public abstract class RocketComponent implements ChangeSource, Cloneable, Iterab c.CDOverriddenBy = null; } } - - if (component instanceof AxialStage) { - AxialStage stage = (AxialStage) component; - this.getRocket().forgetStage(stage); - } - // Remove sub-stages of the removed component - for (AxialStage stage : component.getSubStages()) { - this.getRocket().forgetStage(stage); + if (trackStage) { + if (component instanceof AxialStage) { + AxialStage stage = (AxialStage) component; + this.getRocket().forgetStage(stage); + } + + // Remove sub-stages of the removed component + for (AxialStage stage : component.getSubStages()) { + this.getRocket().forgetStage(stage); + } } this.checkComponentStructure(); @@ -1821,6 +1868,17 @@ public abstract class RocketComponent implements ChangeSource, Cloneable, Iterab } return false; } + + /** + * Removes a child from the rocket component tree. Does nothing if the component + * is not present as a child. + * + * @param component the component to remove + * @return whether the component was a child + */ + public final boolean removeChild(RocketComponent component) { + return removeChild(component, true); + } diff --git a/swing/src/net/sf/openrocket/gui/main/OpenRocketClipboard.java b/swing/src/net/sf/openrocket/gui/main/OpenRocketClipboard.java index cda0a7e85..7302d8b43 100644 --- a/swing/src/net/sf/openrocket/gui/main/OpenRocketClipboard.java +++ b/swing/src/net/sf/openrocket/gui/main/OpenRocketClipboard.java @@ -101,7 +101,7 @@ public final class OpenRocketClipboard { if (someChildrenSelected) { for (RocketComponent child : component.getChildren()) { if (!clipboardComponents.contains(child)) { - component.removeChild(child); + component.removeChild(child, false); } else { clipboardComponents.remove(child); filterClipboardComponents(child.getChildren()); diff --git a/swing/src/net/sf/openrocket/gui/main/RocketActions.java b/swing/src/net/sf/openrocket/gui/main/RocketActions.java index 200244723..2bfa6e9a6 100644 --- a/swing/src/net/sf/openrocket/gui/main/RocketActions.java +++ b/swing/src/net/sf/openrocket/gui/main/RocketActions.java @@ -337,7 +337,7 @@ public class RocketActions { RocketComponent originalParent = components.get(i).getParent(); int originalParentIdx = components.indexOf(originalParent); - result.get(originalParentIdx).addChild(result.get(i)); + result.get(originalParentIdx).addChild(result.get(i), false); } else if (RocketComponent.listContainsParent(components, components.get(i))){ RocketComponent originalParent = components.get(i); while (originalParent != components.get(i)) { @@ -346,7 +346,7 @@ public class RocketActions { } } int originalParentIdx = components.indexOf(originalParent); - result.get(originalParentIdx).addChild(result.get(i)); + result.get(originalParentIdx).addChild(result.get(i), false); } }