Terminal: Added support for Copy/Paste shortcuts

Signed-off-by: Max Weninger <max.weninger@windriver.com>
diff --git a/terminal/plugins/org.eclipse.tm.terminal/plugin.properties b/terminal/plugins/org.eclipse.tm.terminal/plugin.properties
index 2120813..d7efc18 100644
--- a/terminal/plugins/org.eclipse.tm.terminal/plugin.properties
+++ b/terminal/plugins/org.eclipse.tm.terminal/plugin.properties
@@ -27,6 +27,7 @@
 terminal.insertion.description=Terminal view insertion
 terminal.insertion.name=Terminal view insert
 terminal.insertion.category.name=Terminal view commands
+terminal.view.insertion.description = Terminal view commands
 
 terminal.preferences.name = Terminal
 terminal.font.description = The font for the terminal console.
diff --git a/terminal/plugins/org.eclipse.tm.terminal/plugin.xml b/terminal/plugins/org.eclipse.tm.terminal/plugin.xml
index 1115912..6584680 100644
--- a/terminal/plugins/org.eclipse.tm.terminal/plugin.xml
+++ b/terminal/plugins/org.eclipse.tm.terminal/plugin.xml
@@ -21,10 +21,16 @@
             description="%terminal.context.description"
             id="org.eclipse.tm.terminal.TerminalContext"
             />
+    <context
+            name="%terminal.context.name"
+            description="%terminal.context.description"
+            parentId="org.eclipse.ui.contexts.window"
+            id="org.eclipse.tm.terminal.EditContext" />
    </extension>
-	<extension point="org.eclipse.help.contexts">
-  		<contexts file="HelpContexts.xml"/>
-	</extension>
+
+    <extension point="org.eclipse.help.contexts">
+        <contexts file="HelpContexts.xml"/>
+   </extension>
    <extension
          point="org.eclipse.ui.commands">
       <!-- Dummy commands for bindings, see below -->
@@ -32,11 +38,24 @@
             categoryId="org.eclipse.tm.terminal.category1"
             id="org.eclipse.tm.terminal.command1"
             name="%terminal.insertion.name"/>
+      <command
+            categoryId="org.eclipse.tm.terminal.category1"
+            id="org.eclipse.tm.terminal.copy"
+            name="Copy"/>
+      <command
+            categoryId="org.eclipse.tm.terminal.category1"
+            id="org.eclipse.tm.terminal.paste"
+            name="Paste"/>
       <category
             description="%terminal.view.insertion.description"
             id="org.eclipse.tm.terminal.category1"
             name="%terminal.insertion.category.name"/>
    </extension>
+
+    <extension point="org.eclipse.help.contexts">
+        <contexts file="HelpContexts.xml"/>
+    </extension>
+
    <extension
          point="org.eclipse.ui.bindings">
       <!--
@@ -106,6 +125,16 @@
             contextId="org.eclipse.tm.terminal.TerminalContext"
             schemeId="org.eclipse.ui.defaultAcceleratorConfiguration"
             sequence="Alt+W"/> <!-- Window -->
+      <key
+            commandId="org.eclipse.tm.terminal.copy"
+            contextId="org.eclipse.tm.terminal.EditContext"
+            schemeId="org.eclipse.ui.defaultAcceleratorConfiguration"
+            sequence="CTRL+SHIFT+C"/>
+      <key
+            commandId="org.eclipse.tm.terminal.paste"
+            contextId="org.eclipse.tm.terminal.EditContext"
+            schemeId="org.eclipse.ui.defaultAcceleratorConfiguration"
+            sequence="CTRL+SHIFT+V"/>
    </extension>
 
    <extension
diff --git a/terminal/plugins/org.eclipse.tm.terminal/src/org/eclipse/tm/internal/terminal/control/actions/TerminalActionCopy.java b/terminal/plugins/org.eclipse.tm.terminal/src/org/eclipse/tm/internal/terminal/control/actions/TerminalActionCopy.java
index dabf91d..a21f46b 100644
--- a/terminal/plugins/org.eclipse.tm.terminal/src/org/eclipse/tm/internal/terminal/control/actions/TerminalActionCopy.java
+++ b/terminal/plugins/org.eclipse.tm.terminal/src/org/eclipse/tm/internal/terminal/control/actions/TerminalActionCopy.java
@@ -25,6 +25,7 @@
 public class TerminalActionCopy extends AbstractTerminalAction {
 	public TerminalActionCopy() {
 		super(TerminalActionCopy.class.getName());
+		setActionDefinitionId("org.eclipse.tm.terminal.copy"); //$NON-NLS-1$
 		ISharedImages si = PlatformUI.getWorkbench().getSharedImages();
 		setupAction(ActionMessages.COPY, ActionMessages.COPY, si
 				.getImageDescriptor(ISharedImages.IMG_TOOL_COPY), si
@@ -34,6 +35,7 @@
 
 	public TerminalActionCopy(ITerminalViewControl target) {
 		super(target, TerminalActionCopy.class.getName());
+		setActionDefinitionId("org.eclipse.tm.terminal.copy"); //$NON-NLS-1$
 		ISharedImages si = PlatformUI.getWorkbench().getSharedImages();
 		setupAction(ActionMessages.COPY, ActionMessages.COPY, si
 				.getImageDescriptor(ISharedImages.IMG_TOOL_COPY), si
diff --git a/terminal/plugins/org.eclipse.tm.terminal/src/org/eclipse/tm/internal/terminal/control/actions/TerminalActionPaste.java b/terminal/plugins/org.eclipse.tm.terminal/src/org/eclipse/tm/internal/terminal/control/actions/TerminalActionPaste.java
index 3c33be2..441e803 100644
--- a/terminal/plugins/org.eclipse.tm.terminal/src/org/eclipse/tm/internal/terminal/control/actions/TerminalActionPaste.java
+++ b/terminal/plugins/org.eclipse.tm.terminal/src/org/eclipse/tm/internal/terminal/control/actions/TerminalActionPaste.java
@@ -29,6 +29,7 @@
 public class TerminalActionPaste extends AbstractTerminalAction {
 	public TerminalActionPaste() {
 		super(TerminalActionPaste.class.getName());
+		setActionDefinitionId("org.eclipse.tm.terminal.paste"); //$NON-NLS-1$
 		ISharedImages si = PlatformUI.getWorkbench().getSharedImages();
 		setupAction(ActionMessages.PASTE, ActionMessages.PASTE, si
 				.getImageDescriptor(ISharedImages.IMG_TOOL_PASTE), si
@@ -38,6 +39,7 @@
 
 	public TerminalActionPaste(ITerminalViewControl target) {
 		super(target, TerminalActionPaste.class.getName());
+		setActionDefinitionId("org.eclipse.tm.terminal.paste"); //$NON-NLS-1$
 		ISharedImages si = PlatformUI.getWorkbench().getSharedImages();
 		setupAction(ActionMessages.PASTE, ActionMessages.PASTE, si
 				.getImageDescriptor(ISharedImages.IMG_TOOL_PASTE), si
diff --git a/terminal/plugins/org.eclipse.tm.terminal/src/org/eclipse/tm/internal/terminal/emulator/EditActionAccelerators.java b/terminal/plugins/org.eclipse.tm.terminal/src/org/eclipse/tm/internal/terminal/emulator/EditActionAccelerators.java
new file mode 100644
index 0000000..2fd6b68
--- /dev/null
+++ b/terminal/plugins/org.eclipse.tm.terminal/src/org/eclipse/tm/internal/terminal/emulator/EditActionAccelerators.java
@@ -0,0 +1,72 @@
+/*******************************************************************************
+ * Copyright (c) 2013 Wind River Systems, Inc. and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *******************************************************************************/
+
+package org.eclipse.tm.internal.terminal.emulator;
+
+import java.util.HashMap;
+import java.util.Map;
+
+import org.eclipse.jface.bindings.TriggerSequence;
+import org.eclipse.jface.bindings.keys.KeySequence;
+import org.eclipse.jface.bindings.keys.KeyStroke;
+import org.eclipse.jface.bindings.keys.SWTKeySupport;
+import org.eclipse.ui.PlatformUI;
+import org.eclipse.ui.keys.IBindingService;
+
+class EditActionAccelerators {
+	private static final String COPY_COMMAND_ID = "org.eclipse.tm.terminal.copy";
+	private static final String PASTE_COMMAND_ID = "org.eclipse.tm.terminal.paste";
+
+	private final Map commandIdsByAccelerator = new HashMap();
+
+	private void load() {
+		addAccelerator(COPY_COMMAND_ID);
+		addAccelerator(PASTE_COMMAND_ID);
+	}
+
+	private void addAccelerator(String commandId) {
+		KeySequence keySequence = bindingFor(commandId);
+		if (keySequence == null) {
+			return;
+		}
+		KeyStroke[] keyStrokes = keySequence.getKeyStrokes();
+		if (keyStrokes.length != 0) {
+			int accelerator = SWTKeySupport.convertKeyStrokeToAccelerator(keyStrokes[0]);
+			commandIdsByAccelerator.put(new Integer(accelerator), commandId);
+		}
+	}
+
+	private static KeySequence bindingFor(String commandId) {
+		IBindingService bindingService = bindingService();
+		TriggerSequence binding = bindingService.getBestActiveBindingFor(commandId);
+		if (binding instanceof KeySequence) {
+			KeySequence keySequence = (KeySequence) binding;
+			return keySequence;
+		}
+		return null;
+	}
+
+	private static IBindingService bindingService() {
+		return (IBindingService) PlatformUI.getWorkbench().getAdapter(IBindingService.class);
+	}
+
+	boolean isCopyAction(int accelerator) {
+		return isMatchingAction(accelerator, COPY_COMMAND_ID);
+	}
+
+	boolean isPasteAction(int accelerator) {
+		return isMatchingAction(accelerator, PASTE_COMMAND_ID);
+	}
+
+	private boolean isMatchingAction(int accelerator, String commandId) {
+		if (commandIdsByAccelerator.isEmpty()) {
+			load();
+		}
+		return commandId.equals(commandIdsByAccelerator.get(new Integer(accelerator)));
+	}
+}
diff --git a/terminal/plugins/org.eclipse.tm.terminal/src/org/eclipse/tm/internal/terminal/emulator/VT100TerminalControl.java b/terminal/plugins/org.eclipse.tm.terminal/src/org/eclipse/tm/internal/terminal/emulator/VT100TerminalControl.java
index ae4dc69..f521c30 100644
--- a/terminal/plugins/org.eclipse.tm.terminal/src/org/eclipse/tm/internal/terminal/emulator/VT100TerminalControl.java
+++ b/terminal/plugins/org.eclipse.tm.terminal/src/org/eclipse/tm/internal/terminal/emulator/VT100TerminalControl.java
@@ -47,6 +47,7 @@
 import org.eclipse.core.runtime.Platform;
 import org.eclipse.core.runtime.Status;
 import org.eclipse.core.runtime.jobs.Job;
+import org.eclipse.jface.bindings.keys.SWTKeySupport;
 import org.eclipse.jface.resource.JFaceResources;
 import org.eclipse.jface.util.IPropertyChangeListener;
 import org.eclipse.jface.util.PropertyChangeEvent;
@@ -65,7 +66,6 @@
 import org.eclipse.swt.events.MouseEvent;
 import org.eclipse.swt.graphics.Font;
 import org.eclipse.swt.layout.FillLayout;
-import org.eclipse.swt.layout.GridData;
 import org.eclipse.swt.widgets.Composite;
 import org.eclipse.swt.widgets.Control;
 import org.eclipse.swt.widgets.Display;
@@ -127,7 +127,7 @@
     private ITerminalConnector		  fConnector;
     private final ITerminalConnector[]      fConnectors;
 	private final boolean fUseCommonPrefs;
-	
+
     PipedInputStream fInputStream;
 	private static final String defaultEncoding = new java.io.InputStreamReader(new java.io.ByteArrayInputStream(new byte[0])).getEncoding();
 	private String fEncoding = defaultEncoding;
@@ -139,6 +139,8 @@
 
 	private final ITerminalTextData fTerminalModel;
 
+	private final EditActionAccelerators editActionAccelerators = new EditActionAccelerators();
+
 	/**
 	 * Listens to changes in the preferences
 	 */
@@ -157,7 +159,7 @@
 			}
 		}
 	};
-	
+
 	/**
 	 * Is protected by synchronize on this
 	 */
@@ -166,13 +168,13 @@
 	public VT100TerminalControl(ITerminalListener target, Composite wndParent, ITerminalConnector[] connectors) {
 		this(target, wndParent, connectors, false);
 	}
-	
+
 	/**
 	 * Instantiate a Terminal widget.
 	 * @param target Callback for notifying the owner of Terminal state changes.
 	 * @param wndParent The Window parent to embed the Terminal in.
 	 * @param connectors Provided connectors.
-	 * @param useCommonPrefs If <code>true</code>, the Terminal widget will pick up settings 
+	 * @param useCommonPrefs If <code>true</code>, the Terminal widget will pick up settings
 	 *    from the <code>org.eclipse.tm.terminal.TerminalPreferencePage</code> Preference page.
 	 *    Otherwise, clients need to maintain settings themselves.
 	 * @since 3.2
@@ -620,7 +622,7 @@
 	}
 
 	private void onTerminalFontChanged() {
-		// set the font for all 
+		// set the font for all
 		setFont(ITerminalConstants.FONT_DEFINITION);
 	}
 
@@ -790,6 +792,7 @@
 	}
 	protected class TerminalFocusListener implements FocusListener {
 		private IContextActivation contextActivation = null;
+		private IContextActivation contextActivation1 = null;
 
 		protected TerminalFocusListener() {
 			super();
@@ -815,6 +818,9 @@
 					.getWorkbench().getAdapter(IContextService.class);
 			contextActivation = contextService
 					.activateContext("org.eclipse.tm.terminal.TerminalContext"); //$NON-NLS-1$
+			contextActivation1 = contextService
+					.activateContext("org.eclipse.tm.terminal.EditContext"); //$NON-NLS-1$
+
 		}
 
 		public void focusLost(FocusEvent event) {
@@ -829,6 +835,7 @@
 			IContextService contextService = (IContextService) PlatformUI
 					.getWorkbench().getAdapter(IContextService.class);
 			contextService.deactivateContext(contextActivation);
+			contextService.deactivateContext(contextActivation1);
 		}
 	}
 
@@ -837,6 +844,16 @@
 			if (getState()==TerminalState.CONNECTING)
 				return;
 
+			int accelerator = SWTKeySupport.convertEventToUnmodifiedAccelerator(event);
+			if (editActionAccelerators.isCopyAction(accelerator)) {
+				copy();
+				return;
+			}
+			if (editActionAccelerators.isPasteAction(accelerator)) {
+				paste();
+				return;
+			}
+
 			// We set the event.doit to false to prevent any further processing of this
 			// key event.  The only reason this is here is because I was seeing the F10
 			// key both send an escape sequence (due to this method) and switch focus