diff --git a/diylc/diylc-core/src/org/diylc/common/IPlugInPort.java b/diylc/diylc-core/src/org/diylc/common/IPlugInPort.java index f25c8d5d..20865023 100644 --- a/diylc/diylc-core/src/org/diylc/common/IPlugInPort.java +++ b/diylc/diylc-core/src/org/diylc/common/IPlugInPort.java @@ -202,9 +202,10 @@ public interface IPlugInPort extends ISelectionProcessor, IMouseProcessor, IKeyP /** * Adds a list of components to the project. * - * @param components + * @param components + * @param autoGroup */ - void pasteComponents(Collection> components); + void pasteComponents(Collection> components, boolean autoGroup); /** * Duplicates selected components and places them nearby. diff --git a/diylc/diylc-core/src/org/diylc/presenter/ComponentProcessor.java b/diylc/diylc-core/src/org/diylc/presenter/ComponentProcessor.java index e241c18d..a279c84d 100644 --- a/diylc/diylc-core/src/org/diylc/presenter/ComponentProcessor.java +++ b/diylc/diylc-core/src/org/diylc/presenter/ComponentProcessor.java @@ -117,21 +117,7 @@ public class ComponentProcessor { keywordTag = annotation.keywordTag(); continuity = annotation.continuity(); } else { // default - name = clazz.getSimpleName(); - description = ""; - creationMethod = CreationMethod.SINGLE_CLICK; - category = "Uncategorized"; - namePrefix = "Unknown"; - author = "Unknown"; - zOrder = IDIYComponent.COMPONENT; - flexibleZOrder = false; - stretchable = true; - bomPolicy = BomPolicy.SHOW_ALL_NAMES; - autoEdit = true; - transformer = null; - keywordPolicy = KeywordPolicy.NEVER_SHOW; - keywordTag = null; - continuity = false; + return null; } icon = null; // Draw component icon. diff --git a/diylc/diylc-core/src/org/diylc/presenter/InstantiationManager.java b/diylc/diylc-core/src/org/diylc/presenter/InstantiationManager.java index 7ef31690..c847d523 100644 --- a/diylc/diylc-core/src/org/diylc/presenter/InstantiationManager.java +++ b/diylc/diylc-core/src/org/diylc/presenter/InstantiationManager.java @@ -29,7 +29,7 @@ import java.util.Collection; import java.util.HashMap; import java.util.List; import java.util.Map; - + import org.apache.log4j.Logger; import org.diylc.appframework.miscutils.ConfigurationManager; import org.diylc.common.ComponentType; @@ -61,9 +61,12 @@ public class InstantiationManager { private Point firstControlPoint; private Point potentialControlPoint; - private static final ComponentType clipboardType = new ComponentType("Clipboard contents", + public static final ComponentType clipboardType = new ComponentType("Clipboard contents", "Components from the clipboard", CreationMethod.SINGLE_CLICK, "Multi", "", "", null, null, 0, false, false, null, - false, null, KeywordPolicy.NEVER_SHOW, null, false); + false, null, KeywordPolicy.NEVER_SHOW, null, false); + public static final ComponentType blockType = new ComponentType("Building block", + "Components from the building block", CreationMethod.SINGLE_CLICK, "Multi", "", "", null, null, 0, false, false, null, + false, null, KeywordPolicy.NEVER_SHOW, null, false); public InstantiationManager() {} @@ -85,7 +88,11 @@ public class InstantiationManager { public Point getPotentialControlPoint() { return potentialControlPoint; - } + } + + public void setPotentialControlPoint(Point potentialControlPoint) { + this.potentialControlPoint = potentialControlPoint; +} public void setComponentTypeSlot(ComponentType componentTypeSlot, Template template, Project currentProject) throws Exception { @@ -133,7 +140,7 @@ public class InstantiationManager { } public void pasteComponents(Collection> components, Point scaledPoint, boolean snapToGrid, - Size gridSpacing) { + Size gridSpacing, boolean autoGroup) { // Adjust location of components so they are centered under the mouse // cursor int minX = Integer.MAX_VALUE; @@ -176,7 +183,7 @@ public class InstantiationManager { // Update the component type slot so the app knows that something's // being instantiated. - this.componentTypeSlot = clipboardType; + this.componentTypeSlot = autoGroup ? blockType : clipboardType; if (snapToGrid) { scaledPoint = new Point(scaledPoint); diff --git a/diylc/diylc-core/src/org/diylc/presenter/Presenter.java b/diylc/diylc-core/src/org/diylc/presenter/Presenter.java index 9ac15193..cfd8f4e4 100644 --- a/diylc/diylc-core/src/org/diylc/presenter/Presenter.java +++ b/diylc/diylc-core/src/org/diylc/presenter/Presenter.java @@ -356,6 +356,8 @@ public class Presenter implements IPlugInPort { if (!Modifier.isAbstract(clazz.getModifiers()) && IDIYComponent.class.isAssignableFrom(clazz)) { ComponentType componentType = ComponentProcessor.getInstance().extractComponentTypeFrom((Class>) clazz); + if (componentType == null) + continue; List nestedList; if (componentTypes.containsKey(componentType.getCategory())) { nestedList = componentTypes.get(componentType.getCategory()); @@ -517,8 +519,8 @@ public class Presenter implements IPlugInPort { addComponent(component, true); newSelection.add(component); } - // group components if there's more than one, e.g. building blocks - if (componentSlot.size() > 1) { + // group components if there's more than one, e.g. building blocks, but not clipboard contents + if (componentSlot.size() > 1 && !componentTypeSlot.getName().toLowerCase().contains("clipboard")) { this.currentProject.getGroups().add(new HashSet>(componentSlot)); } // Select the new component @@ -1452,10 +1454,10 @@ public class Presenter implements IPlugInPort { } @Override - public void pasteComponents(Collection> components) { - LOG.info(String.format("pasteComponents(%s)", components)); + public void pasteComponents(Collection> components, boolean autoGroup) { + LOG.info(String.format("pasteComponents(%s, %s)", components, autoGroup)); instantiationManager.pasteComponents(components, this.previousScaledPoint, isSnapToGrid(), - currentProject.getGridSpacing()); + currentProject.getGridSpacing(), autoGroup); messageDispatcher.dispatchMessage(EventType.REPAINT); messageDispatcher.dispatchMessage(EventType.SLOT_CHANGED, instantiationManager.getComponentTypeSlot(), instantiationManager.getFirstControlPoint()); @@ -2327,6 +2329,8 @@ public class Presenter implements IPlugInPort { Collection> components = blocks.get(blockName); if (components == null) throw new InvalidBlockException(); + // clear potential control point every time! + instantiationManager.setPotentialControlPoint(null); // clone components List> clones = new ArrayList>(); List> testComponents = new ArrayList>(currentProject.getComponents()); @@ -2341,7 +2345,7 @@ public class Presenter implements IPlugInPort { LOG.error("Could not clone component: " + c); } // paste them to the project - pasteComponents(clones); + pasteComponents(clones, true); } else throw new InvalidBlockException(); } diff --git a/diylc/diylc-library/lib/diylc-core.jar b/diylc/diylc-library/lib/diylc-core.jar index 3c24d50f..5c31a81b 100644 Binary files a/diylc/diylc-library/lib/diylc-core.jar and b/diylc/diylc-library/lib/diylc-core.jar differ diff --git a/diylc/diylc-library/src/org/diylc/components/chassis/ChassisPanel.java b/diylc/diylc-library/src/org/diylc/components/chassis/ChassisPanel.java index a43098c3..bf351d5e 100644 --- a/diylc/diylc-library/src/org/diylc/components/chassis/ChassisPanel.java +++ b/diylc/diylc-library/src/org/diylc/components/chassis/ChassisPanel.java @@ -38,7 +38,7 @@ import org.diylc.core.annotations.EditableProperty; import org.diylc.core.measures.Size; import org.diylc.core.measures.SizeUnit; -@ComponentDescriptor(name = "Chassis Panel", author = "Branislav Stojkovic", category = "Electromechanical", +@ComponentDescriptor(name = "Chassis Panel", author = "Branislav Stojkovic", category = "Electro-Mechanical", instanceNamePrefix = "CP", description = "One side of a chassis, with or withouth rounded edges", zOrder = IDIYComponent.CHASSIS, bomPolicy = BomPolicy.SHOW_ONLY_TYPE_NAME, autoEdit = false, transformer = SimpleComponentTransformer.class) diff --git a/diylc/diylc-library/src/org/diylc/components/chassis/EllipticalCutout.java b/diylc/diylc-library/src/org/diylc/components/chassis/EllipticalCutout.java index d1521142..c1ec859e 100644 --- a/diylc/diylc-library/src/org/diylc/components/chassis/EllipticalCutout.java +++ b/diylc/diylc-library/src/org/diylc/components/chassis/EllipticalCutout.java @@ -1,75 +1,75 @@ -/* - * - * DIY Layout Creator (DIYLC). Copyright (c) 2009-2018 held jointly by the individual authors. - * - * This file is part of DIYLC. - * - * DIYLC is free software: you can redistribute it and/or modify it under the terms of the GNU - * General Public License as published by the Free Software Foundation, either version 3 of the - * License, or (at your option) any later version. - * - * DIYLC is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even - * the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General - * Public License for more details. - * - * You should have received a copy of the GNU General Public License along with DIYLC. If not, see - * . - */ -package org.diylc.components.chassis; - -import java.awt.AlphaComposite; -import java.awt.Composite; -import java.awt.Graphics2D; - -import org.diylc.common.ObjectCache; -import org.diylc.common.SimpleComponentTransformer; -import org.diylc.components.shapes.AbstractShape; -import org.diylc.core.ComponentState; -import org.diylc.core.IDIYComponent; -import org.diylc.core.IDrawingObserver; -import org.diylc.core.Project; -import org.diylc.core.annotations.BomPolicy; -import org.diylc.core.annotations.ComponentDescriptor; - -@ComponentDescriptor(name = "Elliptical Cutout", author = "Branislav Stojkovic", category = "Electromechanical", - instanceNamePrefix = "ELC", description = "Elliptical chassis cutout", zOrder = IDIYComponent.CHASSIS + 0.1, - bomPolicy = BomPolicy.NEVER_SHOW, autoEdit = false, transformer = SimpleComponentTransformer.class) -public class EllipticalCutout extends AbstractShape { - - private static final long serialVersionUID = 1L; - - public EllipticalCutout() { - this.borderColor = LIGHT_METAL_COLOR.darker(); - } - - @Override - public void draw(Graphics2D g2d, ComponentState componentState, boolean outlineMode, Project project, - IDrawingObserver drawingObserver) { - g2d.setStroke(ObjectCache.getInstance().fetchBasicStroke((int) borderThickness.convertToPixels())); - - if (componentState != ComponentState.DRAGGING) { - Composite oldComposite = g2d.getComposite(); - if (alpha < MAX_ALPHA) { - g2d.setComposite(AlphaComposite.getInstance(AlphaComposite.SRC_OVER, 1f * alpha / MAX_ALPHA)); - } - g2d.setColor(color); - g2d.fillOval(firstPoint.x, firstPoint.y, secondPoint.x - firstPoint.x, secondPoint.y - firstPoint.y); - g2d.setComposite(oldComposite); - } - // Do not track any changes that follow because the whole oval has been - // tracked so far. - drawingObserver.stopTracking(); - g2d.setColor(componentState == ComponentState.SELECTED || componentState == ComponentState.DRAGGING ? SELECTION_COLOR - : borderColor); - g2d.drawOval(firstPoint.x, firstPoint.y, secondPoint.x - firstPoint.x, secondPoint.y - firstPoint.y); - } - - @Override - public void drawIcon(Graphics2D g2d, int width, int height) { - int factor = 32 / width; - g2d.setColor(COLOR); - g2d.fillOval(2 / factor, 2 / factor, width - 4 / factor, height - 4 / factor); - g2d.setColor(LIGHT_METAL_COLOR.darker()); - g2d.drawOval(2 / factor, 2 / factor, width - 4 / factor, height - 4 / factor); - } -} +/* + * + * DIY Layout Creator (DIYLC). Copyright (c) 2009-2018 held jointly by the individual authors. + * + * This file is part of DIYLC. + * + * DIYLC is free software: you can redistribute it and/or modify it under the terms of the GNU + * General Public License as published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * DIYLC is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even + * the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General + * Public License for more details. + * + * You should have received a copy of the GNU General Public License along with DIYLC. If not, see + * . + */ +package org.diylc.components.chassis; + +import java.awt.AlphaComposite; +import java.awt.Composite; +import java.awt.Graphics2D; + +import org.diylc.common.ObjectCache; +import org.diylc.common.SimpleComponentTransformer; +import org.diylc.components.shapes.AbstractShape; +import org.diylc.core.ComponentState; +import org.diylc.core.IDIYComponent; +import org.diylc.core.IDrawingObserver; +import org.diylc.core.Project; +import org.diylc.core.annotations.BomPolicy; +import org.diylc.core.annotations.ComponentDescriptor; + +@ComponentDescriptor(name = "Elliptical Cutout", author = "Branislav Stojkovic", category = "Electro-Mechanical", + instanceNamePrefix = "ELC", description = "Elliptical chassis cutout", zOrder = IDIYComponent.CHASSIS + 0.1, + bomPolicy = BomPolicy.NEVER_SHOW, autoEdit = false, transformer = SimpleComponentTransformer.class) +public class EllipticalCutout extends AbstractShape { + + private static final long serialVersionUID = 1L; + + public EllipticalCutout() { + this.borderColor = LIGHT_METAL_COLOR.darker(); + } + + @Override + public void draw(Graphics2D g2d, ComponentState componentState, boolean outlineMode, Project project, + IDrawingObserver drawingObserver) { + g2d.setStroke(ObjectCache.getInstance().fetchBasicStroke((int) borderThickness.convertToPixels())); + + if (componentState != ComponentState.DRAGGING) { + Composite oldComposite = g2d.getComposite(); + if (alpha < MAX_ALPHA) { + g2d.setComposite(AlphaComposite.getInstance(AlphaComposite.SRC_OVER, 1f * alpha / MAX_ALPHA)); + } + g2d.setColor(color); + g2d.fillOval(firstPoint.x, firstPoint.y, secondPoint.x - firstPoint.x, secondPoint.y - firstPoint.y); + g2d.setComposite(oldComposite); + } + // Do not track any changes that follow because the whole oval has been + // tracked so far. + drawingObserver.stopTracking(); + g2d.setColor(componentState == ComponentState.SELECTED || componentState == ComponentState.DRAGGING ? SELECTION_COLOR + : borderColor); + g2d.drawOval(firstPoint.x, firstPoint.y, secondPoint.x - firstPoint.x, secondPoint.y - firstPoint.y); + } + + @Override + public void drawIcon(Graphics2D g2d, int width, int height) { + int factor = 32 / width; + g2d.setColor(COLOR); + g2d.fillOval(2 / factor, 2 / factor, width - 4 / factor, height - 4 / factor); + g2d.setColor(LIGHT_METAL_COLOR.darker()); + g2d.drawOval(2 / factor, 2 / factor, width - 4 / factor, height - 4 / factor); + } +} diff --git a/diylc/diylc-library/src/org/diylc/components/chassis/PolygonalCutout.java b/diylc/diylc-library/src/org/diylc/components/chassis/PolygonalCutout.java index 23dc1164..ea528b47 100644 --- a/diylc/diylc-library/src/org/diylc/components/chassis/PolygonalCutout.java +++ b/diylc/diylc-library/src/org/diylc/components/chassis/PolygonalCutout.java @@ -1,125 +1,125 @@ -/* - * - * DIY Layout Creator (DIYLC). Copyright (c) 2009-2018 held jointly by the individual authors. - * - * This file is part of DIYLC. - * - * DIYLC is free software: you can redistribute it and/or modify it under the terms of the GNU - * General Public License as published by the Free Software Foundation, either version 3 of the - * License, or (at your option) any later version. - * - * DIYLC is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even - * the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General - * Public License for more details. - * - * You should have received a copy of the GNU General Public License along with DIYLC. If not, see - * . - */ -package org.diylc.components.chassis; - -import java.awt.AlphaComposite; -import java.awt.Color; -import java.awt.Composite; -import java.awt.Graphics2D; -import java.awt.Point; -import java.util.Arrays; - -import org.diylc.common.ObjectCache; -import org.diylc.common.SimpleComponentTransformer; -import org.diylc.components.shapes.AbstractShape; -import org.diylc.core.ComponentState; -import org.diylc.core.IDIYComponent; -import org.diylc.core.IDrawingObserver; -import org.diylc.core.Project; -import org.diylc.core.annotations.BomPolicy; -import org.diylc.core.annotations.ComponentDescriptor; -import org.diylc.core.annotations.EditableProperty; - -@ComponentDescriptor(name = "Polygonal Cutout", author = "Branislav Stojkovic", category = "Electromechanical", - instanceNamePrefix = "POLYC", description = "Polygonal chassis cutout", zOrder = IDIYComponent.CHASSIS + 0.1, - bomPolicy = BomPolicy.NEVER_SHOW, autoEdit = false, transformer = SimpleComponentTransformer.class) -public class PolygonalCutout extends AbstractShape { - - private static final long serialVersionUID = 1L; - - protected PointCount pointCount = PointCount._4; - - public PolygonalCutout() { - super(); - this.borderColor = LIGHT_METAL_COLOR.darker(); - this.controlPoints = - new Point[] {new Point(0, 0), new Point(0, (int) DEFAULT_HEIGHT.convertToPixels()), - new Point((int) DEFAULT_WIDTH.convertToPixels(), (int) DEFAULT_HEIGHT.convertToPixels()), - new Point((int) DEFAULT_WIDTH.convertToPixels(), 0)}; - } - - @Override - public void draw(Graphics2D g2d, ComponentState componentState, boolean outlineMode, Project project, - IDrawingObserver drawingObserver) { - g2d.setStroke(ObjectCache.getInstance().fetchBasicStroke((int) borderThickness.convertToPixels())); - g2d.setColor(color); - int[] xPoints = new int[controlPoints.length]; - int[] yPoints = new int[controlPoints.length]; - for (int i = 0; i < controlPoints.length; i++) { - xPoints[i] = controlPoints[i].x; - yPoints[i] = controlPoints[i].y; - } - - Composite oldComposite = g2d.getComposite(); - if (this.alpha < MAX_ALPHA) { - g2d.setComposite(AlphaComposite.getInstance(3, 1.0F * this.alpha / MAX_ALPHA)); - } - g2d.fillPolygon(xPoints, yPoints, controlPoints.length); - g2d.setComposite(oldComposite); - - // Do not track any changes that follow because the whole board has been - // tracked so far. - drawingObserver.stopTracking(); - Color lineColor = - componentState == ComponentState.SELECTED || componentState == ComponentState.DRAGGING ? SELECTION_COLOR - : borderColor; - g2d.setColor(lineColor); - g2d.drawPolygon(xPoints, yPoints, controlPoints.length); - } - - @EditableProperty(name = "Edges") - public PointCount getPointCount() { - return pointCount; - } - - public void setPointCount(PointCount pointCount) { - if (this.pointCount == pointCount) - return; - int oldPointCount = Integer.parseInt(this.pointCount.toString()); - int newPointCount = Integer.parseInt(pointCount.toString()); - this.controlPoints = Arrays.copyOf(this.controlPoints, newPointCount); - if (oldPointCount < newPointCount) { - this.controlPoints[newPointCount - 1] = this.controlPoints[oldPointCount - 1]; - for (int i = oldPointCount - 1; i < newPointCount - 1; i++) { - this.controlPoints[i] = - new Point((this.controlPoints[i - 1].x + this.controlPoints[newPointCount - 1].x) / 2, - (this.controlPoints[i - 1].y + this.controlPoints[newPointCount - 1].y) / 2); - } - } - this.pointCount = pointCount; - } - - @Override - public void drawIcon(Graphics2D g2d, int width, int height) { - int factor = 32 / width; - g2d.setColor(COLOR); - int[] x = {2 / factor, width - 2 / factor, width - 4 / factor, 3 / factor}; - int[] y = {4 / factor, 2 / factor, height - 5 / factor, height - 2 / factor}; - g2d.fillPolygon(x, y, 4); - g2d.setColor(LIGHT_METAL_COLOR.darker()); - g2d.drawPolygon(x, y, 4); - } - - public enum PointCount { - _3, _4, _5, _6, _7, _8; - - public String toString() { - return name().substring(1); - }; - } -} +/* + * + * DIY Layout Creator (DIYLC). Copyright (c) 2009-2018 held jointly by the individual authors. + * + * This file is part of DIYLC. + * + * DIYLC is free software: you can redistribute it and/or modify it under the terms of the GNU + * General Public License as published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * DIYLC is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even + * the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General + * Public License for more details. + * + * You should have received a copy of the GNU General Public License along with DIYLC. If not, see + * . + */ +package org.diylc.components.chassis; + +import java.awt.AlphaComposite; +import java.awt.Color; +import java.awt.Composite; +import java.awt.Graphics2D; +import java.awt.Point; +import java.util.Arrays; + +import org.diylc.common.ObjectCache; +import org.diylc.common.SimpleComponentTransformer; +import org.diylc.components.shapes.AbstractShape; +import org.diylc.core.ComponentState; +import org.diylc.core.IDIYComponent; +import org.diylc.core.IDrawingObserver; +import org.diylc.core.Project; +import org.diylc.core.annotations.BomPolicy; +import org.diylc.core.annotations.ComponentDescriptor; +import org.diylc.core.annotations.EditableProperty; + +@ComponentDescriptor(name = "Polygonal Cutout", author = "Branislav Stojkovic", category = "Electro-Mechanical", + instanceNamePrefix = "POLYC", description = "Polygonal chassis cutout", zOrder = IDIYComponent.CHASSIS + 0.1, + bomPolicy = BomPolicy.NEVER_SHOW, autoEdit = false, transformer = SimpleComponentTransformer.class) +public class PolygonalCutout extends AbstractShape { + + private static final long serialVersionUID = 1L; + + protected PointCount pointCount = PointCount._4; + + public PolygonalCutout() { + super(); + this.borderColor = LIGHT_METAL_COLOR.darker(); + this.controlPoints = + new Point[] {new Point(0, 0), new Point(0, (int) DEFAULT_HEIGHT.convertToPixels()), + new Point((int) DEFAULT_WIDTH.convertToPixels(), (int) DEFAULT_HEIGHT.convertToPixels()), + new Point((int) DEFAULT_WIDTH.convertToPixels(), 0)}; + } + + @Override + public void draw(Graphics2D g2d, ComponentState componentState, boolean outlineMode, Project project, + IDrawingObserver drawingObserver) { + g2d.setStroke(ObjectCache.getInstance().fetchBasicStroke((int) borderThickness.convertToPixels())); + g2d.setColor(color); + int[] xPoints = new int[controlPoints.length]; + int[] yPoints = new int[controlPoints.length]; + for (int i = 0; i < controlPoints.length; i++) { + xPoints[i] = controlPoints[i].x; + yPoints[i] = controlPoints[i].y; + } + + Composite oldComposite = g2d.getComposite(); + if (this.alpha < MAX_ALPHA) { + g2d.setComposite(AlphaComposite.getInstance(3, 1.0F * this.alpha / MAX_ALPHA)); + } + g2d.fillPolygon(xPoints, yPoints, controlPoints.length); + g2d.setComposite(oldComposite); + + // Do not track any changes that follow because the whole board has been + // tracked so far. + drawingObserver.stopTracking(); + Color lineColor = + componentState == ComponentState.SELECTED || componentState == ComponentState.DRAGGING ? SELECTION_COLOR + : borderColor; + g2d.setColor(lineColor); + g2d.drawPolygon(xPoints, yPoints, controlPoints.length); + } + + @EditableProperty(name = "Edges") + public PointCount getPointCount() { + return pointCount; + } + + public void setPointCount(PointCount pointCount) { + if (this.pointCount == pointCount) + return; + int oldPointCount = Integer.parseInt(this.pointCount.toString()); + int newPointCount = Integer.parseInt(pointCount.toString()); + this.controlPoints = Arrays.copyOf(this.controlPoints, newPointCount); + if (oldPointCount < newPointCount) { + this.controlPoints[newPointCount - 1] = this.controlPoints[oldPointCount - 1]; + for (int i = oldPointCount - 1; i < newPointCount - 1; i++) { + this.controlPoints[i] = + new Point((this.controlPoints[i - 1].x + this.controlPoints[newPointCount - 1].x) / 2, + (this.controlPoints[i - 1].y + this.controlPoints[newPointCount - 1].y) / 2); + } + } + this.pointCount = pointCount; + } + + @Override + public void drawIcon(Graphics2D g2d, int width, int height) { + int factor = 32 / width; + g2d.setColor(COLOR); + int[] x = {2 / factor, width - 2 / factor, width - 4 / factor, 3 / factor}; + int[] y = {4 / factor, 2 / factor, height - 5 / factor, height - 2 / factor}; + g2d.fillPolygon(x, y, 4); + g2d.setColor(LIGHT_METAL_COLOR.darker()); + g2d.drawPolygon(x, y, 4); + } + + public enum PointCount { + _3, _4, _5, _6, _7, _8; + + public String toString() { + return name().substring(1); + }; + } +} diff --git a/diylc/diylc-library/src/org/diylc/components/chassis/RectangularCutout.java b/diylc/diylc-library/src/org/diylc/components/chassis/RectangularCutout.java index 310acfc1..2901f55a 100644 --- a/diylc/diylc-library/src/org/diylc/components/chassis/RectangularCutout.java +++ b/diylc/diylc-library/src/org/diylc/components/chassis/RectangularCutout.java @@ -1,92 +1,92 @@ -/* - * - * DIY Layout Creator (DIYLC). Copyright (c) 2009-2018 held jointly by the individual authors. - * - * This file is part of DIYLC. - * - * DIYLC is free software: you can redistribute it and/or modify it under the terms of the GNU - * General Public License as published by the Free Software Foundation, either version 3 of the - * License, or (at your option) any later version. - * - * DIYLC is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even - * the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General - * Public License for more details. - * - * You should have received a copy of the GNU General Public License along with DIYLC. If not, see - * . - */ -package org.diylc.components.chassis; - -import java.awt.AlphaComposite; -import java.awt.Composite; -import java.awt.Graphics2D; - -import org.diylc.common.ObjectCache; -import org.diylc.common.SimpleComponentTransformer; -import org.diylc.components.shapes.AbstractShape; -import org.diylc.core.ComponentState; -import org.diylc.core.IDIYComponent; -import org.diylc.core.IDrawingObserver; -import org.diylc.core.Project; -import org.diylc.core.annotations.BomPolicy; -import org.diylc.core.annotations.ComponentDescriptor; -import org.diylc.core.annotations.EditableProperty; -import org.diylc.core.measures.Size; -import org.diylc.core.measures.SizeUnit; - -@ComponentDescriptor(name = "Rectangular Cutout", author = "Branislav Stojkovic", category = "Electromechanical", - instanceNamePrefix = "RECTC", description = "Rectangular chassis cutout, with or without rounded edges", - zOrder = IDIYComponent.CHASSIS + 0.1, bomPolicy = BomPolicy.NEVER_SHOW, autoEdit = false, - transformer = SimpleComponentTransformer.class) -public class RectangularCutout extends AbstractShape { - - private static final long serialVersionUID = 1L; - - protected Size edgeRadius = new Size(0d, SizeUnit.mm); - - public RectangularCutout() { - this.borderColor = LIGHT_METAL_COLOR.darker(); - } - - @Override - public void draw(Graphics2D g2d, ComponentState componentState, boolean outlineMode, Project project, - IDrawingObserver drawingObserver) { - g2d.setStroke(ObjectCache.getInstance().fetchBasicStroke((int) borderThickness.convertToPixels())); - int radius = (int) edgeRadius.convertToPixels(); - if (componentState != ComponentState.DRAGGING) { - Composite oldComposite = g2d.getComposite(); - if (alpha < MAX_ALPHA) { - g2d.setComposite(AlphaComposite.getInstance(AlphaComposite.SRC_OVER, 1f * alpha / MAX_ALPHA)); - } - g2d.setColor(color); - g2d.fillRoundRect(firstPoint.x, firstPoint.y, secondPoint.x - firstPoint.x, secondPoint.y - firstPoint.y, radius, - radius); - g2d.setComposite(oldComposite); - } - // Do not track any changes that follow because the whole rect has been - // tracked so far. - drawingObserver.stopTracking(); - g2d.setColor(componentState == ComponentState.SELECTED || componentState == ComponentState.DRAGGING ? SELECTION_COLOR - : borderColor); - g2d.drawRoundRect(firstPoint.x, firstPoint.y, secondPoint.x - firstPoint.x, secondPoint.y - firstPoint.y, radius, - radius); - } - - @EditableProperty(name = "Radius") - public Size getEdgeRadius() { - return edgeRadius; - } - - public void setEdgeRadius(Size edgeRadius) { - this.edgeRadius = edgeRadius; - } - - @Override - public void drawIcon(Graphics2D g2d, int width, int height) { - int factor = 32 / width; - g2d.setColor(COLOR); - g2d.fillRect(2 / factor, 4 / factor, width - 4 / factor, height - 8 / factor); - g2d.setColor(LIGHT_METAL_COLOR.darker()); - g2d.drawRect(2 / factor, 4 / factor, width - 4 / factor, height - 8 / factor); - } -} +/* + * + * DIY Layout Creator (DIYLC). Copyright (c) 2009-2018 held jointly by the individual authors. + * + * This file is part of DIYLC. + * + * DIYLC is free software: you can redistribute it and/or modify it under the terms of the GNU + * General Public License as published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * DIYLC is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even + * the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General + * Public License for more details. + * + * You should have received a copy of the GNU General Public License along with DIYLC. If not, see + * . + */ +package org.diylc.components.chassis; + +import java.awt.AlphaComposite; +import java.awt.Composite; +import java.awt.Graphics2D; + +import org.diylc.common.ObjectCache; +import org.diylc.common.SimpleComponentTransformer; +import org.diylc.components.shapes.AbstractShape; +import org.diylc.core.ComponentState; +import org.diylc.core.IDIYComponent; +import org.diylc.core.IDrawingObserver; +import org.diylc.core.Project; +import org.diylc.core.annotations.BomPolicy; +import org.diylc.core.annotations.ComponentDescriptor; +import org.diylc.core.annotations.EditableProperty; +import org.diylc.core.measures.Size; +import org.diylc.core.measures.SizeUnit; + +@ComponentDescriptor(name = "Rectangular Cutout", author = "Branislav Stojkovic", category = "Electro-Mechanical", + instanceNamePrefix = "RECTC", description = "Rectangular chassis cutout, with or without rounded edges", + zOrder = IDIYComponent.CHASSIS + 0.1, bomPolicy = BomPolicy.NEVER_SHOW, autoEdit = false, + transformer = SimpleComponentTransformer.class) +public class RectangularCutout extends AbstractShape { + + private static final long serialVersionUID = 1L; + + protected Size edgeRadius = new Size(0d, SizeUnit.mm); + + public RectangularCutout() { + this.borderColor = LIGHT_METAL_COLOR.darker(); + } + + @Override + public void draw(Graphics2D g2d, ComponentState componentState, boolean outlineMode, Project project, + IDrawingObserver drawingObserver) { + g2d.setStroke(ObjectCache.getInstance().fetchBasicStroke((int) borderThickness.convertToPixels())); + int radius = (int) edgeRadius.convertToPixels(); + if (componentState != ComponentState.DRAGGING) { + Composite oldComposite = g2d.getComposite(); + if (alpha < MAX_ALPHA) { + g2d.setComposite(AlphaComposite.getInstance(AlphaComposite.SRC_OVER, 1f * alpha / MAX_ALPHA)); + } + g2d.setColor(color); + g2d.fillRoundRect(firstPoint.x, firstPoint.y, secondPoint.x - firstPoint.x, secondPoint.y - firstPoint.y, radius, + radius); + g2d.setComposite(oldComposite); + } + // Do not track any changes that follow because the whole rect has been + // tracked so far. + drawingObserver.stopTracking(); + g2d.setColor(componentState == ComponentState.SELECTED || componentState == ComponentState.DRAGGING ? SELECTION_COLOR + : borderColor); + g2d.drawRoundRect(firstPoint.x, firstPoint.y, secondPoint.x - firstPoint.x, secondPoint.y - firstPoint.y, radius, + radius); + } + + @EditableProperty(name = "Radius") + public Size getEdgeRadius() { + return edgeRadius; + } + + public void setEdgeRadius(Size edgeRadius) { + this.edgeRadius = edgeRadius; + } + + @Override + public void drawIcon(Graphics2D g2d, int width, int height) { + int factor = 32 / width; + g2d.setColor(COLOR); + g2d.fillRect(2 / factor, 4 / factor, width - 4 / factor, height - 8 / factor); + g2d.setColor(LIGHT_METAL_COLOR.darker()); + g2d.drawRect(2 / factor, 4 / factor, width - 4 / factor, height - 8 / factor); + } +} diff --git a/diylc/diylc-library/src/org/diylc/components/electromechanical/BatterySnap9V.java b/diylc/diylc-library/src/org/diylc/components/electromechanical/BatterySnap9V.java index 2e92e54c..618c27a2 100644 --- a/diylc/diylc-library/src/org/diylc/components/electromechanical/BatterySnap9V.java +++ b/diylc/diylc-library/src/org/diylc/components/electromechanical/BatterySnap9V.java @@ -51,7 +51,7 @@ import org.diylc.core.measures.Size; import org.diylc.core.measures.SizeUnit; import org.diylc.utils.Constants; -@ComponentDescriptor(name = "9V Battery Snap", category = "Electromechanical", author = "Branislav Stojkovic", +@ComponentDescriptor(name = "9V Battery Snap", category = "Electro-Mechanical", author = "Branislav Stojkovic", description = "", stretchable = false, zOrder = IDIYComponent.COMPONENT, instanceNamePrefix = "BTR", autoEdit = false, transformer = BatterySnapTransformer.class) public class BatterySnap9V extends AbstractTransparentComponent { diff --git a/diylc/diylc-library/src/org/diylc/components/electromechanical/CliffJack1_4.java b/diylc/diylc-library/src/org/diylc/components/electromechanical/CliffJack1_4.java index 528aef9c..cab17aef 100644 --- a/diylc/diylc-library/src/org/diylc/components/electromechanical/CliffJack1_4.java +++ b/diylc/diylc-library/src/org/diylc/components/electromechanical/CliffJack1_4.java @@ -53,7 +53,7 @@ import org.diylc.core.measures.Size; import org.diylc.core.measures.SizeUnit; import org.diylc.utils.Constants; -@ComponentDescriptor(name = "Cliff 1/4\" Jack", category = "Electromechanical", author = "Branislav Stojkovic", +@ComponentDescriptor(name = "Cliff 1/4\" Jack", category = "Electro-Mechanical", author = "Branislav Stojkovic", description = "Cliff-style closed panel mount 1/4\" phono jack", stretchable = false, zOrder = IDIYComponent.COMPONENT, instanceNamePrefix = "J", autoEdit = false, transformer = CliffJackTransformer.class) public class CliffJack1_4 extends AbstractTransparentComponent { diff --git a/diylc/diylc-library/src/org/diylc/components/electromechanical/ClosedJack1_4.java b/diylc/diylc-library/src/org/diylc/components/electromechanical/ClosedJack1_4.java index 59f6ef86..8702a4a3 100644 --- a/diylc/diylc-library/src/org/diylc/components/electromechanical/ClosedJack1_4.java +++ b/diylc/diylc-library/src/org/diylc/components/electromechanical/ClosedJack1_4.java @@ -53,7 +53,7 @@ import org.diylc.core.measures.Size; import org.diylc.core.measures.SizeUnit; import org.diylc.utils.Constants; -@ComponentDescriptor(name = "Closed 1/4\" Jack", category = "Electromechanical", author = "Branislav Stojkovic", +@ComponentDescriptor(name = "Closed 1/4\" Jack", category = "Electro-Mechanical", author = "Branislav Stojkovic", description = "Enclosed panel mount 1/4\" phono jack", stretchable = false, zOrder = IDIYComponent.COMPONENT, instanceNamePrefix = "J", autoEdit = false, transformer = ClosedJackTransformer.class) public class ClosedJack1_4 extends AbstractTransparentComponent { diff --git a/diylc/diylc-library/src/org/diylc/components/electromechanical/MiniRelay.java b/diylc/diylc-library/src/org/diylc/components/electromechanical/MiniRelay.java index 25aafa23..aac507a4 100644 --- a/diylc/diylc-library/src/org/diylc/components/electromechanical/MiniRelay.java +++ b/diylc/diylc-library/src/org/diylc/components/electromechanical/MiniRelay.java @@ -52,7 +52,7 @@ import org.diylc.core.measures.Voltage; import org.diylc.core.measures.VoltageUnit; import org.diylc.utils.Constants; -@ComponentDescriptor(name = "Mini Relay", author = "Branislav Stojkovic", category = "Electromechanical", +@ComponentDescriptor(name = "Mini Relay", author = "Branislav Stojkovic", category = "Electro-Mechanical", instanceNamePrefix = "RY", description = "Miniature PCB mount relay, like Omron G5V-1 or G5V-2", stretchable = false, zOrder = IDIYComponent.COMPONENT) public class MiniRelay extends AbstractTransparentComponent { diff --git a/diylc/diylc-library/src/org/diylc/components/electromechanical/MiniToggleSwitch.java b/diylc/diylc-library/src/org/diylc/components/electromechanical/MiniToggleSwitch.java index dd77418a..5a806f6d 100644 --- a/diylc/diylc-library/src/org/diylc/components/electromechanical/MiniToggleSwitch.java +++ b/diylc/diylc-library/src/org/diylc/components/electromechanical/MiniToggleSwitch.java @@ -48,7 +48,7 @@ import org.diylc.core.measures.Size; import org.diylc.core.measures.SizeUnit; import org.diylc.utils.Constants; -@ComponentDescriptor(name = "Mini Toggle Switch", category = "Electromechanical", author = "Branislav Stojkovic", +@ComponentDescriptor(name = "Mini Toggle Switch", category = "Electro-Mechanical", author = "Branislav Stojkovic", description = "Panel mounted mini toggle switch", stretchable = false, zOrder = IDIYComponent.COMPONENT, instanceNamePrefix = "SW", autoEdit = false) public class MiniToggleSwitch extends AbstractTransparentComponent { diff --git a/diylc/diylc-library/src/org/diylc/components/electromechanical/OpenJack1_4.java b/diylc/diylc-library/src/org/diylc/components/electromechanical/OpenJack1_4.java index b2c5af2a..96dec254 100644 --- a/diylc/diylc-library/src/org/diylc/components/electromechanical/OpenJack1_4.java +++ b/diylc/diylc-library/src/org/diylc/components/electromechanical/OpenJack1_4.java @@ -51,7 +51,7 @@ import org.diylc.core.measures.Size; import org.diylc.core.measures.SizeUnit; import org.diylc.utils.Constants; -@ComponentDescriptor(name = "Open 1/4\" Jack", category = "Electromechanical", author = "Branislav Stojkovic", +@ComponentDescriptor(name = "Open 1/4\" Jack", category = "Electro-Mechanical", author = "Branislav Stojkovic", description = "Switchcraft-style open panel mount 1/4\" phono jack, stereo and mono", stretchable = false, zOrder = IDIYComponent.COMPONENT, instanceNamePrefix = "J") public class OpenJack1_4 extends AbstractTransparentComponent { diff --git a/diylc/diylc-library/src/org/diylc/components/electromechanical/PlasticDCJack.java b/diylc/diylc-library/src/org/diylc/components/electromechanical/PlasticDCJack.java index 1b1589fd..6f720cb2 100644 --- a/diylc/diylc-library/src/org/diylc/components/electromechanical/PlasticDCJack.java +++ b/diylc/diylc-library/src/org/diylc/components/electromechanical/PlasticDCJack.java @@ -49,7 +49,7 @@ import org.diylc.core.measures.Size; import org.diylc.core.measures.SizeUnit; import org.diylc.utils.Constants; -@ComponentDescriptor(name = "Plastic DC Jack", category = "Electromechanical", author = "Branislav Stojkovic", +@ComponentDescriptor(name = "Plastic DC Jack", category = "Electro-Mechanical", author = "Branislav Stojkovic", description = "Panel mount plastic DC jack", stretchable = false, zOrder = IDIYComponent.COMPONENT, instanceNamePrefix = "J", autoEdit = false) public class PlasticDCJack extends AbstractTransparentComponent { diff --git a/diylc/diylc-library/src/org/diylc/components/semiconductors/DIL_IC.java b/diylc/diylc-library/src/org/diylc/components/semiconductors/DIL_IC.java index b83f4b11..ebaa3c8d 100644 --- a/diylc/diylc-library/src/org/diylc/components/semiconductors/DIL_IC.java +++ b/diylc/diylc-library/src/org/diylc/components/semiconductors/DIL_IC.java @@ -134,7 +134,7 @@ public class DIL_IC extends AbstractTransparentComponent { body = null; } - @EditableProperty(name = "Pin spacing") + @EditableProperty(name = "Pin Spacing") public Size getPinSpacing() { return pinSpacing; } @@ -146,7 +146,7 @@ public class DIL_IC extends AbstractTransparentComponent { body = null; } - @EditableProperty(name = "Row spacing") + @EditableProperty(name = "Row Spacing") public Size getRowSpacing() { return rowSpacing; } @@ -527,7 +527,7 @@ public class DIL_IC extends AbstractTransparentComponent { this.indentColor = indentColor; } - @EditableProperty(name = "Display pin numbers") + @EditableProperty(name = "Display Pin #s") public DisplayNumbers getDisplayNumbers() { return displayNumbers; } diff --git a/diylc/diylc-library/src/org/diylc/components/semiconductors/SIL_IC.java b/diylc/diylc-library/src/org/diylc/components/semiconductors/SIL_IC.java index 816890bc..b89ad001 100644 --- a/diylc/diylc-library/src/org/diylc/components/semiconductors/SIL_IC.java +++ b/diylc/diylc-library/src/org/diylc/components/semiconductors/SIL_IC.java @@ -131,7 +131,7 @@ public class SIL_IC extends AbstractTransparentComponent { body = null; } - @EditableProperty(name = "Pin spacing") + @EditableProperty(name = "Pin Spacing") public Size getPinSpacing() { return pinSpacing; } diff --git a/diylc/diylc-library/src/org/diylc/components/semiconductors/TransistorTO220.java b/diylc/diylc-library/src/org/diylc/components/semiconductors/TransistorTO220.java index 9501a2c4..ae2a4c68 100644 --- a/diylc/diylc-library/src/org/diylc/components/semiconductors/TransistorTO220.java +++ b/diylc/diylc-library/src/org/diylc/components/semiconductors/TransistorTO220.java @@ -463,7 +463,7 @@ public class TransistorTO220 extends AbstractTransparentComponent { this.body = null; } - @EditableProperty(name = "Lead length") + @EditableProperty(name = "Lead Length") public Size getLeadLength() { if (leadLength == null) { leadLength = LEAD_LENGTH; @@ -477,7 +477,7 @@ public class TransistorTO220 extends AbstractTransparentComponent { this.body = null; } - @EditableProperty(name = "Tab border") + @EditableProperty(name = "Tab Border") public Color getTabBorderColor() { return tabBorderColor; } diff --git a/diylc/diylc-library/src/org/diylc/components/tube/SubminiTube.java b/diylc/diylc-library/src/org/diylc/components/tube/SubminiTube.java new file mode 100644 index 00000000..629941cd --- /dev/null +++ b/diylc/diylc-library/src/org/diylc/components/tube/SubminiTube.java @@ -0,0 +1,623 @@ +/* + + DIY Layout Creator (DIYLC). + Copyright (c) 2009-2018 held jointly by the individual authors. + + This file is part of DIYLC. + + DIYLC is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + DIYLC is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with DIYLC. If not, see . + + */ +package org.diylc.components.tube; + +import java.awt.AlphaComposite; +import java.awt.Color; +import java.awt.Composite; +import java.awt.FontMetrics; +import java.awt.Graphics2D; +import java.awt.Point; +import java.awt.Rectangle; +import java.awt.Shape; +import java.awt.geom.Area; +import java.awt.geom.Ellipse2D; +import java.awt.geom.Rectangle2D; + +import org.diylc.appframework.miscutils.ConfigurationManager; +import org.diylc.common.Display; +import org.diylc.common.IPlugInPort; +import org.diylc.common.ObjectCache; +import org.diylc.common.Orientation; +import org.diylc.components.AbstractTransparentComponent; +import org.diylc.components.transform.TO220Transformer; +import org.diylc.core.ComponentState; +import org.diylc.core.IDIYComponent; +import org.diylc.core.IDrawingObserver; +import org.diylc.core.Project; +import org.diylc.core.Theme; +import org.diylc.core.VisibilityPolicy; +import org.diylc.core.annotations.ComponentDescriptor; +import org.diylc.core.annotations.EditableProperty; +import org.diylc.core.annotations.KeywordPolicy; +import org.diylc.core.measures.Size; +import org.diylc.core.measures.SizeUnit; +import org.diylc.utils.Constants; + +//@ComponentDescriptor(name = "Sub-Mini Tube", author = "Branislav Stojkovic", category = "Tubes", instanceNamePrefix = "V", description = "Sub-miniature (pencil) vacuum tube", stretchable = false, zOrder = IDIYComponent.COMPONENT, keywordPolicy = KeywordPolicy.SHOW_VALUE, transformer = TO220Transformer.class) +public class SubminiTube extends AbstractTransparentComponent { + + private static final long serialVersionUID = 1L; + + public static Color BODY_COLOR = Color.lightGray; + public static Color BORDER_COLOR = Color.gray; + public static Color PIN_COLOR = Color.decode("#00B2EE"); + public static Color PIN_BORDER_COLOR = PIN_COLOR.darker(); + public static Color LABEL_COLOR = Color.white; + public static Size PIN_SIZE = new Size(0.03d, SizeUnit.in); + public static Size PIN_SPACING = new Size(0.1d, SizeUnit.in); + public static Size BODY_WIDTH = new Size(0.4d, SizeUnit.in); + public static Size BODY_THICKNESS = new Size(4.5d, SizeUnit.mm); + public static Size BODY_HEIGHT = new Size(9d, SizeUnit.mm); + public static Size DIAMETER = new Size(0.4d, SizeUnit.in); + public static Size LENGTH = new Size(1.375d, SizeUnit.in); + public static Size LEAD_LENGTH = new Size(0.2d, SizeUnit.in); + public static Size LEAD_THICKNESS = new Size(0.8d, SizeUnit.mm); + + private String value = ""; + private Orientation orientation = Orientation.DEFAULT; + private Point[] controlPoints = new Point[] { new Point(0, 0), + new Point(0, 0), new Point(0, 0) }; + transient private Shape[] body; + private Color bodyColor = BODY_COLOR; + private Color borderColor = BORDER_COLOR; + private Display display = Display.NAME; + private boolean folded = false; + private Size leadLength = LEAD_LENGTH; + private PinArrangement leadArrangement = PinArrangement.Circular; + private boolean topLead = false; + private Size diameter = DIAMETER; + private Size length = LENGTH; + private PinCount pinCount = PinCount._8; + private Size leadSpacing = PIN_SPACING; + + public SubminiTube() { + super(); + updateControlPoints(); + } + + @EditableProperty + public String getValue() { + return value; + } + + public void setValue(String value) { + this.value = value; + } + + @EditableProperty + public Orientation getOrientation() { + return orientation; + } + + public void setOrientation(Orientation orientation) { + this.orientation = orientation; + updateControlPoints(); + // Reset body shape; + body = null; + } + + @Override + public int getControlPointCount() { + return controlPoints.length; + } + + @Override + public Point getControlPoint(int index) { + return controlPoints[index]; + } + + @Override + public boolean isControlPointSticky(int index) { + return true; + } + + @Override + public VisibilityPolicy getControlPointVisibilityPolicy(int index) { + return VisibilityPolicy.NEVER; + } + + @Override + public void setControlPoint(Point point, int index) { + controlPoints[index].setLocation(point); + body = null; + } + + private void updateControlPoints() { + int pinSpacing = (int) PIN_SPACING.convertToPixels(); + // Update control points. + int x = controlPoints[0].x; + int y = controlPoints[0].y; + int newPointCount = getPinCount().getValue(); + // Need a new array + if (newPointCount != controlPoints.length) { + controlPoints = new Point[newPointCount]; + for (int i = 0; i < controlPoints.length; i++) { + controlPoints[i] = new Point(x, y); + } + } + int dx; + int dy; + if (folded) { + switch (orientation) { + case DEFAULT: + dx = 0; + dy = pinSpacing; + break; + case _90: + dx = -pinSpacing; + dy = 0; + break; + case _180: + dx = 0; + dy = -pinSpacing; + break; + case _270: + dx = pinSpacing; + dy = 0; + break; + default: + throw new RuntimeException("Unexpected orientation: " + + orientation); + } + for (int i = 1; i < controlPoints.length; i++) { + controlPoints[i].setLocation(controlPoints[0].x + i * dx, controlPoints[0].y + i * dy); + } + } else { + switch (orientation) { + case DEFAULT: + controlPoints[1].setLocation(x, y + pinSpacing); + controlPoints[2].setLocation(x, y + 2 * pinSpacing); + break; + case _90: + controlPoints[1].setLocation(x - pinSpacing, y); + controlPoints[2].setLocation(x - 2 * pinSpacing, y); + break; + case _180: + controlPoints[1].setLocation(x, y - pinSpacing); + controlPoints[2].setLocation(x, y - 2 * pinSpacing); + break; + case _270: + controlPoints[1].setLocation(x + pinSpacing, y); + controlPoints[2].setLocation(x + 2 * pinSpacing, y); + break; + default: + throw new RuntimeException("Unexpected orientation: " + + orientation); + } + } + } + + public Shape[] getBody() { + if (body == null) { + body = new Shape[2]; + int x = controlPoints[0].x; + int y = controlPoints[0].y; + int pinSpacing = (int) PIN_SPACING.convertToPixels(); + int bodyWidth = getClosestOdd(BODY_WIDTH.convertToPixels()); + int bodyThickness = getClosestOdd(BODY_THICKNESS.convertToPixels()); + int bodyHeight = getClosestOdd(BODY_HEIGHT.convertToPixels()); + int tabThickness = 0; // (int) TAB_THICKNESS.convertToPixels(); + int tabHeight = 0;// (int) TAB_HEIGHT.convertToPixels(); + int tabHoleDiameter = 0;// (int) + // TAB_HOLE_DIAMETER.convertToPixels(); + double leadLength = getLeadLength().convertToPixels(); + + switch (orientation) { + case DEFAULT: + if (folded) { + body[0] = new Rectangle2D.Double(x + leadLength, y + + pinSpacing - bodyWidth / 2, bodyHeight, bodyWidth); + body[1] = new Area(new Rectangle2D.Double(x + leadLength + + bodyHeight, y + pinSpacing - bodyWidth / 2, + tabHeight, bodyWidth)); + ((Area) body[1]).subtract(new Area(new Ellipse2D.Double(x + + leadLength + bodyHeight + tabHeight / 2 + - tabHoleDiameter / 2, y + pinSpacing + - tabHoleDiameter / 2, tabHoleDiameter, + tabHoleDiameter))); + } else { + body[0] = new Rectangle2D.Double(x - bodyThickness / 2, y + + pinSpacing - bodyWidth / 2, bodyThickness, + bodyWidth); + body[1] = new Rectangle2D.Double(x + bodyThickness / 2 + - tabThickness, y + pinSpacing - bodyWidth / 2, + tabThickness, bodyWidth); + } + break; + case _90: + if (folded) { + body[0] = new Rectangle2D.Double(x - pinSpacing - bodyWidth + / 2, y + leadLength, bodyWidth, bodyHeight); + body[1] = new Area(new Rectangle2D.Double(x - pinSpacing + - bodyWidth / 2, y + leadLength + bodyHeight, + bodyWidth, tabHeight)); + ((Area) body[1]).subtract(new Area(new Ellipse2D.Double(x + - pinSpacing - tabHoleDiameter / 2, y + leadLength + + bodyHeight + tabHeight / 2 - tabHoleDiameter / 2, + tabHoleDiameter, tabHoleDiameter))); + } else { + body[0] = new Rectangle2D.Double(x - pinSpacing - bodyWidth + / 2, y - bodyThickness / 2, bodyWidth, + bodyThickness); + body[1] = new Rectangle2D.Double(x - pinSpacing - bodyWidth + / 2, y + bodyThickness / 2 - tabThickness, + bodyWidth, tabThickness); + } + break; + case _180: + if (folded) { + body[0] = new Rectangle2D.Double(x - leadLength + - bodyHeight, y - pinSpacing - bodyWidth / 2, + bodyHeight, bodyWidth); + body[1] = new Area(new Rectangle2D.Double(x - leadLength + - bodyHeight - tabHeight, y - pinSpacing + - bodyWidth / 2, tabHeight, bodyWidth)); + ((Area) body[1]).subtract(new Area(new Ellipse2D.Double(x + - leadLength - bodyHeight - tabHeight / 2 + - tabHoleDiameter / 2, y - pinSpacing + - tabHoleDiameter / 2, tabHoleDiameter, + tabHoleDiameter))); + } else { + body[0] = new Rectangle2D.Double(x - bodyThickness / 2, y + - pinSpacing - bodyWidth / 2, bodyThickness, + bodyWidth); + body[1] = new Rectangle2D.Double(x - bodyThickness / 2, y + - pinSpacing - bodyWidth / 2, tabThickness, + bodyWidth); + } + break; + case _270: + if (folded) { + body[0] = new Rectangle2D.Double(x + pinSpacing - bodyWidth + / 2, y - leadLength - bodyHeight, bodyWidth, + bodyHeight); + body[1] = new Area(new Rectangle2D.Double(x + pinSpacing + - bodyWidth / 2, y - leadLength - bodyHeight + - tabHeight, bodyWidth, tabHeight)); + ((Area) body[1]).subtract(new Area(new Ellipse2D.Double(x + + pinSpacing - tabHoleDiameter / 2, y - leadLength + - bodyHeight - tabHeight / 2 - tabHoleDiameter / 2, + tabHoleDiameter, tabHoleDiameter))); + } else { + body[0] = new Rectangle2D.Double(x + pinSpacing - bodyWidth + / 2, y - bodyThickness / 2, bodyWidth, + bodyThickness); + body[1] = new Rectangle2D.Double(x + pinSpacing - bodyWidth + / 2, y - bodyThickness / 2, bodyWidth, tabThickness); + } + break; + default: + throw new RuntimeException("Unexpected orientation: " + + orientation); + } + } + return body; + } + + @Override + public void draw(Graphics2D g2d, ComponentState componentState, + boolean outlineMode, Project project, + IDrawingObserver drawingObserver) { + if (checkPointsClipped(g2d.getClip())) { + return; + } + int pinSize = (int) PIN_SIZE.convertToPixels() / 2 * 2; + Shape mainArea = getBody()[0]; + Shape tabArea = getBody()[1]; + Composite oldComposite = g2d.getComposite(); + if (alpha < MAX_ALPHA) { + g2d.setComposite(AlphaComposite.getInstance( + AlphaComposite.SRC_OVER, 1f * alpha / MAX_ALPHA)); + } + g2d.setColor(outlineMode ? Constants.TRANSPARENT_COLOR : bodyColor); + g2d.fill(mainArea); + + Theme theme = (Theme) ConfigurationManager.getInstance().readObject( + IPlugInPort.THEME_KEY, Constants.DEFAULT_THEME); + + // Draw pins. + + if (folded) { + int leadThickness = getClosestOdd(LEAD_THICKNESS.convertToPixels()); + int leadLength = (int) getLeadLength().convertToPixels(); + Color finalPinColor; + Color finalPinBorderColor; + if (outlineMode) { + finalPinColor = new Color(0, 0, 0, 0); + finalPinBorderColor = componentState == ComponentState.SELECTED + || componentState == ComponentState.DRAGGING ? SELECTION_COLOR + : theme.getOutlineColor(); + } else { + finalPinColor = METAL_COLOR; + finalPinBorderColor = METAL_COLOR.darker(); + } + for (Point point : controlPoints) { + switch (orientation) { + case DEFAULT: + g2d.setStroke(ObjectCache.getInstance().fetchBasicStroke( + leadThickness)); + g2d.setColor(finalPinBorderColor); + g2d.drawLine(point.x, point.y, point.x + leadLength + - leadThickness / 2, point.y); + g2d.setStroke(ObjectCache.getInstance().fetchBasicStroke( + leadThickness - 2)); + g2d.setColor(finalPinColor); + g2d.drawLine(point.x, point.y, point.x + leadLength + - leadThickness / 2, point.y); + break; + case _90: + g2d.setStroke(ObjectCache.getInstance().fetchBasicStroke( + leadThickness)); + g2d.setColor(finalPinBorderColor); + g2d.drawLine(point.x, point.y, point.x, point.y + + leadLength - leadThickness / 2); + g2d.setStroke(ObjectCache.getInstance().fetchBasicStroke( + leadThickness - 2)); + g2d.setColor(finalPinColor); + g2d.drawLine(point.x, point.y, point.x, point.y + + leadLength - leadThickness / 2); + break; + case _180: + g2d.setStroke(ObjectCache.getInstance().fetchBasicStroke( + leadThickness)); + g2d.setColor(finalPinBorderColor); + g2d.drawLine(point.x, point.y, point.x - leadLength + - leadThickness / 2, point.y); + g2d.setStroke(ObjectCache.getInstance().fetchBasicStroke( + leadThickness - 2)); + g2d.setColor(finalPinColor); + g2d.drawLine(point.x, point.y, point.x - leadLength + - leadThickness / 2, point.y); + break; + case _270: + g2d.setStroke(ObjectCache.getInstance().fetchBasicStroke( + leadThickness)); + g2d.setColor(finalPinBorderColor); + g2d.drawLine(point.x, point.y, point.x, point.y + - leadLength); + g2d.setStroke(ObjectCache.getInstance().fetchBasicStroke( + leadThickness - 2)); + g2d.setColor(finalPinColor); + g2d.drawLine(point.x, point.y, point.x, point.y + - leadLength); + break; + } + } + } else { + if (!outlineMode) { + for (Point point : controlPoints) { + + g2d.setColor(PIN_COLOR); + g2d.fillOval(point.x - pinSize / 2, point.y - pinSize / 2, + pinSize, pinSize); + g2d.setColor(outlineMode ? theme.getOutlineColor() + : PIN_BORDER_COLOR); + g2d.drawOval(point.x - pinSize / 2, point.y - pinSize / 2, + pinSize, pinSize); + } + } + } + + // Draw label. + g2d.setFont(project.getFont()); + Color finalLabelColor; + if (outlineMode) { + finalLabelColor = componentState == ComponentState.SELECTED + || componentState == ComponentState.DRAGGING ? LABEL_COLOR_SELECTED + : theme.getOutlineColor(); + } else { + finalLabelColor = componentState == ComponentState.SELECTED + || componentState == ComponentState.DRAGGING ? LABEL_COLOR_SELECTED + : LABEL_COLOR; + } + g2d.setColor(finalLabelColor); + String label = ""; + label = (getDisplay() == Display.NAME) ? getName() : getValue(); + if (getDisplay() == Display.NONE) { + label = ""; + } + if (getDisplay() == Display.BOTH) { + label = getName() + " " + + (getValue() == null ? "" : getValue().toString()); + } + FontMetrics fontMetrics = g2d.getFontMetrics(g2d.getFont()); + Rectangle2D rect = fontMetrics.getStringBounds(label, g2d); + int textHeight = (int) (rect.getHeight()); + int textWidth = (int) (rect.getWidth()); + // Center text horizontally and vertically + Rectangle bounds = mainArea.getBounds(); + int x = bounds.x + (bounds.width - textWidth) / 2; + int y = bounds.y + (bounds.height - textHeight) / 2 + + fontMetrics.getAscent(); + g2d.drawString(label, x, y); + } + + @Override + public void drawIcon(Graphics2D g2d, int width, int height) { + int margin = 2 * width / 32; + int bodySize = width * 5 / 10; + int tabSize = bodySize * 6 / 10; + int holeSize = 5 * width / 32; + Area a = new Area(new Rectangle2D.Double((width - bodySize) / 2, + margin, bodySize, tabSize)); + a.subtract(new Area(new Ellipse2D.Double(width / 2 - holeSize / 2, + margin + tabSize / 2 - holeSize / 2, holeSize, holeSize))); + g2d.setColor(BORDER_COLOR); + g2d.draw(a); + g2d.setColor(BODY_COLOR); + g2d.fillRect((width - bodySize) / 2, margin + tabSize, bodySize, + bodySize); + g2d.setColor(BORDER_COLOR); + g2d.drawRect((width - bodySize) / 2, margin + tabSize, bodySize, + bodySize); + g2d.setColor(METAL_COLOR); + g2d.setStroke(ObjectCache.getInstance().fetchBasicStroke(2)); + g2d.drawLine(width / 2, margin + tabSize + bodySize, width / 2, height + - margin); + g2d.drawLine(width / 2 - bodySize / 3, margin + tabSize + bodySize, + width / 2 - bodySize / 3, height - margin); + g2d.drawLine(width / 2 + bodySize / 3, margin + tabSize + bodySize, + width / 2 + bodySize / 3, height - margin); + } + + @EditableProperty(name = "Body") + public Color getBodyColor() { + return bodyColor; + } + + public void setBodyColor(Color bodyColor) { + this.bodyColor = bodyColor; + } + + @EditableProperty(name = "Border") + public Color getBorderColor() { + return borderColor; + } + + public void setBorderColor(Color borderColor) { + this.borderColor = borderColor; + } + + @EditableProperty + public boolean getFolded() { + return folded; + } + + public void setFolded(boolean folded) { + this.folded = folded; + // Invalidate the body + this.body = null; + } + + @EditableProperty(name = "Lead Length") + public Size getLeadLength() { + if (leadLength == null) { + leadLength = LEAD_LENGTH; + } + return leadLength; + } + + public void setLeadLength(Size leadLength) { + this.leadLength = leadLength; + // Invalidate the body + this.body = null; + } + + @EditableProperty + public Display getDisplay() { + if (display == null) { + display = Display.NAME; + } + return display; + } + + public void setDisplay(Display display) { + this.display = display; + } + + @EditableProperty(name = "Pin Arrangement") + public PinArrangement getPinArrangement() { + return leadArrangement; + } + + public void setPinArrangement(PinArrangement pinArrangement) { + this.leadArrangement = pinArrangement; + } + + @EditableProperty(name = "Top Lead") + public boolean getTopLead() { + return topLead; + } + + public void setTopLead(boolean topLead) { + this.topLead = topLead; + updateControlPoints(); + } + + @EditableProperty + public Size getDiameter() { + return diameter; + } + + public void setDiameter(Size diameter) { + this.diameter = diameter; + updateControlPoints(); + } + + @EditableProperty + public Size getLength() { + return length; + } + + public void setLength(Size length) { + this.length = length; + } + + @EditableProperty(name = "Lead Count") + public PinCount getPinCount() { + return pinCount; + } + + public void setPinCount(PinCount pinCount) { + this.pinCount = pinCount; + updateControlPoints(); + } + + @EditableProperty(name = "Lead Spacing") + public Size getLeadSpacing() { + return leadSpacing; + } + + public void setLeadSpacing(Size leadSpacing) { + this.leadSpacing = leadSpacing; + updateControlPoints(); + } + + public static enum PinArrangement { + Inline("In-line"), Circular("Circular"); + + private String label; + + private PinArrangement(String label) { + this.label = label; + } + + @Override + public String toString() { + return label; + } + } + + public static enum PinCount { + _3, _4, _5, _6, _7, _8, _9, _10; + + @Override + public String toString() { + return name().replace("_", ""); + } + + public int getValue() { + return Integer.parseInt(toString()); + } + } +} diff --git a/diylc/diylc-swing/lib/diylc-core.jar b/diylc/diylc-swing/lib/diylc-core.jar index 6e599bcf..5c31a81b 100644 Binary files a/diylc/diylc-swing/lib/diylc-core.jar and b/diylc/diylc-swing/lib/diylc-core.jar differ diff --git a/diylc/diylc-swing/library/main.jar b/diylc/diylc-swing/library/main.jar index babd4529..39a4e75f 100644 Binary files a/diylc/diylc-swing/library/main.jar and b/diylc/diylc-swing/library/main.jar differ diff --git a/diylc/diylc-swing/src/org/diylc/swing/ActionFactory.java b/diylc/diylc-swing/src/org/diylc/swing/ActionFactory.java index 204388b0..c30cd548 100644 --- a/diylc/diylc-swing/src/org/diylc/swing/ActionFactory.java +++ b/diylc/diylc-swing/src/org/diylc/swing/ActionFactory.java @@ -1,1280 +1,1280 @@ -/* - * - * DIY Layout Creator (DIYLC). Copyright (c) 2009-2018 held jointly by the individual authors. - * - * This file is part of DIYLC. - * - * DIYLC is free software: you can redistribute it and/or modify it under the terms of the GNU - * General Public License as published by the Free Software Foundation, either version 3 of the - * License, or (at your option) any later version. - * - * DIYLC is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even - * the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General - * Public License for more details. - * - * You should have received a copy of the GNU General Public License along with DIYLC. If not, see - * . - */ -package org.diylc.swing; - -import java.awt.Toolkit; -import java.awt.datatransfer.Clipboard; -import java.awt.datatransfer.ClipboardOwner; -import java.awt.event.ActionEvent; -import java.awt.event.KeyEvent; -import java.awt.print.PrinterException; -import java.io.File; -import java.util.ArrayList; -import java.util.Collection; -import java.util.List; -import java.util.Set; - -import javax.swing.AbstractAction; -import javax.swing.JOptionPane; -import javax.swing.KeyStroke; - -import org.apache.log4j.Logger; -import org.diylc.appframework.miscutils.ConfigurationManager; -import org.diylc.common.IComponentTransformer; -import org.diylc.common.IPlugInPort; -import org.diylc.common.ITask; -import org.diylc.common.PropertyWrapper; -import org.diylc.core.ExpansionMode; -import org.diylc.core.IDIYComponent; -import org.diylc.core.IView; -import org.diylc.core.Project; -import org.diylc.core.Theme; -import org.diylc.core.measures.Nudge; -import org.diylc.core.measures.Size; -import org.diylc.core.measures.SizeUnit; -import org.diylc.images.IconLoader; -import org.diylc.presenter.Presenter; -import org.diylc.swing.gui.DialogFactory; -import org.diylc.swing.gui.editor.PropertyEditorDialog; -import org.diylc.swing.plugins.config.ConfigPlugin; -import org.diylc.swing.plugins.edit.ComponentTransferable; -import org.diylc.swing.plugins.file.BomDialog; -import org.diylc.swing.plugins.file.FileFilterEnum; -import org.diylc.swingframework.ButtonDialog; -import org.diylc.swingframework.IDrawingProvider; -import org.diylc.swingframework.export.DrawingExporter; -import org.diylc.utils.BomEntry; - -public class ActionFactory { - - private static final Logger LOG = Logger.getLogger(ActionFactory.class); - - private static ActionFactory instance; - - public static ActionFactory getInstance() { - if (instance == null) { - instance = new ActionFactory(); - } - return instance; - } - - private ActionFactory() {} - - // File menu actions. - - public NewAction createNewAction(IPlugInPort plugInPort) { - return new NewAction(plugInPort); - } - - public OpenAction createOpenAction(IPlugInPort plugInPort, ISwingUI swingUI) { - return new OpenAction(plugInPort, swingUI); - } - - public ImportAction createImportAction(IPlugInPort plugInPort, ISwingUI swingUI) { - return new ImportAction(plugInPort, swingUI); - } - - public SaveAction createSaveAction(IPlugInPort plugInPort, ISwingUI swingUI) { - return new SaveAction(plugInPort, swingUI); - } - - public SaveAsAction createSaveAsAction(IPlugInPort plugInPort, ISwingUI swingUI) { - return new SaveAsAction(plugInPort, swingUI); - } - - public CreateBomAction createBomAction(IPlugInPort plugInPort) { - return new CreateBomAction(plugInPort); - } - - public ExportPDFAction createExportPDFAction(IPlugInPort plugInPort, IDrawingProvider drawingProvider, ISwingUI swingUI, String defaultSuffix) { - return new ExportPDFAction(plugInPort, drawingProvider, swingUI, defaultSuffix); - } - - public ExportPNGAction createExportPNGAction(IPlugInPort plugInPort, IDrawingProvider drawingProvider, ISwingUI swingUI, String defaultSuffix) { - return new ExportPNGAction(plugInPort, drawingProvider, swingUI, defaultSuffix); - } - - public PrintAction createPrintAction(IDrawingProvider drawingProvider, int keyModifiers) { - return new PrintAction(drawingProvider, keyModifiers); - } - - public ExitAction createExitAction(IPlugInPort plugInPort) { - return new ExitAction(plugInPort); - } - - // Edit menu actions. - - public CutAction createCutAction(IPlugInPort plugInPort, Clipboard clipboard, ClipboardOwner clipboardOwner) { - return new CutAction(plugInPort, clipboard, clipboardOwner); - } - - public CopyAction createCopyAction(IPlugInPort plugInPort, Clipboard clipboard, ClipboardOwner clipboardOwner) { - return new CopyAction(plugInPort, clipboard, clipboardOwner); - } - - public PasteAction createPasteAction(IPlugInPort plugInPort, Clipboard clipboard) { - return new PasteAction(plugInPort, clipboard); - } - - public DuplicateAction createDuplicateAction(IPlugInPort plugInPort) { - return new DuplicateAction(plugInPort); - } - - public SelectAllAction createSelectAllAction(IPlugInPort plugInPort) { - return new SelectAllAction(plugInPort); - } - - public GroupAction createGroupAction(IPlugInPort plugInPort) { - return new GroupAction(plugInPort); - } - - public UngroupAction createUngroupAction(IPlugInPort plugInPort) { - return new UngroupAction(plugInPort); - } - - public EditProjectAction createEditProjectAction(IPlugInPort plugInPort) { - return new EditProjectAction(plugInPort); - } - - public EditSelectionAction createEditSelectionAction(IPlugInPort plugInPort) { - return new EditSelectionAction(plugInPort); - } - - public DeleteSelectionAction createDeleteSelectionAction(IPlugInPort plugInPort) { - return new DeleteSelectionAction(plugInPort); - } - - public SaveAsTemplateAction createSaveAsTemplateAction(IPlugInPort plugInPort) { - return new SaveAsTemplateAction(plugInPort); - } - - public SaveAsBlockAction createSaveAsBlockAction(IPlugInPort plugInPort) { - return new SaveAsBlockAction(plugInPort); - } - - public ExpandSelectionAction createExpandSelectionAction(IPlugInPort plugInPort, ExpansionMode expansionMode) { - return new ExpandSelectionAction(plugInPort, expansionMode); - } - - public RotateSelectionAction createRotateSelectionAction(IPlugInPort plugInPort, int direction) { - return new RotateSelectionAction(plugInPort, direction); - } - - public MirrorSelectionAction createMirrorSelectionAction(IPlugInPort plugInPort, int direction) { - return new MirrorSelectionAction(plugInPort, direction); - } - - public SendToBackAction createSendToBackAction(IPlugInPort plugInPort) { - return new SendToBackAction(plugInPort); - } - - public BringToFrontAction createBringToFrontAction(IPlugInPort plugInPort) { - return new BringToFrontAction(plugInPort); - } - - public NudgeAction createNudgeAction(IPlugInPort plugInPort) { - return new NudgeAction(plugInPort); - } - - // Config actions. - - public ConfigAction createConfigAction(IPlugInPort plugInPort, String title, String configKey, boolean defaultValue) { - return new ConfigAction(plugInPort, title, configKey, defaultValue); - } - - public ConfigAction createConfigAction(IPlugInPort plugInPort, String title, String configKey, boolean defaultValue, - String tipKey) { - return new ConfigAction(plugInPort, title, configKey, defaultValue, tipKey); - } - - public ThemeAction createThemeAction(IPlugInPort plugInPort, Theme theme) { - return new ThemeAction(plugInPort, theme); - } - - public ComponentBrowserAction createComponentBrowserAction(String browserType) { - return new ComponentBrowserAction(browserType); - } - - public RenumberAction createRenumberAction(IPlugInPort plugInPort, boolean xAxisFirst) { - return new RenumberAction(plugInPort, xAxisFirst); - } - - // File menu actions. - - public static class NewAction extends AbstractAction { - - private static final long serialVersionUID = 1L; - - private IPlugInPort plugInPort; - - public NewAction(IPlugInPort plugInPort) { - super(); - this.plugInPort = plugInPort; - putValue(AbstractAction.NAME, "New"); - putValue(AbstractAction.ACCELERATOR_KEY, - KeyStroke.getKeyStroke(KeyEvent.VK_N, Toolkit.getDefaultToolkit().getMenuShortcutKeyMask())); - putValue(AbstractAction.SMALL_ICON, IconLoader.DocumentPlain.getIcon()); - } - - @Override - public void actionPerformed(ActionEvent e) { - LOG.info("NewAction triggered"); - if (!plugInPort.allowFileAction()) { - return; - } - plugInPort.createNewProject(); - List properties = plugInPort.getProperties(plugInPort.getCurrentProject()); - PropertyEditorDialog editor = - DialogFactory.getInstance().createPropertyEditorDialog(properties, "Edit Project", true); - editor.setVisible(true); - if (ButtonDialog.OK.equals(editor.getSelectedButtonCaption())) { - plugInPort.applyProperties(plugInPort.getCurrentProject(), properties); - } - // Save default values. - for (PropertyWrapper property : editor.getDefaultedProperties()) { - if (property.getValue() != null) { - plugInPort.setDefaultPropertyValue(Project.class, property.getName(), property.getValue()); - } - } - } - } - - public static class OpenAction extends AbstractAction { - - private static final long serialVersionUID = 1L; - - private IPlugInPort plugInPort; - private ISwingUI swingUI; - - public OpenAction(IPlugInPort plugInPort, ISwingUI swingUI) { - super(); - this.plugInPort = plugInPort; - this.swingUI = swingUI; - putValue(AbstractAction.NAME, "Open"); - putValue(AbstractAction.ACCELERATOR_KEY, - KeyStroke.getKeyStroke(KeyEvent.VK_O, Toolkit.getDefaultToolkit().getMenuShortcutKeyMask())); - putValue(AbstractAction.SMALL_ICON, IconLoader.FolderOut.getIcon()); - } - - @Override - public void actionPerformed(ActionEvent e) { - LOG.info("OpenAction triggered"); - if (!plugInPort.allowFileAction()) { - return; - } - final File file = - DialogFactory.getInstance().showOpenDialog(FileFilterEnum.DIY.getFilter(), null, - FileFilterEnum.DIY.getExtensions()[0], null); - if (file != null) { - swingUI.executeBackgroundTask(new ITask() { - - @Override - public Void doInBackground() throws Exception { - LOG.debug("Opening from " + file.getAbsolutePath()); - plugInPort.loadProjectFromFile(file.getAbsolutePath()); - return null; - } - - @Override - public void complete(Void result) {} - - @Override - public void failed(Exception e) { - swingUI.showMessage("Could not open file. " + e.getMessage(), "Error", ISwingUI.ERROR_MESSAGE); - } - }, true); - } - } - } - - public static class ImportAction extends AbstractAction { - - private static final long serialVersionUID = 1L; - - private IPlugInPort plugInPort; - private ISwingUI swingUI; - private Presenter presenter; - - public ImportAction(IPlugInPort plugInPort, ISwingUI swingUI) { - super(); - this.plugInPort = plugInPort; - this.swingUI = swingUI; - this.presenter = new Presenter(new IView() { - - @Override - public int showConfirmDialog(String message, String title, int optionType, int messageType) { - return JOptionPane.showConfirmDialog(null, message, title, optionType, messageType); - } - - @Override - public void showMessage(String message, String title, int messageType) { - JOptionPane.showMessageDialog(null, message, title, messageType); - } - - @Override - public File promptFileSave() { - return null; - } - - @Override - public boolean editProperties(List properties, Set defaultedProperties) { - return false; - } - }); - putValue(AbstractAction.NAME, "Import"); - putValue(AbstractAction.ACCELERATOR_KEY, - KeyStroke.getKeyStroke(KeyEvent.VK_I, Toolkit.getDefaultToolkit().getMenuShortcutKeyMask())); - putValue(AbstractAction.SMALL_ICON, IconLoader.ElementInto.getIcon()); - } - - @Override - public void actionPerformed(ActionEvent e) { - LOG.info("ImportAction triggered"); - - final File file = - DialogFactory.getInstance().showOpenDialog(FileFilterEnum.DIY.getFilter(), null, - FileFilterEnum.DIY.getExtensions()[0], null); - if (file != null) { - swingUI.executeBackgroundTask(new ITask() { - - @Override - public Void doInBackground() throws Exception { - LOG.debug("Opening from " + file.getAbsolutePath()); - // Load project in temp presenter - presenter.loadProjectFromFile(file.getAbsolutePath()); - // Grab all components and paste them into the main - // presenter - plugInPort.pasteComponents(presenter.getCurrentProject().getComponents()); - // Cleanup components in the temp presenter, don't need - // them anymore - presenter.selectAll(0); - presenter.deleteSelectedComponents(); - return null; - } - - @Override - public void complete(Void result) {} - - @Override - public void failed(Exception e) { - swingUI.showMessage("Could not open file. " + e.getMessage(), "Error", ISwingUI.ERROR_MESSAGE); - } - }, true); - } - } - } - - public static class SaveAction extends AbstractAction { - - private static final long serialVersionUID = 1L; - - private IPlugInPort plugInPort; - private ISwingUI swingUI; - - public SaveAction(IPlugInPort plugInPort, ISwingUI swingUI) { - super(); - this.plugInPort = plugInPort; - this.swingUI = swingUI; - putValue(AbstractAction.NAME, "Save"); - putValue(AbstractAction.ACCELERATOR_KEY, - KeyStroke.getKeyStroke(KeyEvent.VK_S, Toolkit.getDefaultToolkit().getMenuShortcutKeyMask())); - putValue(AbstractAction.SMALL_ICON, IconLoader.DiskBlue.getIcon()); - } - - @Override - public void actionPerformed(ActionEvent e) { - LOG.info("SaveAction triggered"); - if (plugInPort.getCurrentFileName() == null) { - final File file = - DialogFactory.getInstance().showSaveDialog(swingUI.getOwnerFrame(), FileFilterEnum.DIY.getFilter(), null, - FileFilterEnum.DIY.getExtensions()[0], null); - if (file != null) { - swingUI.executeBackgroundTask(new ITask() { - - @Override - public Void doInBackground() throws Exception { - LOG.debug("Saving to " + file.getAbsolutePath()); - plugInPort.saveProjectToFile(file.getAbsolutePath(), false); - return null; - } - - @Override - public void complete(Void result) {} - - @Override - public void failed(Exception e) { - swingUI.showMessage("Could not save to file. " + e.getMessage(), "Error", ISwingUI.ERROR_MESSAGE); - } - }, true); - } - } else { - swingUI.executeBackgroundTask(new ITask() { - - @Override - public Void doInBackground() throws Exception { - LOG.debug("Saving to " + plugInPort.getCurrentFileName()); - plugInPort.saveProjectToFile(plugInPort.getCurrentFileName(), false); - return null; - } - - @Override - public void complete(Void result) {} - - @Override - public void failed(Exception e) { - swingUI.showMessage("Could not save to file. " + e.getMessage(), "Error", ISwingUI.ERROR_MESSAGE); - } - }, true); - } - } - } - - public static class SaveAsAction extends AbstractAction { - - private static final long serialVersionUID = 1L; - - private IPlugInPort plugInPort; - private ISwingUI swingUI; - - public SaveAsAction(IPlugInPort plugInPort, ISwingUI swingUI) { - super(); - this.plugInPort = plugInPort; - this.swingUI = swingUI; - putValue(AbstractAction.NAME, "Save As"); - putValue( - AbstractAction.ACCELERATOR_KEY, - KeyStroke.getKeyStroke(KeyEvent.VK_S, Toolkit.getDefaultToolkit().getMenuShortcutKeyMask() - | ActionEvent.SHIFT_MASK)); - putValue(AbstractAction.SMALL_ICON, IconLoader.DiskBlue.getIcon()); - } - - @Override - public void actionPerformed(ActionEvent e) { - LOG.info("SaveAsAction triggered"); - final File file = - DialogFactory.getInstance().showSaveDialog(swingUI.getOwnerFrame(), FileFilterEnum.DIY.getFilter(), null, - FileFilterEnum.DIY.getExtensions()[0], null); - if (file != null) { - swingUI.executeBackgroundTask(new ITask() { - - @Override - public Void doInBackground() throws Exception { - LOG.debug("Saving to " + file.getAbsolutePath()); - plugInPort.saveProjectToFile(file.getAbsolutePath(), false); - return null; - } - - @Override - public void complete(Void result) {} - - @Override - public void failed(Exception e) { - swingUI.showMessage("Could not save to file. " + e.getMessage(), "Error", ISwingUI.ERROR_MESSAGE); - } - }, true); - } - } - } - - public static class CreateBomAction extends AbstractAction { - - private static final long serialVersionUID = 1L; - - private IPlugInPort plugInPort; - - public CreateBomAction(IPlugInPort plugInPort) { - super(); - this.plugInPort = plugInPort; - putValue(AbstractAction.NAME, "Create B.O.M."); - putValue(AbstractAction.SMALL_ICON, IconLoader.BOM.getIcon()); - } - - @Override - public void actionPerformed(ActionEvent e) { - LOG.info("CreateBomAction triggered"); - List bom = - org.diylc.utils.BomMaker.getInstance().createBom(plugInPort.getCurrentProject().getComponents()); - - String initialFileName = null; - String currentFile = plugInPort.getCurrentFileName(); - if (currentFile != null) { - File cFile = new File(currentFile); - initialFileName = cFile.getName().replaceAll("(?i)\\.diy", "") + " BOM"; - } - - BomDialog dialog = DialogFactory.getInstance().createBomDialog(bom, initialFileName); - dialog.setVisible(true); - } - } - - public static class ExportPDFAction extends AbstractAction { - - private static final long serialVersionUID = 1L; - - private IDrawingProvider drawingProvider; - private ISwingUI swingUI; - private IPlugInPort plugInPort; - private String defaultSuffix; - - public ExportPDFAction(IPlugInPort plugInPort, IDrawingProvider drawingProvider, ISwingUI swingUI, String defaultSuffix) { - super(); - this.plugInPort = plugInPort; - this.drawingProvider = drawingProvider; - this.swingUI = swingUI; - this.defaultSuffix = defaultSuffix; - putValue(AbstractAction.NAME, "Export to PDF"); - putValue(AbstractAction.SMALL_ICON, IconLoader.PDF.getIcon()); - } - - @Override - public void actionPerformed(ActionEvent e) { - LOG.info("ExportPDFAction triggered"); - - File initialFile = null; - String currentFile = plugInPort.getCurrentFileName(); - if (currentFile != null) { - File cFile = new File(currentFile); - initialFile = new File(cFile.getName().replaceAll("(?i)\\.diy", "") + defaultSuffix + ".pdf"); - } - - final File file = - DialogFactory.getInstance().showSaveDialog(swingUI.getOwnerFrame(), FileFilterEnum.PDF.getFilter(), initialFile, - FileFilterEnum.PDF.getExtensions()[0], null); - if (file != null) { - swingUI.executeBackgroundTask(new ITask() { - - @Override - public Void doInBackground() throws Exception { - LOG.debug("Exporting to " + file.getAbsolutePath()); - DrawingExporter.getInstance().exportPDF(ExportPDFAction.this.drawingProvider, file); - return null; - } - - @Override - public void complete(Void result) {} - - @Override - public void failed(Exception e) { - swingUI.showMessage("Could not export to PDF. " + e.getMessage(), "Error", ISwingUI.ERROR_MESSAGE); - } - }, true); - } - } - } - - public static class ExportPNGAction extends AbstractAction { - - private static final long serialVersionUID = 1L; - - private IDrawingProvider drawingProvider; - private ISwingUI swingUI; - private IPlugInPort plugInPort; - private String defaultSuffix; - - public ExportPNGAction(IPlugInPort plugInPort, IDrawingProvider drawingProvider, ISwingUI swingUI, String defaultSuffix) { - super(); - this.plugInPort = plugInPort; - this.drawingProvider = drawingProvider; - this.drawingProvider = drawingProvider; - this.swingUI = swingUI; - this.defaultSuffix = defaultSuffix; - putValue(AbstractAction.NAME, "Export to PNG"); - putValue(AbstractAction.SMALL_ICON, IconLoader.Image.getIcon()); - } - - @Override - public void actionPerformed(ActionEvent e) { - LOG.info("ExportPNGAction triggered"); - - File initialFile = null; - String currentFile = plugInPort.getCurrentFileName(); - if (currentFile != null) { - File cFile = new File(currentFile); - initialFile = new File(cFile.getName().replaceAll("(?i)\\.diy", "") + defaultSuffix + ".png"); - } - - final File file = - DialogFactory.getInstance().showSaveDialog(swingUI.getOwnerFrame(), FileFilterEnum.PNG.getFilter(), initialFile, - FileFilterEnum.PNG.getExtensions()[0], null); - if (file != null) { - swingUI.executeBackgroundTask(new ITask() { - - @Override - public Void doInBackground() throws Exception { - LOG.debug("Exporting to " + file.getAbsolutePath()); - DrawingExporter.getInstance().exportPNG(ExportPNGAction.this.drawingProvider, file); - return null; - } - - @Override - public void complete(Void result) {} - - @Override - public void failed(Exception e) { - swingUI.showMessage("Could not export to PNG. " + e.getMessage(), "Error", ISwingUI.ERROR_MESSAGE); - } - }, true); - } - } - } - - public static class PrintAction extends AbstractAction { - - private static final long serialVersionUID = 1L; - - private IDrawingProvider drawingProvider; - - public PrintAction(IDrawingProvider drawingProvider, int keyModifiers) { - super(); - this.drawingProvider = drawingProvider; - putValue(AbstractAction.NAME, "Print..."); - putValue(AbstractAction.ACCELERATOR_KEY, KeyStroke.getKeyStroke(KeyEvent.VK_P, keyModifiers)); - putValue(AbstractAction.SMALL_ICON, IconLoader.Print.getIcon()); - } - - @Override - public void actionPerformed(ActionEvent e) { - LOG.info("PrintAction triggered"); - try { - DrawingExporter.getInstance().print(this.drawingProvider); - } catch (PrinterException e1) { - // TODO Auto-generated catch block - e1.printStackTrace(); - } - } - } - - public static class ExitAction extends AbstractAction { - - private static final long serialVersionUID = 1L; - - private IPlugInPort plugInPort; - - public ExitAction(IPlugInPort plugInPort) { - super(); - this.plugInPort = plugInPort; - putValue(AbstractAction.NAME, "Exit"); - putValue(AbstractAction.SMALL_ICON, IconLoader.Exit.getIcon()); - } - - @Override - public void actionPerformed(ActionEvent e) { - LOG.info("ExitAction triggered"); - if (plugInPort.allowFileAction()) { - System.exit(0); - } - } - } - - // Edit menu actions. - - public static class CutAction extends AbstractAction { - - private static final long serialVersionUID = 1L; - - private IPlugInPort plugInPort; - private Clipboard clipboard; - private ClipboardOwner clipboardOwner; - - public CutAction(IPlugInPort plugInPort, Clipboard clipboard, ClipboardOwner clipboardOwner) { - super(); - this.plugInPort = plugInPort; - this.clipboard = clipboard; - this.clipboardOwner = clipboardOwner; - putValue(AbstractAction.NAME, "Cut"); - putValue(AbstractAction.ACCELERATOR_KEY, - KeyStroke.getKeyStroke(KeyEvent.VK_X, Toolkit.getDefaultToolkit().getMenuShortcutKeyMask())); - putValue(AbstractAction.SMALL_ICON, IconLoader.Cut.getIcon()); - } - - @Override - public void actionPerformed(ActionEvent e) { - LOG.info("Cut triggered"); - clipboard.setContents(new ComponentTransferable(cloneComponents(plugInPort.getSelectedComponents())), - clipboardOwner); - plugInPort.deleteSelectedComponents(); - } - } - - public static class PasteAction extends AbstractAction { - - private static final long serialVersionUID = 1L; - - private IPlugInPort plugInPort; - private Clipboard clipboard; - - public PasteAction(IPlugInPort plugInPort, Clipboard clipboard) { - super(); - this.plugInPort = plugInPort; - this.clipboard = clipboard; - putValue(AbstractAction.NAME, "Paste"); - putValue(AbstractAction.ACCELERATOR_KEY, - KeyStroke.getKeyStroke(KeyEvent.VK_V, Toolkit.getDefaultToolkit().getMenuShortcutKeyMask())); - putValue(AbstractAction.SMALL_ICON, IconLoader.Paste.getIcon()); - } - - @SuppressWarnings("unchecked") - @Override - public void actionPerformed(ActionEvent e) { - LOG.info("Paste triggered"); - try { - List> components = - (List>) clipboard.getData(ComponentTransferable.listFlavor); - plugInPort.pasteComponents(cloneComponents(components)); - } catch (Exception ex) { - LOG.error("Coule not paste.", ex); - } - } - } - - public static class CopyAction extends AbstractAction { - - private static final long serialVersionUID = 1L; - - private IPlugInPort plugInPort; - private Clipboard clipboard; - private ClipboardOwner clipboardOwner; - - public CopyAction(IPlugInPort plugInPort, Clipboard clipboard, ClipboardOwner clipboardOwner) { - super(); - this.plugInPort = plugInPort; - this.clipboard = clipboard; - this.clipboardOwner = clipboardOwner; - putValue(AbstractAction.NAME, "Copy"); - putValue(AbstractAction.ACCELERATOR_KEY, - KeyStroke.getKeyStroke(KeyEvent.VK_C, Toolkit.getDefaultToolkit().getMenuShortcutKeyMask())); - putValue(AbstractAction.SMALL_ICON, IconLoader.Copy.getIcon()); - } - - @Override - public void actionPerformed(ActionEvent e) { - LOG.info("Copy triggered"); - clipboard.setContents(new ComponentTransferable(cloneComponents(plugInPort.getSelectedComponents())), - clipboardOwner); - } - } - - - public static class DuplicateAction extends AbstractAction { - - private static final long serialVersionUID = 1L; - - private IPlugInPort plugInPort; - - public DuplicateAction(IPlugInPort plugInPort) { - super(); - this.plugInPort = plugInPort; - putValue(AbstractAction.NAME, "Duplicate"); - putValue(AbstractAction.ACCELERATOR_KEY, - KeyStroke.getKeyStroke(KeyEvent.VK_D, Toolkit.getDefaultToolkit().getMenuShortcutKeyMask())); - putValue(AbstractAction.SMALL_ICON, IconLoader.DocumentsGear.getIcon()); - } - - @Override - public void actionPerformed(ActionEvent e) { - LOG.info("Duplicate triggered"); - try { - plugInPort.duplicateSelection(); - } catch (Exception ex) { - LOG.error("Coule not duplicate.", ex); - } - } - } - - private static List> cloneComponents(Collection> components) { - List> result = new ArrayList>(components.size()); - for (IDIYComponent component : components) { - try { - result.add(component.clone()); - } catch (CloneNotSupportedException e) { - throw new RuntimeException(e); - } - } - return result; - } - - public static class SelectAllAction extends AbstractAction { - - private static final long serialVersionUID = 1L; - - private IPlugInPort plugInPort; - - public SelectAllAction(IPlugInPort plugInPort) { - super(); - this.plugInPort = plugInPort; - putValue(AbstractAction.NAME, "Select All"); - putValue(AbstractAction.ACCELERATOR_KEY, - KeyStroke.getKeyStroke(KeyEvent.VK_A, Toolkit.getDefaultToolkit().getMenuShortcutKeyMask())); - putValue(AbstractAction.SMALL_ICON, IconLoader.Selection.getIcon()); - } - - @Override - public void actionPerformed(ActionEvent e) { - LOG.info("Select All triggered"); - plugInPort.selectAll(0); - } - } - - public static class GroupAction extends AbstractAction { - - private static final long serialVersionUID = 1L; - - private IPlugInPort plugInPort; - - public GroupAction(IPlugInPort plugInPort) { - super(); - this.plugInPort = plugInPort; - putValue(AbstractAction.NAME, "Group Selection"); - putValue(AbstractAction.ACCELERATOR_KEY, - KeyStroke.getKeyStroke(KeyEvent.VK_G, Toolkit.getDefaultToolkit().getMenuShortcutKeyMask())); - putValue(AbstractAction.SMALL_ICON, IconLoader.Group.getIcon()); - } - - @Override - public void actionPerformed(ActionEvent e) { - LOG.info("Group Selection triggered"); - plugInPort.groupSelectedComponents(); - } - } - - public static class UngroupAction extends AbstractAction { - - private static final long serialVersionUID = 1L; - - private IPlugInPort plugInPort; - - public UngroupAction(IPlugInPort plugInPort) { - super(); - this.plugInPort = plugInPort; - putValue(AbstractAction.NAME, "Ungroup Selection"); - putValue(AbstractAction.ACCELERATOR_KEY, - KeyStroke.getKeyStroke(KeyEvent.VK_U, Toolkit.getDefaultToolkit().getMenuShortcutKeyMask())); - putValue(AbstractAction.SMALL_ICON, IconLoader.Ungroup.getIcon()); - } - - @Override - public void actionPerformed(ActionEvent e) { - LOG.info("Ungroup Selection triggered"); - plugInPort.ungroupSelectedComponents(); - } - } - - public static class EditProjectAction extends AbstractAction { - - private static final long serialVersionUID = 1L; - - private IPlugInPort plugInPort; - - public EditProjectAction(IPlugInPort plugInPort) { - super(); - this.plugInPort = plugInPort; - putValue(AbstractAction.NAME, "Edit Project Settings"); - putValue(AbstractAction.SMALL_ICON, IconLoader.DocumentEdit.getIcon()); - } - - @Override - public void actionPerformed(ActionEvent e) { - LOG.info("Edit Project triggered"); - List properties = plugInPort.getProperties(plugInPort.getCurrentProject()); - PropertyEditorDialog editor = - DialogFactory.getInstance().createPropertyEditorDialog(properties, "Edit Project", true); - editor.setVisible(true); - if (ButtonDialog.OK.equals(editor.getSelectedButtonCaption())) { - plugInPort.applyProperties(plugInPort.getCurrentProject(), properties); - } - // Save default values. - for (PropertyWrapper property : editor.getDefaultedProperties()) { - if (property.getValue() != null) { - plugInPort.setDefaultPropertyValue(Project.class, property.getName(), property.getValue()); - } - } - } - } - - public static class NudgeAction extends AbstractAction { - - private static final long serialVersionUID = 1L; - - private IPlugInPort plugInPort; - - public NudgeAction(IPlugInPort plugInPort) { - super(); - this.plugInPort = plugInPort; - putValue(AbstractAction.NAME, "Nudge"); - putValue(AbstractAction.SMALL_ICON, IconLoader.FitToSize.getIcon()); - putValue(AbstractAction.ACCELERATOR_KEY, - KeyStroke.getKeyStroke(KeyEvent.VK_Q, Toolkit.getDefaultToolkit().getMenuShortcutKeyMask())); - } - - @Override - public void actionPerformed(ActionEvent e) { - LOG.info("Nudge triggered"); - Nudge n = new Nudge(); - boolean metric = ConfigurationManager.getInstance().readBoolean(Presenter.METRIC_KEY, true); - if (metric) { - n.setxOffset(new Size(0d, SizeUnit.mm)); - n.setyOffset(new Size(0d, SizeUnit.mm)); - } else { - n.setxOffset(new Size(0d, SizeUnit.in)); - n.setyOffset(new Size(0d, SizeUnit.in)); - } - List properties = plugInPort.getProperties(n); - PropertyEditorDialog editor = - DialogFactory.getInstance().createPropertyEditorDialog(properties, "Nudge Selection", false); - editor.setVisible(true); - if (ButtonDialog.OK.equals(editor.getSelectedButtonCaption())) { - plugInPort.applyProperties(n, properties); - plugInPort.nudgeSelection(n.getxOffset(), n.getyOffset(), n.getAffectStuckComponents()); - } - } - } - - public static class EditSelectionAction extends AbstractAction { - - private static final long serialVersionUID = 1L; - - private IPlugInPort plugInPort; - - public EditSelectionAction(IPlugInPort plugInPort) { - super(); - this.plugInPort = plugInPort; - putValue(AbstractAction.NAME, "Edit Selection"); - putValue(AbstractAction.ACCELERATOR_KEY, - KeyStroke.getKeyStroke(KeyEvent.VK_E, Toolkit.getDefaultToolkit().getMenuShortcutKeyMask())); - putValue(AbstractAction.SMALL_ICON, IconLoader.EditComponent.getIcon()); - } - - @Override - public void actionPerformed(ActionEvent e) { - LOG.info("Edit Selection triggered"); - List properties = plugInPort.getMutualSelectionProperties(); - if (properties == null || properties.isEmpty()) { - LOG.info("Nothing to edit"); - return; - } - plugInPort.editSelection(); - } - } - - public static class DeleteSelectionAction extends AbstractAction { - - private static final long serialVersionUID = 1L; - - private IPlugInPort plugInPort; - - public DeleteSelectionAction(IPlugInPort plugInPort) { - super(); - this.plugInPort = plugInPort; - putValue(AbstractAction.NAME, "Delete Selection"); - putValue(AbstractAction.ACCELERATOR_KEY, KeyStroke.getKeyStroke(KeyEvent.VK_DELETE, 0)); - putValue(AbstractAction.SMALL_ICON, IconLoader.Delete.getIcon()); - } - - @Override - public void actionPerformed(ActionEvent e) { - LOG.info("Delete Selection triggered"); - plugInPort.deleteSelectedComponents(); - } - } - - public static class SaveAsTemplateAction extends AbstractAction { - - private static final long serialVersionUID = 1L; - - private IPlugInPort plugInPort; - - public SaveAsTemplateAction(IPlugInPort plugInPort) { - super(); - this.plugInPort = plugInPort; - putValue(AbstractAction.NAME, "Save as Variant"); - putValue(AbstractAction.SMALL_ICON, IconLoader.BriefcaseAdd.getIcon()); - } - - @Override - public void actionPerformed(ActionEvent e) { - LOG.info("Save as template triggered"); - String templateName = - JOptionPane.showInputDialog(null, "Variant name:", "Save as Variant", JOptionPane.PLAIN_MESSAGE); - if (templateName != null && !templateName.trim().isEmpty()) { - plugInPort.saveSelectedComponentAsTemplate(templateName); - } - } - } - - public static class SaveAsBlockAction extends AbstractAction { - - private static final long serialVersionUID = 1L; - - private IPlugInPort plugInPort; - - public SaveAsBlockAction(IPlugInPort plugInPort) { - super(); - this.plugInPort = plugInPort; - putValue(AbstractAction.NAME, "Save as Building Block"); - putValue(AbstractAction.SMALL_ICON, IconLoader.ComponentAdd.getIcon()); - } - - @Override - public void actionPerformed(ActionEvent e) { - LOG.info("Save as building block triggered"); - String templateName = - JOptionPane.showInputDialog(null, "Block name:", "Save as Building Block", JOptionPane.PLAIN_MESSAGE); - if (templateName != null && !templateName.trim().isEmpty()) { - plugInPort.saveSelectionAsBlock(templateName); - } - } - } - - public static class ExpandSelectionAction extends AbstractAction { - - private static final long serialVersionUID = 1L; - - private IPlugInPort plugInPort; - private ExpansionMode expansionMode; - - public ExpandSelectionAction(IPlugInPort plugInPort, ExpansionMode expansionMode) { - super(); - this.plugInPort = plugInPort; - this.expansionMode = expansionMode; - switch (expansionMode) { - case ALL: - putValue(AbstractAction.NAME, "All Connected"); - break; - case IMMEDIATE: - putValue(AbstractAction.NAME, "Immediate Only"); - break; - case SAME_TYPE: - putValue(AbstractAction.NAME, "Same Type Only"); - break; - - default: - break; - } - } - - @Override - public void actionPerformed(ActionEvent e) { - LOG.info("Expand Selection triggered: " + expansionMode); - plugInPort.expandSelection(expansionMode); - } - } - - public static class RotateSelectionAction extends AbstractAction { - - private static final long serialVersionUID = 1L; - - private IPlugInPort plugInPort; - private int direction; - - public RotateSelectionAction(IPlugInPort plugInPort, int direction) { - super(); - this.plugInPort = plugInPort; - this.direction = direction; - if (direction > 0) { - putValue(AbstractAction.NAME, "Rotate Clockwise"); - putValue(AbstractAction.SMALL_ICON, IconLoader.RotateCW.getIcon()); - putValue(AbstractAction.ACCELERATOR_KEY, KeyStroke.getKeyStroke(KeyEvent.VK_RIGHT, ActionEvent.ALT_MASK)); - } else { - putValue(AbstractAction.NAME, "Rotate Counterclockwise"); - putValue(AbstractAction.SMALL_ICON, IconLoader.RotateCCW.getIcon()); - putValue(AbstractAction.ACCELERATOR_KEY, KeyStroke.getKeyStroke(KeyEvent.VK_LEFT, ActionEvent.ALT_MASK)); - } - } - - @Override - public void actionPerformed(ActionEvent e) { - LOG.info("Rotate Selection triggered: " + direction); - plugInPort.rotateSelection(direction); - } - } - - public static class MirrorSelectionAction extends AbstractAction { - - private static final long serialVersionUID = 1L; - - private IPlugInPort plugInPort; - private int direction; - - public MirrorSelectionAction(IPlugInPort plugInPort, int direction) { - super(); - this.plugInPort = plugInPort; - this.direction = direction; - if (direction == IComponentTransformer.HORIZONTAL) { - putValue(AbstractAction.NAME, "Mirror Horizontally"); - putValue(AbstractAction.SMALL_ICON, IconLoader.FlipHorizontal.getIcon()); - putValue(AbstractAction.ACCELERATOR_KEY, KeyStroke.getKeyStroke(KeyEvent.VK_H, ActionEvent.ALT_MASK)); - } else { - putValue(AbstractAction.NAME, "Mirror Vertically"); - putValue(AbstractAction.SMALL_ICON, IconLoader.FlipVertical.getIcon()); - putValue(AbstractAction.ACCELERATOR_KEY, KeyStroke.getKeyStroke(KeyEvent.VK_V, ActionEvent.ALT_MASK)); - } - } - - @Override - public void actionPerformed(ActionEvent e) { - LOG.info("Mirror Selection triggered: " + direction); - plugInPort.mirrorSelection(direction); - } - } - - public static class SendToBackAction extends AbstractAction { - - private static final long serialVersionUID = 1L; - - private IPlugInPort plugInPort; - - public SendToBackAction(IPlugInPort plugInPort) { - super(); - this.plugInPort = plugInPort; - putValue(AbstractAction.NAME, "Send Backward"); - putValue(AbstractAction.SMALL_ICON, IconLoader.Back.getIcon()); - putValue(AbstractAction.ACCELERATOR_KEY, KeyStroke.getKeyStroke(KeyEvent.VK_DOWN, ActionEvent.ALT_MASK)); - } - - @Override - public void actionPerformed(ActionEvent e) { - LOG.info("Send to Back triggered"); - plugInPort.sendSelectionToBack(); - } - } - - public static class BringToFrontAction extends AbstractAction { - - private static final long serialVersionUID = 1L; - - private IPlugInPort plugInPort; - - public BringToFrontAction(IPlugInPort plugInPort) { - super(); - this.plugInPort = plugInPort; - putValue(AbstractAction.NAME, "Bring Forward"); - putValue(AbstractAction.SMALL_ICON, IconLoader.Front.getIcon()); - putValue(AbstractAction.ACCELERATOR_KEY, KeyStroke.getKeyStroke(KeyEvent.VK_UP, ActionEvent.ALT_MASK)); - } - - @Override - public void actionPerformed(ActionEvent e) { - LOG.info("Bring to Front triggered"); - plugInPort.bringSelectionToFront(); - } - } - - public static class ConfigAction extends AbstractAction { - - private static final long serialVersionUID = 1L; - - private IPlugInPort plugInPort; - private String configKey; - private String tipKey; - - public ConfigAction(IPlugInPort plugInPort, String title, String configKey, boolean defaultValue, String tipKey) { - super(); - this.plugInPort = plugInPort; - this.configKey = configKey; - this.tipKey = tipKey; - putValue(AbstractAction.NAME, title); - putValue(IView.CHECK_BOX_MENU_ITEM, true); - putValue(AbstractAction.SELECTED_KEY, ConfigurationManager.getInstance().readBoolean(configKey, defaultValue)); - } - - public ConfigAction(IPlugInPort plugInPort, String title, String configKey, boolean defaultValue) { - this(plugInPort, title, configKey, defaultValue, null); - } - - @Override - public void actionPerformed(ActionEvent e) { - LOG.info(getValue(AbstractAction.NAME) + " triggered"); - ConfigurationManager.getInstance().writeValue(configKey, getValue(AbstractAction.SELECTED_KEY)); - if ((Boolean) getValue(AbstractAction.SELECTED_KEY) && tipKey != null - && !ConfigurationManager.getInstance().readBoolean(tipKey + ".dismissed", false)) { - DialogFactory.getInstance().createInfoDialog(tipKey).setVisible(true); - } - plugInPort.refresh(); - } - } - - public static class ThemeAction extends AbstractAction { - - private static final long serialVersionUID = 1L; - - private IPlugInPort plugInPort; - private Theme theme; - - public ThemeAction(IPlugInPort plugInPort, Theme theme) { - super(); - this.plugInPort = plugInPort; - this.theme = theme; - putValue(AbstractAction.NAME, theme.getName()); - putValue(IView.RADIO_BUTTON_GROUP_KEY, "theme"); - putValue(AbstractAction.SELECTED_KEY, plugInPort.getSelectedTheme().getName().equals(theme.getName())); - } - - @Override - public void actionPerformed(ActionEvent e) { - LOG.info(getValue(AbstractAction.NAME) + " triggered"); - plugInPort.setSelectedTheme(theme); - } - } - - public static class ComponentBrowserAction extends AbstractAction { - - private static final long serialVersionUID = 1L; - - private String browserType; - - public ComponentBrowserAction(String browserType) { - super(); - this.browserType = browserType; - putValue(AbstractAction.NAME, browserType); - putValue(IView.RADIO_BUTTON_GROUP_KEY, "componentBrowser"); - - putValue( - AbstractAction.SELECTED_KEY, - browserType.equals(ConfigurationManager.getInstance().readString(ConfigPlugin.COMPONENT_BROWSER, - ConfigPlugin.SEARCHABLE_TREE))); - } - - @Override - public void actionPerformed(ActionEvent e) { - LOG.info(getValue(AbstractAction.NAME) + " triggered"); - ConfigurationManager.getInstance().writeValue(ConfigPlugin.COMPONENT_BROWSER, browserType); - } - } - - - public static class RenumberAction extends AbstractAction { - - private static final long serialVersionUID = 1L; - - private IPlugInPort plugInPort; - private boolean xAxisFirst; - - public RenumberAction(IPlugInPort plugInPort, boolean xAxisFirst) { - super(); - this.plugInPort = plugInPort; - this.xAxisFirst = xAxisFirst; - putValue(AbstractAction.NAME, xAxisFirst ? "Top-to-Bottom" : "Left-to-Right"); - } - - @Override - public void actionPerformed(ActionEvent e) { - LOG.info(getValue(AbstractAction.NAME) + " triggered"); - plugInPort.renumberSelectedComponents(xAxisFirst); - } - } -} +/* + * + * DIY Layout Creator (DIYLC). Copyright (c) 2009-2018 held jointly by the individual authors. + * + * This file is part of DIYLC. + * + * DIYLC is free software: you can redistribute it and/or modify it under the terms of the GNU + * General Public License as published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * DIYLC is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even + * the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General + * Public License for more details. + * + * You should have received a copy of the GNU General Public License along with DIYLC. If not, see + * . + */ +package org.diylc.swing; + +import java.awt.Toolkit; +import java.awt.datatransfer.Clipboard; +import java.awt.datatransfer.ClipboardOwner; +import java.awt.event.ActionEvent; +import java.awt.event.KeyEvent; +import java.awt.print.PrinterException; +import java.io.File; +import java.util.ArrayList; +import java.util.Collection; +import java.util.List; +import java.util.Set; + +import javax.swing.AbstractAction; +import javax.swing.JOptionPane; +import javax.swing.KeyStroke; + +import org.apache.log4j.Logger; +import org.diylc.appframework.miscutils.ConfigurationManager; +import org.diylc.common.IComponentTransformer; +import org.diylc.common.IPlugInPort; +import org.diylc.common.ITask; +import org.diylc.common.PropertyWrapper; +import org.diylc.core.ExpansionMode; +import org.diylc.core.IDIYComponent; +import org.diylc.core.IView; +import org.diylc.core.Project; +import org.diylc.core.Theme; +import org.diylc.core.measures.Nudge; +import org.diylc.core.measures.Size; +import org.diylc.core.measures.SizeUnit; +import org.diylc.images.IconLoader; +import org.diylc.presenter.Presenter; +import org.diylc.swing.gui.DialogFactory; +import org.diylc.swing.gui.editor.PropertyEditorDialog; +import org.diylc.swing.plugins.config.ConfigPlugin; +import org.diylc.swing.plugins.edit.ComponentTransferable; +import org.diylc.swing.plugins.file.BomDialog; +import org.diylc.swing.plugins.file.FileFilterEnum; +import org.diylc.swingframework.ButtonDialog; +import org.diylc.swingframework.IDrawingProvider; +import org.diylc.swingframework.export.DrawingExporter; +import org.diylc.utils.BomEntry; + +public class ActionFactory { + + private static final Logger LOG = Logger.getLogger(ActionFactory.class); + + private static ActionFactory instance; + + public static ActionFactory getInstance() { + if (instance == null) { + instance = new ActionFactory(); + } + return instance; + } + + private ActionFactory() {} + + // File menu actions. + + public NewAction createNewAction(IPlugInPort plugInPort) { + return new NewAction(plugInPort); + } + + public OpenAction createOpenAction(IPlugInPort plugInPort, ISwingUI swingUI) { + return new OpenAction(plugInPort, swingUI); + } + + public ImportAction createImportAction(IPlugInPort plugInPort, ISwingUI swingUI) { + return new ImportAction(plugInPort, swingUI); + } + + public SaveAction createSaveAction(IPlugInPort plugInPort, ISwingUI swingUI) { + return new SaveAction(plugInPort, swingUI); + } + + public SaveAsAction createSaveAsAction(IPlugInPort plugInPort, ISwingUI swingUI) { + return new SaveAsAction(plugInPort, swingUI); + } + + public CreateBomAction createBomAction(IPlugInPort plugInPort) { + return new CreateBomAction(plugInPort); + } + + public ExportPDFAction createExportPDFAction(IPlugInPort plugInPort, IDrawingProvider drawingProvider, ISwingUI swingUI, String defaultSuffix) { + return new ExportPDFAction(plugInPort, drawingProvider, swingUI, defaultSuffix); + } + + public ExportPNGAction createExportPNGAction(IPlugInPort plugInPort, IDrawingProvider drawingProvider, ISwingUI swingUI, String defaultSuffix) { + return new ExportPNGAction(plugInPort, drawingProvider, swingUI, defaultSuffix); + } + + public PrintAction createPrintAction(IDrawingProvider drawingProvider, int keyModifiers) { + return new PrintAction(drawingProvider, keyModifiers); + } + + public ExitAction createExitAction(IPlugInPort plugInPort) { + return new ExitAction(plugInPort); + } + + // Edit menu actions. + + public CutAction createCutAction(IPlugInPort plugInPort, Clipboard clipboard, ClipboardOwner clipboardOwner) { + return new CutAction(plugInPort, clipboard, clipboardOwner); + } + + public CopyAction createCopyAction(IPlugInPort plugInPort, Clipboard clipboard, ClipboardOwner clipboardOwner) { + return new CopyAction(plugInPort, clipboard, clipboardOwner); + } + + public PasteAction createPasteAction(IPlugInPort plugInPort, Clipboard clipboard) { + return new PasteAction(plugInPort, clipboard); + } + + public DuplicateAction createDuplicateAction(IPlugInPort plugInPort) { + return new DuplicateAction(plugInPort); + } + + public SelectAllAction createSelectAllAction(IPlugInPort plugInPort) { + return new SelectAllAction(plugInPort); + } + + public GroupAction createGroupAction(IPlugInPort plugInPort) { + return new GroupAction(plugInPort); + } + + public UngroupAction createUngroupAction(IPlugInPort plugInPort) { + return new UngroupAction(plugInPort); + } + + public EditProjectAction createEditProjectAction(IPlugInPort plugInPort) { + return new EditProjectAction(plugInPort); + } + + public EditSelectionAction createEditSelectionAction(IPlugInPort plugInPort) { + return new EditSelectionAction(plugInPort); + } + + public DeleteSelectionAction createDeleteSelectionAction(IPlugInPort plugInPort) { + return new DeleteSelectionAction(plugInPort); + } + + public SaveAsTemplateAction createSaveAsTemplateAction(IPlugInPort plugInPort) { + return new SaveAsTemplateAction(plugInPort); + } + + public SaveAsBlockAction createSaveAsBlockAction(IPlugInPort plugInPort) { + return new SaveAsBlockAction(plugInPort); + } + + public ExpandSelectionAction createExpandSelectionAction(IPlugInPort plugInPort, ExpansionMode expansionMode) { + return new ExpandSelectionAction(plugInPort, expansionMode); + } + + public RotateSelectionAction createRotateSelectionAction(IPlugInPort plugInPort, int direction) { + return new RotateSelectionAction(plugInPort, direction); + } + + public MirrorSelectionAction createMirrorSelectionAction(IPlugInPort plugInPort, int direction) { + return new MirrorSelectionAction(plugInPort, direction); + } + + public SendToBackAction createSendToBackAction(IPlugInPort plugInPort) { + return new SendToBackAction(plugInPort); + } + + public BringToFrontAction createBringToFrontAction(IPlugInPort plugInPort) { + return new BringToFrontAction(plugInPort); + } + + public NudgeAction createNudgeAction(IPlugInPort plugInPort) { + return new NudgeAction(plugInPort); + } + + // Config actions. + + public ConfigAction createConfigAction(IPlugInPort plugInPort, String title, String configKey, boolean defaultValue) { + return new ConfigAction(plugInPort, title, configKey, defaultValue); + } + + public ConfigAction createConfigAction(IPlugInPort plugInPort, String title, String configKey, boolean defaultValue, + String tipKey) { + return new ConfigAction(plugInPort, title, configKey, defaultValue, tipKey); + } + + public ThemeAction createThemeAction(IPlugInPort plugInPort, Theme theme) { + return new ThemeAction(plugInPort, theme); + } + + public ComponentBrowserAction createComponentBrowserAction(String browserType) { + return new ComponentBrowserAction(browserType); + } + + public RenumberAction createRenumberAction(IPlugInPort plugInPort, boolean xAxisFirst) { + return new RenumberAction(plugInPort, xAxisFirst); + } + + // File menu actions. + + public static class NewAction extends AbstractAction { + + private static final long serialVersionUID = 1L; + + private IPlugInPort plugInPort; + + public NewAction(IPlugInPort plugInPort) { + super(); + this.plugInPort = plugInPort; + putValue(AbstractAction.NAME, "New"); + putValue(AbstractAction.ACCELERATOR_KEY, + KeyStroke.getKeyStroke(KeyEvent.VK_N, Toolkit.getDefaultToolkit().getMenuShortcutKeyMask())); + putValue(AbstractAction.SMALL_ICON, IconLoader.DocumentPlain.getIcon()); + } + + @Override + public void actionPerformed(ActionEvent e) { + LOG.info("NewAction triggered"); + if (!plugInPort.allowFileAction()) { + return; + } + plugInPort.createNewProject(); + List properties = plugInPort.getProperties(plugInPort.getCurrentProject()); + PropertyEditorDialog editor = + DialogFactory.getInstance().createPropertyEditorDialog(properties, "Edit Project", true); + editor.setVisible(true); + if (ButtonDialog.OK.equals(editor.getSelectedButtonCaption())) { + plugInPort.applyProperties(plugInPort.getCurrentProject(), properties); + } + // Save default values. + for (PropertyWrapper property : editor.getDefaultedProperties()) { + if (property.getValue() != null) { + plugInPort.setDefaultPropertyValue(Project.class, property.getName(), property.getValue()); + } + } + } + } + + public static class OpenAction extends AbstractAction { + + private static final long serialVersionUID = 1L; + + private IPlugInPort plugInPort; + private ISwingUI swingUI; + + public OpenAction(IPlugInPort plugInPort, ISwingUI swingUI) { + super(); + this.plugInPort = plugInPort; + this.swingUI = swingUI; + putValue(AbstractAction.NAME, "Open"); + putValue(AbstractAction.ACCELERATOR_KEY, + KeyStroke.getKeyStroke(KeyEvent.VK_O, Toolkit.getDefaultToolkit().getMenuShortcutKeyMask())); + putValue(AbstractAction.SMALL_ICON, IconLoader.FolderOut.getIcon()); + } + + @Override + public void actionPerformed(ActionEvent e) { + LOG.info("OpenAction triggered"); + if (!plugInPort.allowFileAction()) { + return; + } + final File file = + DialogFactory.getInstance().showOpenDialog(FileFilterEnum.DIY.getFilter(), null, + FileFilterEnum.DIY.getExtensions()[0], null); + if (file != null) { + swingUI.executeBackgroundTask(new ITask() { + + @Override + public Void doInBackground() throws Exception { + LOG.debug("Opening from " + file.getAbsolutePath()); + plugInPort.loadProjectFromFile(file.getAbsolutePath()); + return null; + } + + @Override + public void complete(Void result) {} + + @Override + public void failed(Exception e) { + swingUI.showMessage("Could not open file. " + e.getMessage(), "Error", ISwingUI.ERROR_MESSAGE); + } + }, true); + } + } + } + + public static class ImportAction extends AbstractAction { + + private static final long serialVersionUID = 1L; + + private IPlugInPort plugInPort; + private ISwingUI swingUI; + private Presenter presenter; + + public ImportAction(IPlugInPort plugInPort, ISwingUI swingUI) { + super(); + this.plugInPort = plugInPort; + this.swingUI = swingUI; + this.presenter = new Presenter(new IView() { + + @Override + public int showConfirmDialog(String message, String title, int optionType, int messageType) { + return JOptionPane.showConfirmDialog(null, message, title, optionType, messageType); + } + + @Override + public void showMessage(String message, String title, int messageType) { + JOptionPane.showMessageDialog(null, message, title, messageType); + } + + @Override + public File promptFileSave() { + return null; + } + + @Override + public boolean editProperties(List properties, Set defaultedProperties) { + return false; + } + }); + putValue(AbstractAction.NAME, "Import"); + putValue(AbstractAction.ACCELERATOR_KEY, + KeyStroke.getKeyStroke(KeyEvent.VK_I, Toolkit.getDefaultToolkit().getMenuShortcutKeyMask())); + putValue(AbstractAction.SMALL_ICON, IconLoader.ElementInto.getIcon()); + } + + @Override + public void actionPerformed(ActionEvent e) { + LOG.info("ImportAction triggered"); + + final File file = + DialogFactory.getInstance().showOpenDialog(FileFilterEnum.DIY.getFilter(), null, + FileFilterEnum.DIY.getExtensions()[0], null); + if (file != null) { + swingUI.executeBackgroundTask(new ITask() { + + @Override + public Void doInBackground() throws Exception { + LOG.debug("Opening from " + file.getAbsolutePath()); + // Load project in temp presenter + presenter.loadProjectFromFile(file.getAbsolutePath()); + // Grab all components and paste them into the main + // presenter + plugInPort.pasteComponents(presenter.getCurrentProject().getComponents(), false); + // Cleanup components in the temp presenter, don't need + // them anymore + presenter.selectAll(0); + presenter.deleteSelectedComponents(); + return null; + } + + @Override + public void complete(Void result) {} + + @Override + public void failed(Exception e) { + swingUI.showMessage("Could not open file. " + e.getMessage(), "Error", ISwingUI.ERROR_MESSAGE); + } + }, true); + } + } + } + + public static class SaveAction extends AbstractAction { + + private static final long serialVersionUID = 1L; + + private IPlugInPort plugInPort; + private ISwingUI swingUI; + + public SaveAction(IPlugInPort plugInPort, ISwingUI swingUI) { + super(); + this.plugInPort = plugInPort; + this.swingUI = swingUI; + putValue(AbstractAction.NAME, "Save"); + putValue(AbstractAction.ACCELERATOR_KEY, + KeyStroke.getKeyStroke(KeyEvent.VK_S, Toolkit.getDefaultToolkit().getMenuShortcutKeyMask())); + putValue(AbstractAction.SMALL_ICON, IconLoader.DiskBlue.getIcon()); + } + + @Override + public void actionPerformed(ActionEvent e) { + LOG.info("SaveAction triggered"); + if (plugInPort.getCurrentFileName() == null) { + final File file = + DialogFactory.getInstance().showSaveDialog(swingUI.getOwnerFrame(), FileFilterEnum.DIY.getFilter(), null, + FileFilterEnum.DIY.getExtensions()[0], null); + if (file != null) { + swingUI.executeBackgroundTask(new ITask() { + + @Override + public Void doInBackground() throws Exception { + LOG.debug("Saving to " + file.getAbsolutePath()); + plugInPort.saveProjectToFile(file.getAbsolutePath(), false); + return null; + } + + @Override + public void complete(Void result) {} + + @Override + public void failed(Exception e) { + swingUI.showMessage("Could not save to file. " + e.getMessage(), "Error", ISwingUI.ERROR_MESSAGE); + } + }, true); + } + } else { + swingUI.executeBackgroundTask(new ITask() { + + @Override + public Void doInBackground() throws Exception { + LOG.debug("Saving to " + plugInPort.getCurrentFileName()); + plugInPort.saveProjectToFile(plugInPort.getCurrentFileName(), false); + return null; + } + + @Override + public void complete(Void result) {} + + @Override + public void failed(Exception e) { + swingUI.showMessage("Could not save to file. " + e.getMessage(), "Error", ISwingUI.ERROR_MESSAGE); + } + }, true); + } + } + } + + public static class SaveAsAction extends AbstractAction { + + private static final long serialVersionUID = 1L; + + private IPlugInPort plugInPort; + private ISwingUI swingUI; + + public SaveAsAction(IPlugInPort plugInPort, ISwingUI swingUI) { + super(); + this.plugInPort = plugInPort; + this.swingUI = swingUI; + putValue(AbstractAction.NAME, "Save As"); + putValue( + AbstractAction.ACCELERATOR_KEY, + KeyStroke.getKeyStroke(KeyEvent.VK_S, Toolkit.getDefaultToolkit().getMenuShortcutKeyMask() + | ActionEvent.SHIFT_MASK)); + putValue(AbstractAction.SMALL_ICON, IconLoader.DiskBlue.getIcon()); + } + + @Override + public void actionPerformed(ActionEvent e) { + LOG.info("SaveAsAction triggered"); + final File file = + DialogFactory.getInstance().showSaveDialog(swingUI.getOwnerFrame(), FileFilterEnum.DIY.getFilter(), null, + FileFilterEnum.DIY.getExtensions()[0], null); + if (file != null) { + swingUI.executeBackgroundTask(new ITask() { + + @Override + public Void doInBackground() throws Exception { + LOG.debug("Saving to " + file.getAbsolutePath()); + plugInPort.saveProjectToFile(file.getAbsolutePath(), false); + return null; + } + + @Override + public void complete(Void result) {} + + @Override + public void failed(Exception e) { + swingUI.showMessage("Could not save to file. " + e.getMessage(), "Error", ISwingUI.ERROR_MESSAGE); + } + }, true); + } + } + } + + public static class CreateBomAction extends AbstractAction { + + private static final long serialVersionUID = 1L; + + private IPlugInPort plugInPort; + + public CreateBomAction(IPlugInPort plugInPort) { + super(); + this.plugInPort = plugInPort; + putValue(AbstractAction.NAME, "Create B.O.M."); + putValue(AbstractAction.SMALL_ICON, IconLoader.BOM.getIcon()); + } + + @Override + public void actionPerformed(ActionEvent e) { + LOG.info("CreateBomAction triggered"); + List bom = + org.diylc.utils.BomMaker.getInstance().createBom(plugInPort.getCurrentProject().getComponents()); + + String initialFileName = null; + String currentFile = plugInPort.getCurrentFileName(); + if (currentFile != null) { + File cFile = new File(currentFile); + initialFileName = cFile.getName().replaceAll("(?i)\\.diy", "") + " BOM"; + } + + BomDialog dialog = DialogFactory.getInstance().createBomDialog(bom, initialFileName); + dialog.setVisible(true); + } + } + + public static class ExportPDFAction extends AbstractAction { + + private static final long serialVersionUID = 1L; + + private IDrawingProvider drawingProvider; + private ISwingUI swingUI; + private IPlugInPort plugInPort; + private String defaultSuffix; + + public ExportPDFAction(IPlugInPort plugInPort, IDrawingProvider drawingProvider, ISwingUI swingUI, String defaultSuffix) { + super(); + this.plugInPort = plugInPort; + this.drawingProvider = drawingProvider; + this.swingUI = swingUI; + this.defaultSuffix = defaultSuffix; + putValue(AbstractAction.NAME, "Export to PDF"); + putValue(AbstractAction.SMALL_ICON, IconLoader.PDF.getIcon()); + } + + @Override + public void actionPerformed(ActionEvent e) { + LOG.info("ExportPDFAction triggered"); + + File initialFile = null; + String currentFile = plugInPort.getCurrentFileName(); + if (currentFile != null) { + File cFile = new File(currentFile); + initialFile = new File(cFile.getName().replaceAll("(?i)\\.diy", "") + defaultSuffix + ".pdf"); + } + + final File file = + DialogFactory.getInstance().showSaveDialog(swingUI.getOwnerFrame(), FileFilterEnum.PDF.getFilter(), initialFile, + FileFilterEnum.PDF.getExtensions()[0], null); + if (file != null) { + swingUI.executeBackgroundTask(new ITask() { + + @Override + public Void doInBackground() throws Exception { + LOG.debug("Exporting to " + file.getAbsolutePath()); + DrawingExporter.getInstance().exportPDF(ExportPDFAction.this.drawingProvider, file); + return null; + } + + @Override + public void complete(Void result) {} + + @Override + public void failed(Exception e) { + swingUI.showMessage("Could not export to PDF. " + e.getMessage(), "Error", ISwingUI.ERROR_MESSAGE); + } + }, true); + } + } + } + + public static class ExportPNGAction extends AbstractAction { + + private static final long serialVersionUID = 1L; + + private IDrawingProvider drawingProvider; + private ISwingUI swingUI; + private IPlugInPort plugInPort; + private String defaultSuffix; + + public ExportPNGAction(IPlugInPort plugInPort, IDrawingProvider drawingProvider, ISwingUI swingUI, String defaultSuffix) { + super(); + this.plugInPort = plugInPort; + this.drawingProvider = drawingProvider; + this.drawingProvider = drawingProvider; + this.swingUI = swingUI; + this.defaultSuffix = defaultSuffix; + putValue(AbstractAction.NAME, "Export to PNG"); + putValue(AbstractAction.SMALL_ICON, IconLoader.Image.getIcon()); + } + + @Override + public void actionPerformed(ActionEvent e) { + LOG.info("ExportPNGAction triggered"); + + File initialFile = null; + String currentFile = plugInPort.getCurrentFileName(); + if (currentFile != null) { + File cFile = new File(currentFile); + initialFile = new File(cFile.getName().replaceAll("(?i)\\.diy", "") + defaultSuffix + ".png"); + } + + final File file = + DialogFactory.getInstance().showSaveDialog(swingUI.getOwnerFrame(), FileFilterEnum.PNG.getFilter(), initialFile, + FileFilterEnum.PNG.getExtensions()[0], null); + if (file != null) { + swingUI.executeBackgroundTask(new ITask() { + + @Override + public Void doInBackground() throws Exception { + LOG.debug("Exporting to " + file.getAbsolutePath()); + DrawingExporter.getInstance().exportPNG(ExportPNGAction.this.drawingProvider, file); + return null; + } + + @Override + public void complete(Void result) {} + + @Override + public void failed(Exception e) { + swingUI.showMessage("Could not export to PNG. " + e.getMessage(), "Error", ISwingUI.ERROR_MESSAGE); + } + }, true); + } + } + } + + public static class PrintAction extends AbstractAction { + + private static final long serialVersionUID = 1L; + + private IDrawingProvider drawingProvider; + + public PrintAction(IDrawingProvider drawingProvider, int keyModifiers) { + super(); + this.drawingProvider = drawingProvider; + putValue(AbstractAction.NAME, "Print..."); + putValue(AbstractAction.ACCELERATOR_KEY, KeyStroke.getKeyStroke(KeyEvent.VK_P, keyModifiers)); + putValue(AbstractAction.SMALL_ICON, IconLoader.Print.getIcon()); + } + + @Override + public void actionPerformed(ActionEvent e) { + LOG.info("PrintAction triggered"); + try { + DrawingExporter.getInstance().print(this.drawingProvider); + } catch (PrinterException e1) { + // TODO Auto-generated catch block + e1.printStackTrace(); + } + } + } + + public static class ExitAction extends AbstractAction { + + private static final long serialVersionUID = 1L; + + private IPlugInPort plugInPort; + + public ExitAction(IPlugInPort plugInPort) { + super(); + this.plugInPort = plugInPort; + putValue(AbstractAction.NAME, "Exit"); + putValue(AbstractAction.SMALL_ICON, IconLoader.Exit.getIcon()); + } + + @Override + public void actionPerformed(ActionEvent e) { + LOG.info("ExitAction triggered"); + if (plugInPort.allowFileAction()) { + System.exit(0); + } + } + } + + // Edit menu actions. + + public static class CutAction extends AbstractAction { + + private static final long serialVersionUID = 1L; + + private IPlugInPort plugInPort; + private Clipboard clipboard; + private ClipboardOwner clipboardOwner; + + public CutAction(IPlugInPort plugInPort, Clipboard clipboard, ClipboardOwner clipboardOwner) { + super(); + this.plugInPort = plugInPort; + this.clipboard = clipboard; + this.clipboardOwner = clipboardOwner; + putValue(AbstractAction.NAME, "Cut"); + putValue(AbstractAction.ACCELERATOR_KEY, + KeyStroke.getKeyStroke(KeyEvent.VK_X, Toolkit.getDefaultToolkit().getMenuShortcutKeyMask())); + putValue(AbstractAction.SMALL_ICON, IconLoader.Cut.getIcon()); + } + + @Override + public void actionPerformed(ActionEvent e) { + LOG.info("Cut triggered"); + clipboard.setContents(new ComponentTransferable(cloneComponents(plugInPort.getSelectedComponents())), + clipboardOwner); + plugInPort.deleteSelectedComponents(); + } + } + + public static class PasteAction extends AbstractAction { + + private static final long serialVersionUID = 1L; + + private IPlugInPort plugInPort; + private Clipboard clipboard; + + public PasteAction(IPlugInPort plugInPort, Clipboard clipboard) { + super(); + this.plugInPort = plugInPort; + this.clipboard = clipboard; + putValue(AbstractAction.NAME, "Paste"); + putValue(AbstractAction.ACCELERATOR_KEY, + KeyStroke.getKeyStroke(KeyEvent.VK_V, Toolkit.getDefaultToolkit().getMenuShortcutKeyMask())); + putValue(AbstractAction.SMALL_ICON, IconLoader.Paste.getIcon()); + } + + @SuppressWarnings("unchecked") + @Override + public void actionPerformed(ActionEvent e) { + LOG.info("Paste triggered"); + try { + List> components = + (List>) clipboard.getData(ComponentTransferable.listFlavor); + plugInPort.pasteComponents(cloneComponents(components), false); + } catch (Exception ex) { + LOG.error("Coule not paste.", ex); + } + } + } + + public static class CopyAction extends AbstractAction { + + private static final long serialVersionUID = 1L; + + private IPlugInPort plugInPort; + private Clipboard clipboard; + private ClipboardOwner clipboardOwner; + + public CopyAction(IPlugInPort plugInPort, Clipboard clipboard, ClipboardOwner clipboardOwner) { + super(); + this.plugInPort = plugInPort; + this.clipboard = clipboard; + this.clipboardOwner = clipboardOwner; + putValue(AbstractAction.NAME, "Copy"); + putValue(AbstractAction.ACCELERATOR_KEY, + KeyStroke.getKeyStroke(KeyEvent.VK_C, Toolkit.getDefaultToolkit().getMenuShortcutKeyMask())); + putValue(AbstractAction.SMALL_ICON, IconLoader.Copy.getIcon()); + } + + @Override + public void actionPerformed(ActionEvent e) { + LOG.info("Copy triggered"); + clipboard.setContents(new ComponentTransferable(cloneComponents(plugInPort.getSelectedComponents())), + clipboardOwner); + } + } + + + public static class DuplicateAction extends AbstractAction { + + private static final long serialVersionUID = 1L; + + private IPlugInPort plugInPort; + + public DuplicateAction(IPlugInPort plugInPort) { + super(); + this.plugInPort = plugInPort; + putValue(AbstractAction.NAME, "Duplicate"); + putValue(AbstractAction.ACCELERATOR_KEY, + KeyStroke.getKeyStroke(KeyEvent.VK_D, Toolkit.getDefaultToolkit().getMenuShortcutKeyMask())); + putValue(AbstractAction.SMALL_ICON, IconLoader.DocumentsGear.getIcon()); + } + + @Override + public void actionPerformed(ActionEvent e) { + LOG.info("Duplicate triggered"); + try { + plugInPort.duplicateSelection(); + } catch (Exception ex) { + LOG.error("Coule not duplicate.", ex); + } + } + } + + private static List> cloneComponents(Collection> components) { + List> result = new ArrayList>(components.size()); + for (IDIYComponent component : components) { + try { + result.add(component.clone()); + } catch (CloneNotSupportedException e) { + throw new RuntimeException(e); + } + } + return result; + } + + public static class SelectAllAction extends AbstractAction { + + private static final long serialVersionUID = 1L; + + private IPlugInPort plugInPort; + + public SelectAllAction(IPlugInPort plugInPort) { + super(); + this.plugInPort = plugInPort; + putValue(AbstractAction.NAME, "Select All"); + putValue(AbstractAction.ACCELERATOR_KEY, + KeyStroke.getKeyStroke(KeyEvent.VK_A, Toolkit.getDefaultToolkit().getMenuShortcutKeyMask())); + putValue(AbstractAction.SMALL_ICON, IconLoader.Selection.getIcon()); + } + + @Override + public void actionPerformed(ActionEvent e) { + LOG.info("Select All triggered"); + plugInPort.selectAll(0); + } + } + + public static class GroupAction extends AbstractAction { + + private static final long serialVersionUID = 1L; + + private IPlugInPort plugInPort; + + public GroupAction(IPlugInPort plugInPort) { + super(); + this.plugInPort = plugInPort; + putValue(AbstractAction.NAME, "Group Selection"); + putValue(AbstractAction.ACCELERATOR_KEY, + KeyStroke.getKeyStroke(KeyEvent.VK_G, Toolkit.getDefaultToolkit().getMenuShortcutKeyMask())); + putValue(AbstractAction.SMALL_ICON, IconLoader.Group.getIcon()); + } + + @Override + public void actionPerformed(ActionEvent e) { + LOG.info("Group Selection triggered"); + plugInPort.groupSelectedComponents(); + } + } + + public static class UngroupAction extends AbstractAction { + + private static final long serialVersionUID = 1L; + + private IPlugInPort plugInPort; + + public UngroupAction(IPlugInPort plugInPort) { + super(); + this.plugInPort = plugInPort; + putValue(AbstractAction.NAME, "Ungroup Selection"); + putValue(AbstractAction.ACCELERATOR_KEY, + KeyStroke.getKeyStroke(KeyEvent.VK_U, Toolkit.getDefaultToolkit().getMenuShortcutKeyMask())); + putValue(AbstractAction.SMALL_ICON, IconLoader.Ungroup.getIcon()); + } + + @Override + public void actionPerformed(ActionEvent e) { + LOG.info("Ungroup Selection triggered"); + plugInPort.ungroupSelectedComponents(); + } + } + + public static class EditProjectAction extends AbstractAction { + + private static final long serialVersionUID = 1L; + + private IPlugInPort plugInPort; + + public EditProjectAction(IPlugInPort plugInPort) { + super(); + this.plugInPort = plugInPort; + putValue(AbstractAction.NAME, "Edit Project Settings"); + putValue(AbstractAction.SMALL_ICON, IconLoader.DocumentEdit.getIcon()); + } + + @Override + public void actionPerformed(ActionEvent e) { + LOG.info("Edit Project triggered"); + List properties = plugInPort.getProperties(plugInPort.getCurrentProject()); + PropertyEditorDialog editor = + DialogFactory.getInstance().createPropertyEditorDialog(properties, "Edit Project", true); + editor.setVisible(true); + if (ButtonDialog.OK.equals(editor.getSelectedButtonCaption())) { + plugInPort.applyProperties(plugInPort.getCurrentProject(), properties); + } + // Save default values. + for (PropertyWrapper property : editor.getDefaultedProperties()) { + if (property.getValue() != null) { + plugInPort.setDefaultPropertyValue(Project.class, property.getName(), property.getValue()); + } + } + } + } + + public static class NudgeAction extends AbstractAction { + + private static final long serialVersionUID = 1L; + + private IPlugInPort plugInPort; + + public NudgeAction(IPlugInPort plugInPort) { + super(); + this.plugInPort = plugInPort; + putValue(AbstractAction.NAME, "Nudge"); + putValue(AbstractAction.SMALL_ICON, IconLoader.FitToSize.getIcon()); + putValue(AbstractAction.ACCELERATOR_KEY, + KeyStroke.getKeyStroke(KeyEvent.VK_Q, Toolkit.getDefaultToolkit().getMenuShortcutKeyMask())); + } + + @Override + public void actionPerformed(ActionEvent e) { + LOG.info("Nudge triggered"); + Nudge n = new Nudge(); + boolean metric = ConfigurationManager.getInstance().readBoolean(Presenter.METRIC_KEY, true); + if (metric) { + n.setxOffset(new Size(0d, SizeUnit.mm)); + n.setyOffset(new Size(0d, SizeUnit.mm)); + } else { + n.setxOffset(new Size(0d, SizeUnit.in)); + n.setyOffset(new Size(0d, SizeUnit.in)); + } + List properties = plugInPort.getProperties(n); + PropertyEditorDialog editor = + DialogFactory.getInstance().createPropertyEditorDialog(properties, "Nudge Selection", false); + editor.setVisible(true); + if (ButtonDialog.OK.equals(editor.getSelectedButtonCaption())) { + plugInPort.applyProperties(n, properties); + plugInPort.nudgeSelection(n.getxOffset(), n.getyOffset(), n.getAffectStuckComponents()); + } + } + } + + public static class EditSelectionAction extends AbstractAction { + + private static final long serialVersionUID = 1L; + + private IPlugInPort plugInPort; + + public EditSelectionAction(IPlugInPort plugInPort) { + super(); + this.plugInPort = plugInPort; + putValue(AbstractAction.NAME, "Edit Selection"); + putValue(AbstractAction.ACCELERATOR_KEY, + KeyStroke.getKeyStroke(KeyEvent.VK_E, Toolkit.getDefaultToolkit().getMenuShortcutKeyMask())); + putValue(AbstractAction.SMALL_ICON, IconLoader.EditComponent.getIcon()); + } + + @Override + public void actionPerformed(ActionEvent e) { + LOG.info("Edit Selection triggered"); + List properties = plugInPort.getMutualSelectionProperties(); + if (properties == null || properties.isEmpty()) { + LOG.info("Nothing to edit"); + return; + } + plugInPort.editSelection(); + } + } + + public static class DeleteSelectionAction extends AbstractAction { + + private static final long serialVersionUID = 1L; + + private IPlugInPort plugInPort; + + public DeleteSelectionAction(IPlugInPort plugInPort) { + super(); + this.plugInPort = plugInPort; + putValue(AbstractAction.NAME, "Delete Selection"); + putValue(AbstractAction.ACCELERATOR_KEY, KeyStroke.getKeyStroke(KeyEvent.VK_DELETE, 0)); + putValue(AbstractAction.SMALL_ICON, IconLoader.Delete.getIcon()); + } + + @Override + public void actionPerformed(ActionEvent e) { + LOG.info("Delete Selection triggered"); + plugInPort.deleteSelectedComponents(); + } + } + + public static class SaveAsTemplateAction extends AbstractAction { + + private static final long serialVersionUID = 1L; + + private IPlugInPort plugInPort; + + public SaveAsTemplateAction(IPlugInPort plugInPort) { + super(); + this.plugInPort = plugInPort; + putValue(AbstractAction.NAME, "Save as Variant"); + putValue(AbstractAction.SMALL_ICON, IconLoader.BriefcaseAdd.getIcon()); + } + + @Override + public void actionPerformed(ActionEvent e) { + LOG.info("Save as template triggered"); + String templateName = + JOptionPane.showInputDialog(null, "Variant name:", "Save as Variant", JOptionPane.PLAIN_MESSAGE); + if (templateName != null && !templateName.trim().isEmpty()) { + plugInPort.saveSelectedComponentAsTemplate(templateName); + } + } + } + + public static class SaveAsBlockAction extends AbstractAction { + + private static final long serialVersionUID = 1L; + + private IPlugInPort plugInPort; + + public SaveAsBlockAction(IPlugInPort plugInPort) { + super(); + this.plugInPort = plugInPort; + putValue(AbstractAction.NAME, "Save as Building Block"); + putValue(AbstractAction.SMALL_ICON, IconLoader.ComponentAdd.getIcon()); + } + + @Override + public void actionPerformed(ActionEvent e) { + LOG.info("Save as building block triggered"); + String templateName = + JOptionPane.showInputDialog(null, "Block name:", "Save as Building Block", JOptionPane.PLAIN_MESSAGE); + if (templateName != null && !templateName.trim().isEmpty()) { + plugInPort.saveSelectionAsBlock(templateName); + } + } + } + + public static class ExpandSelectionAction extends AbstractAction { + + private static final long serialVersionUID = 1L; + + private IPlugInPort plugInPort; + private ExpansionMode expansionMode; + + public ExpandSelectionAction(IPlugInPort plugInPort, ExpansionMode expansionMode) { + super(); + this.plugInPort = plugInPort; + this.expansionMode = expansionMode; + switch (expansionMode) { + case ALL: + putValue(AbstractAction.NAME, "All Connected"); + break; + case IMMEDIATE: + putValue(AbstractAction.NAME, "Immediate Only"); + break; + case SAME_TYPE: + putValue(AbstractAction.NAME, "Same Type Only"); + break; + + default: + break; + } + } + + @Override + public void actionPerformed(ActionEvent e) { + LOG.info("Expand Selection triggered: " + expansionMode); + plugInPort.expandSelection(expansionMode); + } + } + + public static class RotateSelectionAction extends AbstractAction { + + private static final long serialVersionUID = 1L; + + private IPlugInPort plugInPort; + private int direction; + + public RotateSelectionAction(IPlugInPort plugInPort, int direction) { + super(); + this.plugInPort = plugInPort; + this.direction = direction; + if (direction > 0) { + putValue(AbstractAction.NAME, "Rotate Clockwise"); + putValue(AbstractAction.SMALL_ICON, IconLoader.RotateCW.getIcon()); + putValue(AbstractAction.ACCELERATOR_KEY, KeyStroke.getKeyStroke(KeyEvent.VK_RIGHT, ActionEvent.ALT_MASK)); + } else { + putValue(AbstractAction.NAME, "Rotate Counterclockwise"); + putValue(AbstractAction.SMALL_ICON, IconLoader.RotateCCW.getIcon()); + putValue(AbstractAction.ACCELERATOR_KEY, KeyStroke.getKeyStroke(KeyEvent.VK_LEFT, ActionEvent.ALT_MASK)); + } + } + + @Override + public void actionPerformed(ActionEvent e) { + LOG.info("Rotate Selection triggered: " + direction); + plugInPort.rotateSelection(direction); + } + } + + public static class MirrorSelectionAction extends AbstractAction { + + private static final long serialVersionUID = 1L; + + private IPlugInPort plugInPort; + private int direction; + + public MirrorSelectionAction(IPlugInPort plugInPort, int direction) { + super(); + this.plugInPort = plugInPort; + this.direction = direction; + if (direction == IComponentTransformer.HORIZONTAL) { + putValue(AbstractAction.NAME, "Mirror Horizontally"); + putValue(AbstractAction.SMALL_ICON, IconLoader.FlipHorizontal.getIcon()); + putValue(AbstractAction.ACCELERATOR_KEY, KeyStroke.getKeyStroke(KeyEvent.VK_H, ActionEvent.ALT_MASK)); + } else { + putValue(AbstractAction.NAME, "Mirror Vertically"); + putValue(AbstractAction.SMALL_ICON, IconLoader.FlipVertical.getIcon()); + putValue(AbstractAction.ACCELERATOR_KEY, KeyStroke.getKeyStroke(KeyEvent.VK_V, ActionEvent.ALT_MASK)); + } + } + + @Override + public void actionPerformed(ActionEvent e) { + LOG.info("Mirror Selection triggered: " + direction); + plugInPort.mirrorSelection(direction); + } + } + + public static class SendToBackAction extends AbstractAction { + + private static final long serialVersionUID = 1L; + + private IPlugInPort plugInPort; + + public SendToBackAction(IPlugInPort plugInPort) { + super(); + this.plugInPort = plugInPort; + putValue(AbstractAction.NAME, "Send Backward"); + putValue(AbstractAction.SMALL_ICON, IconLoader.Back.getIcon()); + putValue(AbstractAction.ACCELERATOR_KEY, KeyStroke.getKeyStroke(KeyEvent.VK_DOWN, ActionEvent.ALT_MASK)); + } + + @Override + public void actionPerformed(ActionEvent e) { + LOG.info("Send to Back triggered"); + plugInPort.sendSelectionToBack(); + } + } + + public static class BringToFrontAction extends AbstractAction { + + private static final long serialVersionUID = 1L; + + private IPlugInPort plugInPort; + + public BringToFrontAction(IPlugInPort plugInPort) { + super(); + this.plugInPort = plugInPort; + putValue(AbstractAction.NAME, "Bring Forward"); + putValue(AbstractAction.SMALL_ICON, IconLoader.Front.getIcon()); + putValue(AbstractAction.ACCELERATOR_KEY, KeyStroke.getKeyStroke(KeyEvent.VK_UP, ActionEvent.ALT_MASK)); + } + + @Override + public void actionPerformed(ActionEvent e) { + LOG.info("Bring to Front triggered"); + plugInPort.bringSelectionToFront(); + } + } + + public static class ConfigAction extends AbstractAction { + + private static final long serialVersionUID = 1L; + + private IPlugInPort plugInPort; + private String configKey; + private String tipKey; + + public ConfigAction(IPlugInPort plugInPort, String title, String configKey, boolean defaultValue, String tipKey) { + super(); + this.plugInPort = plugInPort; + this.configKey = configKey; + this.tipKey = tipKey; + putValue(AbstractAction.NAME, title); + putValue(IView.CHECK_BOX_MENU_ITEM, true); + putValue(AbstractAction.SELECTED_KEY, ConfigurationManager.getInstance().readBoolean(configKey, defaultValue)); + } + + public ConfigAction(IPlugInPort plugInPort, String title, String configKey, boolean defaultValue) { + this(plugInPort, title, configKey, defaultValue, null); + } + + @Override + public void actionPerformed(ActionEvent e) { + LOG.info(getValue(AbstractAction.NAME) + " triggered"); + ConfigurationManager.getInstance().writeValue(configKey, getValue(AbstractAction.SELECTED_KEY)); + if ((Boolean) getValue(AbstractAction.SELECTED_KEY) && tipKey != null + && !ConfigurationManager.getInstance().readBoolean(tipKey + ".dismissed", false)) { + DialogFactory.getInstance().createInfoDialog(tipKey).setVisible(true); + } + plugInPort.refresh(); + } + } + + public static class ThemeAction extends AbstractAction { + + private static final long serialVersionUID = 1L; + + private IPlugInPort plugInPort; + private Theme theme; + + public ThemeAction(IPlugInPort plugInPort, Theme theme) { + super(); + this.plugInPort = plugInPort; + this.theme = theme; + putValue(AbstractAction.NAME, theme.getName()); + putValue(IView.RADIO_BUTTON_GROUP_KEY, "theme"); + putValue(AbstractAction.SELECTED_KEY, plugInPort.getSelectedTheme().getName().equals(theme.getName())); + } + + @Override + public void actionPerformed(ActionEvent e) { + LOG.info(getValue(AbstractAction.NAME) + " triggered"); + plugInPort.setSelectedTheme(theme); + } + } + + public static class ComponentBrowserAction extends AbstractAction { + + private static final long serialVersionUID = 1L; + + private String browserType; + + public ComponentBrowserAction(String browserType) { + super(); + this.browserType = browserType; + putValue(AbstractAction.NAME, browserType); + putValue(IView.RADIO_BUTTON_GROUP_KEY, "componentBrowser"); + + putValue( + AbstractAction.SELECTED_KEY, + browserType.equals(ConfigurationManager.getInstance().readString(ConfigPlugin.COMPONENT_BROWSER, + ConfigPlugin.SEARCHABLE_TREE))); + } + + @Override + public void actionPerformed(ActionEvent e) { + LOG.info(getValue(AbstractAction.NAME) + " triggered"); + ConfigurationManager.getInstance().writeValue(ConfigPlugin.COMPONENT_BROWSER, browserType); + } + } + + + public static class RenumberAction extends AbstractAction { + + private static final long serialVersionUID = 1L; + + private IPlugInPort plugInPort; + private boolean xAxisFirst; + + public RenumberAction(IPlugInPort plugInPort, boolean xAxisFirst) { + super(); + this.plugInPort = plugInPort; + this.xAxisFirst = xAxisFirst; + putValue(AbstractAction.NAME, xAxisFirst ? "Top-to-Bottom" : "Left-to-Right"); + } + + @Override + public void actionPerformed(ActionEvent e) { + LOG.info(getValue(AbstractAction.NAME) + " triggered"); + plugInPort.renumberSelectedComponents(xAxisFirst); + } + } +} diff --git a/diylc/diylc-swing/src/org/diylc/swing/plugins/tree/TreePanel.java b/diylc/diylc-swing/src/org/diylc/swing/plugins/tree/TreePanel.java index 990e989e..0eb58165 100644 --- a/diylc/diylc-swing/src/org/diylc/swing/plugins/tree/TreePanel.java +++ b/diylc/diylc-swing/src/org/diylc/swing/plugins/tree/TreePanel.java @@ -1,716 +1,719 @@ -/* - * - * DIY Layout Creator (DIYLC). Copyright (c) 2009-2018 held jointly by the individual authors. - * - * This file is part of DIYLC. - * - * DIYLC is free software: you can redistribute it and/or modify it under the terms of the GNU - * General Public License as published by the Free Software Foundation, either version 3 of the - * License, or (at your option) any later version. - * - * DIYLC is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even - * the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General - * Public License for more details. - * - * You should have received a copy of the GNU General Public License along with DIYLC. If not, see - * . - */ -package org.diylc.swing.plugins.tree; - -import java.awt.AlphaComposite; -import java.awt.Color; -import java.awt.Component; -import java.awt.Dimension; -import java.awt.Graphics; -import java.awt.Graphics2D; -import java.awt.GridBagConstraints; -import java.awt.GridBagLayout; -import java.awt.event.ActionEvent; -import java.awt.event.ActionListener; -import java.awt.event.FocusAdapter; -import java.awt.event.FocusEvent; -import java.awt.event.MouseAdapter; -import java.awt.event.MouseEvent; -import java.awt.event.MouseListener; -import java.util.ArrayList; -import java.util.Collection; -import java.util.Collections; -import java.util.HashMap; -import java.util.HashSet; -import java.util.Iterator; -import java.util.List; -import java.util.Map; -import java.util.Map.Entry; - -import javax.swing.AbstractAction; -import javax.swing.Icon; -import javax.swing.JMenu; -import javax.swing.JMenuItem; -import javax.swing.JPanel; -import javax.swing.JPopupMenu; -import javax.swing.JScrollPane; -import javax.swing.JSeparator; -import javax.swing.JTextField; -import javax.swing.JTree; -import javax.swing.SwingUtilities; -import javax.swing.ToolTipManager; -import javax.swing.event.DocumentEvent; -import javax.swing.event.DocumentListener; -import javax.swing.event.PopupMenuEvent; -import javax.swing.event.PopupMenuListener; -import javax.swing.event.TreeSelectionEvent; -import javax.swing.event.TreeSelectionListener; -import javax.swing.tree.DefaultMutableTreeNode; -import javax.swing.tree.DefaultTreeCellRenderer; -import javax.swing.tree.DefaultTreeModel; -import javax.swing.tree.TreePath; -import javax.swing.tree.TreeSelectionModel; - -import org.apache.log4j.Logger; -import org.diylc.appframework.miscutils.ConfigurationManager; -import org.diylc.appframework.miscutils.IConfigListener; -import org.diylc.common.ComponentType; -import org.diylc.common.IBlockProcessor.InvalidBlockException; -import org.diylc.common.IPlugInPort; -import org.diylc.core.IDIYComponent; -import org.diylc.core.Template; -import org.diylc.images.IconLoader; -import org.diylc.presenter.ComponentProcessor; -import org.diylc.swing.plugins.toolbox.ComponentButtonFactory; - -public class TreePanel extends JPanel { - - private static final long serialVersionUID = 1L; - - private static final Logger LOG = Logger.getLogger(TreePanel.class); - - public static final String COMPONENT_SHORTCUT_KEY = "componentShortcuts"; - - private DefaultTreeModel treeModel; - private JTree tree; - private JScrollPane treeScroll; - private JTextField searchField; - private DefaultMutableTreeNode recentNode; - private DefaultMutableTreeNode blocksNode; - private List recentComponents; - private List blocks; - - private IPlugInPort plugInPort; - - private JPopupMenu popup; - - public TreePanel(IPlugInPort plugInPort) { - this.plugInPort = plugInPort; - setLayout(new GridBagLayout()); - - GridBagConstraints gbc = new GridBagConstraints(); - gbc.gridx = 0; - gbc.gridy = 0; - gbc.fill = GridBagConstraints.HORIZONTAL; - gbc.weighty = 0; - gbc.gridwidth = 1; - - add(getSearchField(), gbc); - - gbc.gridy++; - - gbc.fill = GridBagConstraints.BOTH; - gbc.weighty = 1; - gbc.weightx = 1; - - add(getTreeScroll(), gbc); - - setPreferredSize(new Dimension(240, 200)); - - ConfigurationManager.getInstance().addConfigListener(IPlugInPort.RECENT_COMPONENTS_KEY, new IConfigListener() { - - @SuppressWarnings("unchecked") - @Override - public void valueChanged(String key, Object value) { - List newComponents = (List) value; - if (newComponents != null - && !new HashSet(newComponents).equals(new HashSet(TreePanel.this.recentComponents))) { - LOG.info("Detected recent component change"); - refreshRecentComponents(newComponents); - } else - LOG.info("Detected no recent component change"); - TreePanel.this.recentComponents = new ArrayList(newComponents); - } - }); - - ConfigurationManager.getInstance().addConfigListener(IPlugInPort.BLOCKS_KEY, new IConfigListener() { - - @SuppressWarnings("unchecked") - @Override - public void valueChanged(String key, Object value) { - Map>> newBlocks = (Map>>) value; - if (newBlocks != null) { - List blockNames = new ArrayList(newBlocks.keySet()); - Collections.sort(blockNames); - if (!blockNames.equals(TreePanel.this.blocks)) { - LOG.info("Detected block change"); - refreshBlocks(blockNames); - } else - LOG.info("Detected no block change"); - } else - LOG.info("Detected no block change"); - } - }); - - getTree().expandRow(0); - } - - public JScrollPane getTreeScroll() { - if (treeScroll == null) { - treeScroll = new JScrollPane(getTree()); - treeScroll.setHorizontalScrollBarPolicy(JScrollPane.HORIZONTAL_SCROLLBAR_NEVER); - } - return treeScroll; - } - - public DefaultMutableTreeNode getRecentNode() { - if (this.recentNode == null) { - this.recentNode = new DefaultMutableTreeNode(new Payload("(Recently Used)", null), true); - @SuppressWarnings("unchecked") - List recent = - (List) ConfigurationManager.getInstance().readObject(IPlugInPort.RECENT_COMPONENTS_KEY, null); - if (recent != null) { - this.recentComponents = new ArrayList(recent); - refreshRecentComponents(recent); - } else { - this.recentComponents = new ArrayList(); - } - } - return this.recentNode; - } - - public DefaultMutableTreeNode getBlocksNode() { - if (this.blocksNode == null) { - this.blocksNode = new DefaultMutableTreeNode(new Payload("(Building Blocks)", null), true); - @SuppressWarnings("unchecked") - Map>> newBlocks = - (Map>>) ConfigurationManager.getInstance().readObject( - IPlugInPort.BLOCKS_KEY, null); - if (newBlocks != null) { - List blockNames = new ArrayList(newBlocks.keySet()); - Collections.sort(blockNames); - refreshBlocks(blockNames); - this.blocks = blockNames; - } else { - this.blocks = new ArrayList(); - } - } - return this.blocksNode; - } - - @SuppressWarnings("unchecked") - private void refreshRecentComponents(List recentComponentClassList) { - getRecentNode().removeAllChildren(); - for (String componentClassName : recentComponentClassList) { - final ComponentType componentType; - try { - componentType = - ComponentProcessor.getInstance().extractComponentTypeFrom( - (Class>) Class.forName(componentClassName)); - Payload payload = new Payload(componentType, new MouseAdapter() { - - @Override - public void mouseClicked(MouseEvent e) { - if (plugInPort.getNewComponentTypeSlot() != componentType) - plugInPort.setNewComponentTypeSlot(componentType, null); - } - }); - final DefaultMutableTreeNode componentNode = new DefaultMutableTreeNode(payload, false); - String text = getSearchField().getText(); - boolean visible = - text.trim().length() == 0 || componentType.getName().toLowerCase().contains(text.toLowerCase()) - || componentType.getDescription().toLowerCase().contains(text.toLowerCase()) - || componentType.getCategory().toLowerCase().contains(text.toLowerCase()); - payload.setVisible(visible); - getRecentNode().add(componentNode); - } catch (ClassNotFoundException e) { - LOG.error("Could not create recent component button for " + componentClassName, e); - } - } - getTreeModel().nodeStructureChanged(getRecentNode()); - } - - private void refreshBlocks(List blocks) { - getBlocksNode().removeAllChildren(); - for (final String block : blocks) { - Payload payload = new Payload(block, new MouseAdapter() { - - @Override - public void mouseClicked(MouseEvent e) { - if (e == null || SwingUtilities.isLeftMouseButton(e)) { - try { - plugInPort.loadBlock(block); - } catch (InvalidBlockException e1) { - // TODO Auto-generated catch block - e1.printStackTrace(); - } - } - } - }); - final DefaultMutableTreeNode componentNode = new DefaultMutableTreeNode(payload, false); - String text = getSearchField().getText(); - boolean visible = text.trim().length() == 0 || block.toLowerCase().contains(text.toLowerCase()); - payload.setVisible(visible); - getBlocksNode().add(componentNode); - } - getTreeModel().nodeStructureChanged(getBlocksNode()); - } - - public DefaultTreeModel getTreeModel() { - if (treeModel == null) { - final DefaultMutableTreeNode rootNode = new DefaultMutableTreeNode("Components", true); - rootNode.add(getRecentNode()); - rootNode.add(getBlocksNode()); - Map> componentTypes = plugInPort.getComponentTypes(); - List categories = new ArrayList(componentTypes.keySet()); - Collections.sort(categories); - for (String category : categories) { - final DefaultMutableTreeNode categoryNode = new DefaultMutableTreeNode(new Payload(category, null)); - rootNode.add(categoryNode); - for (final ComponentType type : componentTypes.get(category)) { - final DefaultMutableTreeNode componentNode = new DefaultMutableTreeNode(new Payload(type, new MouseAdapter() { - - @Override - public void mouseClicked(MouseEvent e) { - plugInPort.setNewComponentTypeSlot(type, null); - } - }), false); - categoryNode.add(componentNode); - } - } - treeModel = new DefaultTreeModel(rootNode); - } - return treeModel; - } - - public JTree getTree() { - if (tree == null) { - tree = new JTree(getTreeModel()); - tree.setRootVisible(false); - tree.setCellRenderer(new ComponentCellRenderer()); - tree.getSelectionModel().setSelectionMode(TreeSelectionModel.SINGLE_TREE_SELECTION); - tree.setRowHeight(0); - ToolTipManager.sharedInstance().registerComponent(tree); - - tree.addTreeSelectionListener(new TreeSelectionListener() { - - @Override - public void valueChanged(TreeSelectionEvent e) { - DefaultMutableTreeNode node = (DefaultMutableTreeNode) e.getPath().getLastPathComponent(); - if (node != null && node.getUserObject() != null) { - Payload payload = (Payload) node.getUserObject(); - if (payload.getClickListener() != null) { - payload.getClickListener().mouseClicked(null); - } - } - } - }); - - tree.addMouseListener(new MouseAdapter() { - - @Override - public void mouseClicked(MouseEvent e) { - if (e.getClickCount() != 1) - return; - - if (SwingUtilities.isRightMouseButton(e)) { - int row = tree.getClosestRowForLocation(e.getX(), e.getY()); - tree.setSelectionRow(row); - getPopup().show(e.getComponent(), e.getX(), e.getY()); - } else { - TreePath path = tree.getClosestPathForLocation(e.getX(), e.getY()); - DefaultMutableTreeNode node = (DefaultMutableTreeNode) path.getLastPathComponent(); - if (node != null && node.getUserObject() != null) { - Payload payload = (Payload) node.getUserObject(); - if (payload.getClickListener() != null) { - payload.getClickListener().mouseClicked(e); - } - } - } - } - }); - } - return tree; - } - - public JPopupMenu getPopup() { - if (popup == null) { - popup = new JPopupMenu(); - popup.add("Loading..."); - popup.addPopupMenuListener(new PopupMenuListener() { - - @Override - public void popupMenuWillBecomeVisible(PopupMenuEvent e) { - popup.removeAll(); - - DefaultMutableTreeNode selectedNode = (DefaultMutableTreeNode) tree.getLastSelectedPathComponent(); - - if (selectedNode == null || selectedNode.getUserObject() == null) - return; - - Payload payload = (Payload) selectedNode.getUserObject(); - - final ComponentType componentType = payload.getComponentType(); - - final String identifier = - componentType == null ? "block:" + payload.toString() : componentType.getInstanceClass() - .getCanonicalName(); - - JMenu shortcutSubmenu = new JMenu("Assign Shortcut"); - final JMenuItem noneItem = new JMenuItem("None"); - noneItem.addActionListener(new ActionListener() { - - @SuppressWarnings("unchecked") - @Override - public void actionPerformed(ActionEvent e) { - HashMap map = - (HashMap) ConfigurationManager.getInstance().readObject(COMPONENT_SHORTCUT_KEY, null); - if (map == null) - map = new HashMap(); - - Iterator> it = map.entrySet().iterator(); - while (it.hasNext()) { - Entry item = it.next(); - if (item.getValue().equals(identifier)) - it.remove(); - } - - ConfigurationManager.getInstance().writeValue(COMPONENT_SHORTCUT_KEY, map); - - TreePanel.this.invalidate(); - TreePanel.this.repaint(); - } - - }); - - shortcutSubmenu.add(noneItem); - - for (int i = 1; i <= 12; i++) { - final JMenuItem item = new JMenuItem("F" + i); - item.addActionListener(new ActionListener() { - - @SuppressWarnings("unchecked") - @Override - public void actionPerformed(ActionEvent e) { - HashMap map = - (HashMap) ConfigurationManager.getInstance().readObject(COMPONENT_SHORTCUT_KEY, - null); - if (map == null) - map = new HashMap(); - - if (map.containsKey(item.getText())) - map.remove(item.getText()); - - Iterator> it = map.entrySet().iterator(); - while (it.hasNext()) { - Entry item = it.next(); - if (item.getValue().equals(identifier)) - it.remove(); - } - - map.put(item.getText(), identifier); - - ConfigurationManager.getInstance().writeValue(COMPONENT_SHORTCUT_KEY, map); - - TreePanel.this.invalidate(); - TreePanel.this.repaint(); - } - }); - shortcutSubmenu.add(item); - } - - if (componentType != null) { - popup.add(new SelectAllAction(plugInPort)); - popup.add(shortcutSubmenu); - popup.add(new JSeparator()); - - List