Bug 520213 - Improve Key Bindings for TreeMaster Detail Actions

Change-Id: I1d01002995753f1d17753b53801b098dab431c2c
Signed-off-by: Jonas Helming <jhelming@eclipsesource.com>
diff --git a/bundles/org.eclipse.emfforms.swt.treemasterdetail/src/org/eclipse/emfforms/spi/swt/treemasterdetail/actions/KeybindedMasterDetailAction.java b/bundles/org.eclipse.emfforms.swt.treemasterdetail/src/org/eclipse/emfforms/spi/swt/treemasterdetail/actions/KeybindedMasterDetailAction.java
index 3ff151f..5073c80 100644
--- a/bundles/org.eclipse.emfforms.swt.treemasterdetail/src/org/eclipse/emfforms/spi/swt/treemasterdetail/actions/KeybindedMasterDetailAction.java
+++ b/bundles/org.eclipse.emfforms.swt.treemasterdetail/src/org/eclipse/emfforms/spi/swt/treemasterdetail/actions/KeybindedMasterDetailAction.java
@@ -30,6 +30,7 @@
 
 	private TreeViewer registeredTreeViewer;
 	private ISelection currentSelection;
+	private boolean executeOnKeyRelease;
 
 	/**
 	 * {@inheritDoc}
@@ -75,6 +76,7 @@
 	 */
 	@Override
 	public void keyPressed(KeyEvent event) {
+		setExecuteOnKeyRelease(isExecuteOnKeyRelease(event));
 		if (isExecuteOnKeyPressed(event)) {
 			executeOnKeyPressed(currentSelection);
 		}
@@ -86,7 +88,7 @@
 	 * @param event
 	 *            The {@link KeyEvent} which triggers this method.
 	 * @return
-	 *         {@code true} if {@link #executeOnKeyPressed(ISelection)} method shall be called, {@code false} otherwise.
+	 * 		{@code true} if {@link #executeOnKeyPressed(ISelection)} method shall be called, {@code false} otherwise.
 	 */
 	protected boolean isExecuteOnKeyPressed(KeyEvent event) {
 		return false;
@@ -110,18 +112,19 @@
 	 */
 	@Override
 	public void keyReleased(KeyEvent event) {
-		if (isExecuteOnKeyRelease(event)) {
+		if (isExecuteOnKeyRelease()) {
 			executeOnKeyRelease(currentSelection);
 		}
+		setExecuteOnKeyRelease(false);
 	}
 
 	/**
 	 * Determines if the {@link #executeOnKeyRelease(ISelection)} method shall be executed.
 	 *
 	 * @param event
-	 *            The {@link KeyEvent} which triggers this method.
+	 *            The {@link KeyEvent} on Keypress. This allows to react on key combinations even on key release
 	 * @return
-	 *         {@code true} if {@link #executeOnKeyRelease(ISelection)} method shall be called, {@code false} otherwise.
+	 * 		{@code true} if {@link #executeOnKeyRelease(ISelection)} method shall be called, {@code false} otherwise.
 	 */
 	protected abstract boolean isExecuteOnKeyRelease(KeyEvent event);
 
@@ -146,9 +149,23 @@
 	 *            The additional pressed char. Use {@link KeyEvent#keyCode} if you only want to check for
 	 *            {@code swtMask}.
 	 * @return
-	 *         {@code true} if the keys indicated by {@code swtMask} and {@code c} are active, {@code false} otherwise.
+	 * 		{@code true} if the keys indicated by {@code swtMask} and {@code c} are active, {@code false} otherwise.
 	 */
 	protected static boolean isActivated(KeyEvent event, int swtMask, char c) {
 		return (event.stateMask & swtMask) == swtMask && event.keyCode == c;
 	}
+
+	/**
+	 * @return the executeOnKeyRelease
+	 */
+	protected boolean isExecuteOnKeyRelease() {
+		return executeOnKeyRelease;
+	}
+
+	/**
+	 * @param executeOnKeyRelease the executeOnKeyRelease to set
+	 */
+	protected void setExecuteOnKeyRelease(boolean executeOnKeyRelease) {
+		this.executeOnKeyRelease = executeOnKeyRelease;
+	}
 }
diff --git a/bundles/org.eclipse.emfforms.swt.treemasterdetail/src/org/eclipse/emfforms/spi/swt/treemasterdetail/actions/delegating/PasteInParentMasterDetailAction.java b/bundles/org.eclipse.emfforms.swt.treemasterdetail/src/org/eclipse/emfforms/spi/swt/treemasterdetail/actions/delegating/PasteInParentMasterDetailAction.java
index 1074904..ec956b9 100644
--- a/bundles/org.eclipse.emfforms.swt.treemasterdetail/src/org/eclipse/emfforms/spi/swt/treemasterdetail/actions/delegating/PasteInParentMasterDetailAction.java
+++ b/bundles/org.eclipse.emfforms.swt.treemasterdetail/src/org/eclipse/emfforms/spi/swt/treemasterdetail/actions/delegating/PasteInParentMasterDetailAction.java
@@ -13,8 +13,6 @@
 
 import org.eclipse.emf.edit.domain.EditingDomain;
 import org.eclipse.emf.edit.ui.action.CommandActionHandler;
-import org.eclipse.swt.SWT;
-import org.eclipse.swt.events.KeyEvent;
 
 /**
  * Delegates to {@link PasteInParentAction}.
@@ -23,9 +21,7 @@
  * @since 1.13
  *
  */
-public class PasteInParentMasterDetailAction extends DelegatingMasterDetailAction {
-
-	private static final String ICON_PATH = "icons/paste.gif"; //$NON-NLS-1$
+public class PasteInParentMasterDetailAction extends PasteMasterDetailAction {
 
 	/**
 	 * Constructor.
@@ -38,17 +34,8 @@
 	}
 
 	@Override
-	protected String getEMFImagePath() {
-		return ICON_PATH;
-	}
-
-	@Override
 	protected CommandActionHandler createDelegatedAction(EditingDomain editingDomain) {
 		return new PasteInParentAction(editingDomain);
 	}
 
-	@Override
-	protected boolean isExecuteOnKeyRelease(KeyEvent event) {
-		return isActivated(event, SWT.CTRL | SWT.SHIFT, 'v');
-	}
 }
diff --git a/bundles/org.eclipse.emfforms.swt.treemasterdetail/src/org/eclipse/emfforms/spi/swt/treemasterdetail/actions/delegating/PasteMasterDetailAction.java b/bundles/org.eclipse.emfforms.swt.treemasterdetail/src/org/eclipse/emfforms/spi/swt/treemasterdetail/actions/delegating/PasteMasterDetailAction.java
index 19efd99..112d4cd 100644
--- a/bundles/org.eclipse.emfforms.swt.treemasterdetail/src/org/eclipse/emfforms/spi/swt/treemasterdetail/actions/delegating/PasteMasterDetailAction.java
+++ b/bundles/org.eclipse.emfforms.swt.treemasterdetail/src/org/eclipse/emfforms/spi/swt/treemasterdetail/actions/delegating/PasteMasterDetailAction.java
@@ -27,6 +27,7 @@
 public class PasteMasterDetailAction extends DelegatingMasterDetailAction {
 
 	private static final String ICON_PATH = "icons/paste.gif"; //$NON-NLS-1$
+	private boolean alreadyPasted;
 
 	/**
 	 * Constructor.
@@ -50,6 +51,34 @@
 
 	@Override
 	protected boolean isExecuteOnKeyRelease(KeyEvent event) {
+		return false;
+	}
+
+	/**
+	 * {@inheritDoc}
+	 *
+	 * @see org.eclipse.emfforms.spi.swt.treemasterdetail.actions.KeybindedMasterDetailAction#keyPressed(org.eclipse.swt.events.KeyEvent)
+	 */
+	@Override
+	public void keyPressed(KeyEvent event) {
+		if (isExecuteOnKeyPressed(event)) {
+			if (!alreadyPasted) {
+				executeOnKeyRelease(getCurrentSelection());
+				alreadyPasted = true;
+			}
+		} else {
+			alreadyPasted = false;
+		}
+
+	}
+
+	/**
+	 * {@inheritDoc}
+	 *
+	 * @see org.eclipse.emfforms.spi.swt.treemasterdetail.actions.KeybindedMasterDetailAction#isExecuteOnKeyPressed(org.eclipse.swt.events.KeyEvent)
+	 */
+	@Override
+	protected boolean isExecuteOnKeyPressed(KeyEvent event) {
 		return isActivated(event, SWT.CTRL, 'v');
 	}
 }