diff --git a/diylc/diylc-core/src/org/diylc/common/IPlugInPort.java b/diylc/diylc-core/src/org/diylc/common/IPlugInPort.java index 35fdfeb1..9b3991af 100644 --- a/diylc/diylc-core/src/org/diylc/common/IPlugInPort.java +++ b/diylc/diylc-core/src/org/diylc/common/IPlugInPort.java @@ -183,6 +183,11 @@ public interface IPlugInPort extends ISelectionProcessor, IMouseProcessor, IKeyP */ void pasteComponents(Collection> components); + /** + * Duplicates selected components and places them nearby. + */ + void duplicateSelection(); + /** * Deletes all the selected components from the project. */ diff --git a/diylc/diylc-core/src/org/diylc/presenter/InstantiationManager.java b/diylc/diylc-core/src/org/diylc/presenter/InstantiationManager.java index 11858fff..a8bdff07 100644 --- a/diylc/diylc-core/src/org/diylc/presenter/InstantiationManager.java +++ b/diylc/diylc-core/src/org/diylc/presenter/InstantiationManager.java @@ -164,7 +164,7 @@ public class InstantiationManager { // Update the location according to mouse location updateSingleClick(scaledPoint, snapToGrid, gridSpacing); } - + /** * Updates location of component slot based on the new mouse location. * diff --git a/diylc/diylc-core/src/org/diylc/presenter/Presenter.java b/diylc/diylc-core/src/org/diylc/presenter/Presenter.java index 12019309..e4b04317 100644 --- a/diylc/diylc-core/src/org/diylc/presenter/Presenter.java +++ b/diylc/diylc-core/src/org/diylc/presenter/Presenter.java @@ -1410,6 +1410,38 @@ public class Presenter implements IPlugInPort { instantiationManager.getFirstControlPoint()); } + @Override + public void duplicateSelection() { + LOG.info("duplicateSelection()"); + if (selectedComponents.isEmpty()) { + LOG.debug("Nothing to duplicate"); + return; + } + Project oldProject = currentProject.clone(); + Set> newSelection = new HashSet>(); + + int grid = (int) currentProject.getGridSpacing().convertToPixels(); + for (IDIYComponent component : this.selectedComponents) { + try { + IDIYComponent cloned = component.clone(); + newSelection.add(cloned); + for (int i = 0; i < component.getControlPointCount(); i++) { + Point p = component.getControlPoint(i); + Point newPoint = new Point(p.x + grid, p.y + grid); + cloned.setControlPoint(newPoint, i); + } + currentProject.getComponents().add(cloned); + } catch (Exception e) { + } + } + + updateSelection(newSelection); + + messageDispatcher.dispatchMessage(EventType.PROJECT_MODIFIED, oldProject, currentProject.clone(), "Duplicate"); + projectFileManager.notifyFileChange(); + messageDispatcher.dispatchMessage(EventType.REPAINT); + } + @Override public void deleteSelectedComponents() { LOG.info("deleteSelectedComponents()"); diff --git a/diylc/diylc-library/lib/diylc-core.jar b/diylc/diylc-library/lib/diylc-core.jar index 8e7b3d81..12650f1b 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-swing/lib/diylc-core.jar b/diylc/diylc-swing/lib/diylc-core.jar index 8e7b3d81..12650f1b 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 22c3bf5b..4726ee81 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/images/IconLoader.java b/diylc/diylc-swing/src/org/diylc/images/IconLoader.java index 49a92a9b..31571a70 100644 --- a/diylc/diylc-swing/src/org/diylc/images/IconLoader.java +++ b/diylc/diylc-swing/src/org/diylc/images/IconLoader.java @@ -39,7 +39,8 @@ public enum IconLoader { "messages.png"), SearchBox("search-box.png"), Screwdriver("screwdriver.png"), Hammer("hammer.png"), FlipHorizontal( "flip_horizontal.png"), FlipVertical("flip_vertical.png"), MagicWand("magic_wand.png"), PinGrey("pin_grey.png"), PinGreen( "pin_green.png"), CoffeebeanEdit("coffeebean_edit.png"), ApplicationEdit("application_edit.png"), ComponentAdd( - "component_add.png"), History("history.png"), DocumentPlain("document_plain.png"), FitToSize("fit_to_size.png"); + "component_add.png"), History("history.png"), DocumentPlain("document_plain.png"), FitToSize("fit_to_size.png"), DocumentsGear( + "documents_gear.png"); protected String name; diff --git a/diylc/diylc-swing/src/org/diylc/images/documents_gear.png b/diylc/diylc-swing/src/org/diylc/images/documents_gear.png new file mode 100644 index 00000000..3b2261a3 Binary files /dev/null and b/diylc/diylc-swing/src/org/diylc/images/documents_gear.png differ diff --git a/diylc/diylc-swing/src/org/diylc/swing/ActionFactory.java b/diylc/diylc-swing/src/org/diylc/swing/ActionFactory.java index 89eb9336..9d2da20c 100644 --- a/diylc/diylc-swing/src/org/diylc/swing/ActionFactory.java +++ b/diylc/diylc-swing/src/org/diylc/swing/ActionFactory.java @@ -114,6 +114,10 @@ public class ActionFactory { return new PasteAction(plugInPort, clipboard); } + public DuplicateAction createDuplicateAction(IPlugInPort plugInPort) { + return new DuplicateAction(plugInPort); + } + public SelectAllAction createSelectAllAction(IPlugInPort plugInPort) { return new SelectAllAction(plugInPort); } @@ -652,33 +656,6 @@ public class ActionFactory { } } - 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 PasteAction extends AbstractAction { private static final long serialVersionUID = 1L; @@ -710,6 +687,60 @@ public class ActionFactory { } } + 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) { diff --git a/diylc/diylc-swing/src/org/diylc/swing/plugins/canvas/CanvasPlugin.java b/diylc/diylc-swing/src/org/diylc/swing/plugins/canvas/CanvasPlugin.java index cba3dcf1..45a93186 100644 --- a/diylc/diylc-swing/src/org/diylc/swing/plugins/canvas/CanvasPlugin.java +++ b/diylc/diylc-swing/src/org/diylc/swing/plugins/canvas/CanvasPlugin.java @@ -64,6 +64,7 @@ public class CanvasPlugin implements IPlugIn, ClipboardOwner { private ActionFactory.CutAction cutAction; private ActionFactory.CopyAction copyAction; private ActionFactory.PasteAction pasteAction; + private ActionFactory.DuplicateAction duplicateAction; private ActionFactory.EditSelectionAction editSelectionAction; private ActionFactory.DeleteSelectionAction deleteSelectionAction; private ActionFactory.SaveAsTemplateAction saveAsTemplateAction; @@ -138,6 +139,7 @@ public class CanvasPlugin implements IPlugIn, ClipboardOwner { boolean enabled = !plugInPort.getSelectedComponents().isEmpty(); getCutAction().setEnabled(enabled); getCopyAction().setEnabled(enabled); + getDuplicateAction().setEnabled(enabled); try { getPasteAction().setEnabled(clipboard.isDataFlavorAvailable(ComponentTransferable.listFlavor)); } catch (Exception ex) { @@ -172,7 +174,8 @@ public class CanvasPlugin implements IPlugIn, ClipboardOwner { @Override public void keyPressed(KeyEvent e) { - if (plugInPort.keyPressed(e.getKeyCode(), Utils.isMac() ? e.isMetaDown() : e.isControlDown(), e.isShiftDown(), e.isAltDown())) { + if (plugInPort.keyPressed(e.getKeyCode(), Utils.isMac() ? e.isMetaDown() : e.isControlDown(), + e.isShiftDown(), e.isAltDown())) { e.consume(); } } @@ -183,7 +186,8 @@ public class CanvasPlugin implements IPlugIn, ClipboardOwner { @Override public void mouseMoved(MouseEvent e) { canvasPanel.setCursor(plugInPort.getCursorAt(e.getPoint())); - plugInPort.mouseMoved(e.getPoint(), Utils.isMac() ? e.isMetaDown() : e.isControlDown(), e.isShiftDown(), e.isAltDown()); + plugInPort.mouseMoved(e.getPoint(), Utils.isMac() ? e.isMetaDown() : e.isControlDown(), e.isShiftDown(), + e.isAltDown()); } }); @@ -191,8 +195,8 @@ public class CanvasPlugin implements IPlugIn, ClipboardOwner { @Override public void mouseClicked(MouseEvent e) { - plugInPort.mouseClicked(e.getPoint(), e.getButton(), Utils.isMac() ? e.isMetaDown() : e.isControlDown(), e.isShiftDown(), - e.isAltDown(), e.getClickCount()); + plugInPort.mouseClicked(e.getPoint(), e.getButton(), Utils.isMac() ? e.isMetaDown() : e.isControlDown(), + e.isShiftDown(), e.isAltDown(), e.getClickCount()); } }); } @@ -279,6 +283,7 @@ public class CanvasPlugin implements IPlugIn, ClipboardOwner { popupMenu.add(getCutAction()); popupMenu.add(getCopyAction()); popupMenu.add(getPasteAction()); + popupMenu.add(getDuplicateAction()); popupMenu.addSeparator(); popupMenu.add(getEditSelectionAction()); popupMenu.add(getDeleteSelectionAction()); @@ -411,6 +416,13 @@ public class CanvasPlugin implements IPlugIn, ClipboardOwner { return pasteAction; } + public ActionFactory.DuplicateAction getDuplicateAction() { + if (duplicateAction == null) { + duplicateAction = ActionFactory.getInstance().createDuplicateAction(plugInPort); + } + return duplicateAction; + } + public ActionFactory.EditSelectionAction getEditSelectionAction() { if (editSelectionAction == null) { editSelectionAction = ActionFactory.getInstance().createEditSelectionAction(plugInPort); diff --git a/diylc/diylc-swing/src/org/diylc/swing/plugins/edit/EditMenuPlugin.java b/diylc/diylc-swing/src/org/diylc/swing/plugins/edit/EditMenuPlugin.java index b4195b49..be4e3c89 100644 --- a/diylc/diylc-swing/src/org/diylc/swing/plugins/edit/EditMenuPlugin.java +++ b/diylc/diylc-swing/src/org/diylc/swing/plugins/edit/EditMenuPlugin.java @@ -35,6 +35,7 @@ public class EditMenuPlugin implements IPlugIn, ClipboardOwner { private ActionFactory.CutAction cutAction; private ActionFactory.CopyAction copyAction; private ActionFactory.PasteAction pasteAction; + private ActionFactory.DuplicateAction duplicateAction; private ActionFactory.EditSelectionAction editSelectionAction; private ActionFactory.DeleteSelectionAction deleteSelectionAction; private ActionFactory.GroupAction groupAction; @@ -104,6 +105,13 @@ public class EditMenuPlugin implements IPlugIn, ClipboardOwner { return pasteAction; } + public ActionFactory.DuplicateAction getDuplicateAction() { + if (duplicateAction == null) { + duplicateAction = ActionFactory.getInstance().createDuplicateAction(plugInPort); + } + return duplicateAction; + } + public ActionFactory.EditSelectionAction getEditSelectionAction() { if (editSelectionAction == null) { editSelectionAction = ActionFactory.getInstance().createEditSelectionAction(plugInPort); @@ -145,7 +153,7 @@ public class EditMenuPlugin implements IPlugIn, ClipboardOwner { } return bringToFrontAction; } - + public ActionFactory.NudgeAction getNudgeAction() { if (nudgeAction == null) { nudgeAction = ActionFactory.getInstance().createNudgeAction(plugInPort); @@ -196,7 +204,7 @@ public class EditMenuPlugin implements IPlugIn, ClipboardOwner { } return saveAsTemplateAction; } - + public ActionFactory.SaveAsBlockAction getSaveAsBlockAction() { if (saveAsBlockAction == null) { saveAsBlockAction = ActionFactory.getInstance().createSaveAsBlockAction(plugInPort); @@ -217,7 +225,7 @@ public class EditMenuPlugin implements IPlugIn, ClipboardOwner { } return rotateCounterClockwiseAction; } - + public ActionFactory.MirrorSelectionAction getMirrorHorizontallyAction() { if (mirrorHorizontallyAction == null) { mirrorHorizontallyAction = @@ -246,6 +254,7 @@ public class EditMenuPlugin implements IPlugIn, ClipboardOwner { swingUI.injectMenuAction(getCutAction(), EDIT_TITLE); swingUI.injectMenuAction(getCopyAction(), EDIT_TITLE); swingUI.injectMenuAction(getPasteAction(), EDIT_TITLE); + swingUI.injectMenuAction(getDuplicateAction(), EDIT_TITLE); swingUI.injectMenuAction(null, EDIT_TITLE); swingUI.injectMenuAction(actionFactory.createSelectAllAction(plugInPort), EDIT_TITLE); swingUI.injectMenuAction(getEditSelectionAction(), EDIT_TITLE); @@ -265,7 +274,7 @@ public class EditMenuPlugin implements IPlugIn, ClipboardOwner { swingUI.injectMenuAction(getGroupAction(), TRANSFORM_TITLE); swingUI.injectMenuAction(getUngroupAction(), TRANSFORM_TITLE); swingUI.injectMenuAction(null, EDIT_TITLE); -// swingUI.injectMenuAction(getSaveAsTemplateAction(), EDIT_TITLE); + // swingUI.injectMenuAction(getSaveAsTemplateAction(), EDIT_TITLE); swingUI.injectSubmenu(RENUMBER_TITLE, IconLoader.Sort.getIcon(), EDIT_TITLE); swingUI.injectMenuAction(getRenumberXAxisAction(), RENUMBER_TITLE); swingUI.injectMenuAction(getRenumberYAxisAction(), RENUMBER_TITLE); @@ -305,6 +314,7 @@ public class EditMenuPlugin implements IPlugIn, ClipboardOwner { boolean enabled = !plugInPort.getSelectedComponents().isEmpty(); getCutAction().setEnabled(enabled); getCopyAction().setEnabled(enabled); + getDuplicateAction().setEnabled(enabled); try { getPasteAction().setEnabled(clipboard.isDataFlavorAvailable(ComponentTransferable.listFlavor)); } catch (Exception e) { diff --git a/diylc/diylc-swing/update.xml b/diylc/diylc-swing/update.xml index e3d8e80a..d9f2075a 100644 --- a/diylc/diylc-swing/update.xml +++ b/diylc/diylc-swing/update.xml @@ -1774,6 +1774,10 @@ NEW_FEATURE Ability to change PCB board shape from rectangular to oval. + + NEW_FEATURE + Duplicate selection option in Edit menu and popup menu (Ctrl+D). + NEW_FEATURE Added bitchin new splash screen