From d84f7dadf5e8eb9dbe6cdb5e55d182ae2e923846 Mon Sep 17 00:00:00 2001 From: Branislav Stojkovic Date: Sat, 6 May 2017 13:56:54 +0200 Subject: [PATCH] Duplicate selection option in Edit menu and popup menu (Ctrl+D) --- .../src/org/diylc/common/IPlugInPort.java | 5 ++ .../diylc/presenter/InstantiationManager.java | 2 +- .../src/org/diylc/presenter/Presenter.java | 32 +++++++ diylc/diylc-library/lib/diylc-core.jar | Bin 241025 -> 241025 bytes diylc/diylc-swing/lib/diylc-core.jar | Bin 241025 -> 241025 bytes diylc/diylc-swing/library/main.jar | Bin 407807 -> 407807 bytes .../src/org/diylc/images/IconLoader.java | 3 +- .../src/org/diylc/images/documents_gear.png | Bin 0 -> 782 bytes .../src/org/diylc/swing/ActionFactory.java | 85 ++++++++++++------ .../swing/plugins/canvas/CanvasPlugin.java | 20 ++++- .../swing/plugins/edit/EditMenuPlugin.java | 18 +++- diylc/diylc-swing/update.xml | 4 + 12 files changed, 132 insertions(+), 37 deletions(-) create mode 100644 diylc/diylc-swing/src/org/diylc/images/documents_gear.png 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 8e7b3d8116ae038ed3224321b144d08313884715..12650f1b665bbeae59b9769b1878e8501ab520f2 100644 GIT binary patch delta 4202 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 delta 4202 zcmYjTX|}$-Yz^;S@kiQ zY)qzyab`Oo*&SyNcr3f(v;Z*-VV)QXIxSC(L$HX^@?o5IT|AAFo1B2stI`*x4Ke_w zJmIdjcmIE4u-%cP(Zy4Z!JH8cd5UwY=P~ZC3PkX?8jFx<V`qahBx#foa7J(sa9fcKQUjG7;Z3iBtRL5O2 z2*(T#QD|T8F^pt=SPNm;@M+|~bwnWHS6<18+KW$KLU&j1GEz7CxQV{l!_Og8CVy)( znWD7syxjDjC91#HHR@-K_`$aeBd+>o^g^8Ne~}`+o^>G%d~P;jWk3gE!gw<^aDT$f zgi`|V5I+AxwWMi-Uyr!xElnnOD=p8%rR9Eb5ZT91xrw`J@eUhF1BK5TMwmI92Obf* zn*4T0t?Ub{ZShESkcdwuJs|W+?zF}DURj5n5I@ZSll%`A4x|O1FMX2adz-gWpXQ2j zl>e;eO7eGGe93OFD?;ZQdr6xqaM>k%eYDQH;|SF|KF5lw z^%2xb+pc)R;SB-*Kz+=+OQ_Ph_rIph4IlKPip_`JNIrXnEB|rqO_Gu;$@;x~M623b~E72K}_$#|>y6+H*qDHXG|-S(plKT+!0M8LEfptKNE3zUpHc zqQnXeuvA%#Yj*IwEZP0UK80lHK+%tgzngf5NRqqoBC>g?uq9ISgy>6Tzn5^cvhRW$ z{nwD|{XC$Oo78VllrDNqp|Y|3?jyVbE9JSN+>E81<IMNDyovSOW;AASKe#=I>SO%OB2Po+DDe)_jgC85m+4iXjq{Kbv#Y!TpIz*r& z_I3Q42(|@s_*Vf}78Iv%3Nw+Y+oFw#>pkI2Wb^|um&m4W@d}a4kHs1y(Ngm2PgqM& z()?&6eFP?S=p&yZO;BHHLu7`d%p~%Wvz$SskBdA& za?o2IC6eMNZxNY4R!$(Y&0oGtMMIyJZ_o}71jsDDGS+7Xy5__0!$v{-(xbL3dwqbd z?5AJ$mv)xS2{MC1f0`)YqGT08@*ol&PII^=@g<|_Z>Guuvd4u=_$0xE9W#w$&qT;z z(qzw(@Bsvq<6K!rq&`{(Q2KwzNPB$qmK*b>6_MXxmv#76u$0Bi$wb-{rNW;H%NHp! zUcvX-60lTG7C`izba@dKp&4?WGm;A%r6*b}xANsEBJP{yP$H8G`nl6uh&N!E1Li+omxDY)aH zc`!?zu}0DssX93GT(!aqHMa9rIFaZ$6^o7OAI7WkuyOrU7AS8Nep#R1Qm+%kpwjX<$DQgD#{S_lHu>J?@UylD4a@!KR1wB zEo7w3u?snK(Lyx?BfngzW+HkeK|6p+Nopbn?@dy#B0fq|uOrT1#Mrt>MWH-!u?k0A zWZ<#IDiURO15Qohy!9z64P}Q^wFogcRn11cV4&v`H5cVo zOSsO3C2aRhNS*emO)>zr_YzEHxS2Vsl|x(S-hVf17nx7+_qdLV4T+q zwE(f$!2hjKDJaKebKQg4Y8J{OhjDfe_q*G`J2@%>?IF496~t}1Y6{l844vNezw>^BSyUd!{> z8`y1N)SD_1{XTk={oU4azVvl0pIgUuJ@Qz;JdgW1m&f(I*7Lk83_QD@=X2k{eP(T7 z|Iaq?-bZZYy<~0Vy?tWHuK8RiC7)g!=*5R><+zMU0_EoL4ijvk2}b_&r(7acRZucgVo5VtA=w z4=!Q9@)C~!x&+P(^iPy>{Y(Q-mcsm?A5_M13k+;7rB##FJssfy$7RB`cR z)_Lx=I_EuS$nMn~ms-tn$E!J?s^Ph(*Kj`-HSBk-hV%MtW50}TY(KJ%`;xVcVYR%U z>RPs6HE`s1uD@(M>yK?`f7rLXKCDjp;;=8*v2jZs8?V%H@i9BNc=is~pV+~dz^JlmR6JtGE)|F9znf)!H-DVu9<>nl z$$Q{q3wUV{`vo+>GC?kE;E%`;1_thBxyHah44kzOKK|gpe;+?a*$9UY^4vyvRDey5 zDhAPJKlhceA1)`zNB6Uz!&`8OAjcc{fq^zntdBPEohI(9r-|##dm9b`;`Y7`mj&>y YAy00GeSuus40{5+*35BFA5h_c0~|-C9{>OV diff --git a/diylc/diylc-swing/lib/diylc-core.jar b/diylc/diylc-swing/lib/diylc-core.jar index 8e7b3d8116ae038ed3224321b144d08313884715..12650f1b665bbeae59b9769b1878e8501ab520f2 100644 GIT binary patch delta 4202 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 delta 4202 zcmYjTX|}$-Yz^;S@kiQ zY)qzyab`Oo*&SyNcr3f(v;Z*-VV)QXIxSC(L$HX^@?o5IT|AAFo1B2stI`*x4Ke_w zJmIdjcmIE4u-%cP(Zy4Z!JH8cd5UwY=P~ZC3PkX?8jFx<V`qahBx#foa7J(sa9fcKQUjG7;Z3iBtRL5O2 z2*(T#QD|T8F^pt=SPNm;@M+|~bwnWHS6<18+KW$KLU&j1GEz7CxQV{l!_Og8CVy)( znWD7syxjDjC91#HHR@-K_`$aeBd+>o^g^8Ne~}`+o^>G%d~P;jWk3gE!gw<^aDT$f zgi`|V5I+AxwWMi-Uyr!xElnnOD=p8%rR9Eb5ZT91xrw`J@eUhF1BK5TMwmI92Obf* zn*4T0t?Ub{ZShESkcdwuJs|W+?zF}DURj5n5I@ZSll%`A4x|O1FMX2adz-gWpXQ2j zl>e;eO7eGGe93OFD?;ZQdr6xqaM>k%eYDQH;|SF|KF5lw z^%2xb+pc)R;SB-*Kz+=+OQ_Ph_rIph4IlKPip_`JNIrXnEB|rqO_Gu;$@;x~M623b~E72K}_$#|>y6+H*qDHXG|-S(plKT+!0M8LEfptKNE3zUpHc zqQnXeuvA%#Yj*IwEZP0UK80lHK+%tgzngf5NRqqoBC>g?uq9ISgy>6Tzn5^cvhRW$ z{nwD|{XC$Oo78VllrDNqp|Y|3?jyVbE9JSN+>E81<IMNDyovSOW;AASKe#=I>SO%OB2Po+DDe)_jgC85m+4iXjq{Kbv#Y!TpIz*r& z_I3Q42(|@s_*Vf}78Iv%3Nw+Y+oFw#>pkI2Wb^|um&m4W@d}a4kHs1y(Ngm2PgqM& z()?&6eFP?S=p&yZO;BHHLu7`d%p~%Wvz$SskBdA& za?o2IC6eMNZxNY4R!$(Y&0oGtMMIyJZ_o}71jsDDGS+7Xy5__0!$v{-(xbL3dwqbd z?5AJ$mv)xS2{MC1f0`)YqGT08@*ol&PII^=@g<|_Z>Guuvd4u=_$0xE9W#w$&qT;z z(qzw(@Bsvq<6K!rq&`{(Q2KwzNPB$qmK*b>6_MXxmv#76u$0Bi$wb-{rNW;H%NHp! zUcvX-60lTG7C`izba@dKp&4?WGm;A%r6*b}xANsEBJP{yP$H8G`nl6uh&N!E1Li+omxDY)aH zc`!?zu}0DssX93GT(!aqHMa9rIFaZ$6^o7OAI7WkuyOrU7AS8Nep#R1Qm+%kpwjX<$DQgD#{S_lHu>J?@UylD4a@!KR1wB zEo7w3u?snK(Lyx?BfngzW+HkeK|6p+Nopbn?@dy#B0fq|uOrT1#Mrt>MWH-!u?k0A zWZ<#IDiURO15Qohy!9z64P}Q^wFogcRn11cV4&v`H5cVo zOSsO3C2aRhNS*emO)>zr_YzEHxS2Vsl|x(S-hVf17nx7+_qdLV4T+q zwE(f$!2hjKDJaKebKQg4Y8J{OhjDfe_q*G`J2@%>?IF496~t}1Y6{l844vNezw>^BSyUd!{> z8`y1N)SD_1{XTk={oU4azVvl0pIgUuJ@Qz;JdgW1m&f(I*7Lk83_QD@=X2k{eP(T7 z|Iaq?-bZZYy<~0Vy?tWHuK8RiC7)g!=*5R><+zMU0_EoL4ijvk2}b_&r(7acRZucgVo5VtA=w z4=!Q9@)C~!x&+P(^iPy>{Y(Q-mcsm?A5_M13k+;7rB##FJssfy$7RB`cR z)_Lx=I_EuS$nMn~ms-tn$E!J?s^Ph(*Kj`-HSBk-hV%MtW50}TY(KJ%`;xVcVYR%U z>RPs6HE`s1uD@(M>yK?`f7rLXKCDjp;;=8*v2jZs8?V%H@i9BNc=is~pV+~dz^JlmR6JtGE)|F9znf)!H-DVu9<>nl z$$Q{q3wUV{`vo+>GC?kE;E%`;1_thBxyHah44kzOKK|gpe;+?a*$9UY^4vyvRDey5 zDhAPJKlhceA1)`zNB6Uz!&`8OAjcc{fq^zntdBPEohI(9r-|##dm9b`;`Y7`mj&>y YAy00GeSuus40{5+*35BFA5h_c0~|-C9{>OV diff --git a/diylc/diylc-swing/library/main.jar b/diylc/diylc-swing/library/main.jar index 22c3bf5bb4f14b56f5cfef63cffa7d28a0da84e7..4726ee810d4dbd4cb3ae84b23a84333dd8510934 100644 GIT binary patch delta 4341 zcmZWsd03TY7XQBQ{oa@La#=2$S3nU^M1cz`q`8&~E(ju-ESd}Ihzn#rxzv+BrH@OE zAi?JorlbajnKU$h?m6Q;ViqY)nhPV0m1Y{s>VnFA_ndQ^sqvrt<1D}PJLkObd#~Ls z0o^SDrqqc{b(JJ%NqR81qR7AfY?VmN{)jeJSntjum zhrO@Nn7?PetV+@$XRTK-w`!w0d3ep1z}Hm>^9cUN1fVf0k^yjw33mn%pD5e;q)7oM;Am~bH+i`(OQm2zaVAa-i zbCcH4#a(I&b~j?1$2ux9Uo|%VXP@GN9E_-0Us;H)1XjQ81cc@KHna>o8G;&f&JM=D zOX~K!LCo08w*&xNlP_i^-z-A#ujWBm&33x+K$V*$jqIVx&oL9Pm(pm)C@x1+6dhWsm{8`<(MM4M;HDLtS_!%F#m zw5@zy-suB2YoVM)wypAGKd`O%SoZe@34F=C0ZoR4SfN#$jfU+KD$gF3v2NW7d8z`3 z_Wt_AN285JZFDk*qs^|BqxG48lP6)={(s23@c@;)vMXt9pd`5`!u(1*WhZ@2tvoLf z%HC{}pF=4Fe~_!Z!FHuXZbIAf2XZv>HFwEtP-ua-G7h~*EXrf_9u82l10XlRrlg^F zalDd=-YRJx_PP6 z6Ir4Q6a~(a9=}@IiRi*QB^|v{85&#FKt-^>#6nf6CT=QKjEX_>c^UKR#$9n8_s#*oVcIOeJE8^n@uK%HaQ4s1i4#PHqG8&lXDIJ8+)*`H9(SJT*8PZ-s!S+UA!O~^%C2LRP21Rf zM9Di?A$l9i**zT4xxH*5+J^39eeo$czPe!Y72|!)a@F!J##{K(KIW&Ff67|nfz?ZD z*k6J`@Pv960PlmIYb?MO#4TI3PW_2X(s!;}(`X|(zn)q2<2P6rYB+j_d1F84@3Kc& zxvrH(;Fai9RjU)wv?jfzT{8AC$E!Ft9VD3bWOwy8t{}lz{SNs&tZF89k{7BjLcU93 z>PeJZ7O5`53*$CMeTYZXDOpX%^#z^Yz2C{W*@;3M{h4AMpgzJ=8=kD1v}<8P=-Vf% zUMRIXMO}{65ozjCyq`ZVP*)?(w=)_BM;W(m;A%&}g^ z%C@lI$C$Ln2;rjJ&?o=LKUkp{jOwf$>dL{yyh=^jmx_E;s3$ob4ILQ)TvsuW7qiGrVs4&+B+D zjyQD-?~Au!)%!dUFL3D|ei5}TtK?=}%GxU4h@=tW=d!!KB`GdKOH++I5}PP|^&R`U z3x01^o#Za?+ebh6E8hz=+U$Eg@wXp++K2b}Q2UFkUAxC)0C=`=_}Qc-weV5)%c*T{ z;S&K|ZsFqr^l9aj0W5FjQyng=_CqTl0DpP6@v#6h+jtUykJ|W@{|0)uQ{d=!{ydmB zwDSo7F0@l>PzQ(Kj#^F!e-T`VI(QlY_fDP*;FV6E3821{X9I}6&!+>}bf3=vaN|Co z4`9jzz6ijv2NdJ?keCY|@|ocJ_91@(K-425-1LY_+%)37gc-XG2VNH_9k6i!8gLWQkY+pWh3dz(`qO zcY9?q4^qquhG;7liut!9=74J)6E6Yyn2EUdL<(4*^&lS2gGwl7l96o|sStC(Ebug|o@ANs zDW+iwPs3%uC(Mfor+Lv3j(8DaxHpY=gEv+G*_&D(??Ws2#D`{Ru~6`978>|fhh>B> zjiuCAq(k*PzEonmA7vf!qpVK)4Yq|* zaAr8Q{6#ojt9}vW+TsA65fqcvmv~O~C7#HBWGU)L=efBbou9FhB)&3|EKeh8U(@@O z>u`Tc?;S;5tc{|WD^WE0xB=9~2Lni<7)W5*K$3cKAiV&iqD3zJU#nuOUrUgd8Y_IY zQ_%unWRDn{*~>AssKyxLo)Ak7RmW0{#pXDzHX8XQ8;xOj9J$KlC|HfBhUUi;^FQN> zdBh-+ws#Qq>N%Kt%^ysCTpmnK#|@!9zdM8u;7tb@oj?QLkwEKxoIn$rmMHL>rXo?y F_zwtm>!ttz delta 4341 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 M07*qoM6N<$f(Teg9{>OV literal 0 HcmV?d00001 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