Skip to main content
aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorUwe Stieber2011-10-05 03:38:18 -0400
committerUwe Stieber2011-10-05 03:38:18 -0400
commitffd30a64e731f52e747c759c6617b4ad8d362025 (patch)
tree1f9471bb1c01085ee8f7497d0fa32b8d61c6b736
parentd1b1ad8267e77c46a5f1c17d36b219d35fbc1e00 (diff)
downloadorg.eclipse.tcf-ffd30a64e731f52e747c759c6617b4ad8d362025.tar.gz
org.eclipse.tcf-ffd30a64e731f52e747c759c6617b4ad8d362025.tar.xz
org.eclipse.tcf-ffd30a64e731f52e747c759c6617b4ad8d362025.zip
Target Explorer: Terminals view contribution
-rw-r--r--.gitignore4
-rw-r--r--pom.xml2
-rw-r--r--target_explorer/features/org.eclipse.tm.te.feature/feature.xml2
-rw-r--r--target_explorer/features/org.eclipse.tm.te.sdk.feature/feature.xml2
-rw-r--r--target_explorer/plugins/org.eclipse.tm.te.rcp.application/src/org/eclipse/tm/te/rcp/application/nls/Messages.properties2
-rw-r--r--target_explorer/plugins/org.eclipse.tm.te.runtime/src/org/eclipse/tm/te/runtime/events/DisposedEvent.java67
-rw-r--r--target_explorer/plugins/org.eclipse.tm.te.ui.swt/src/org/eclipse/tm/te/ui/swt/listener/AbstractCheckBoxCellPaintListener.java4
-rw-r--r--target_explorer/plugins/org.eclipse.tm.te.ui.swt/src/org/eclipse/tm/te/ui/swt/listener/AbstractDecorationCellPaintListener.java4
-rw-r--r--target_explorer/plugins/org.eclipse.tm.te.ui.terminal/META-INF/MANIFEST.MF12
-rw-r--r--target_explorer/plugins/org.eclipse.tm.te.ui.terminal/src/org/eclipse/tm/te/ui/terminal/activator/UIPlugin.java64
-rw-r--r--target_explorer/plugins/org.eclipse.tm.te.ui.terminals/.classpath (renamed from target_explorer/plugins/org.eclipse.tm.te.ui.terminal/.classpath)0
-rw-r--r--target_explorer/plugins/org.eclipse.tm.te.ui.terminals/.options1
-rw-r--r--target_explorer/plugins/org.eclipse.tm.te.ui.terminals/.project (renamed from target_explorer/plugins/org.eclipse.tm.te.ui.terminal/.project)2
-rw-r--r--target_explorer/plugins/org.eclipse.tm.te.ui.terminals/.settings/org.eclipse.jdt.core.prefs (renamed from target_explorer/plugins/org.eclipse.tm.te.ui.terminal/.settings/org.eclipse.jdt.core.prefs)0
-rw-r--r--target_explorer/plugins/org.eclipse.tm.te.ui.terminals/META-INF/MANIFEST.MF22
-rw-r--r--target_explorer/plugins/org.eclipse.tm.te.ui.terminals/build.properties (renamed from target_explorer/plugins/org.eclipse.tm.te.ui.terminal/build.properties)3
-rw-r--r--target_explorer/plugins/org.eclipse.tm.te.ui.terminals/plugin.properties (renamed from target_explorer/plugins/org.eclipse.tm.te.ui.terminal/plugin.properties)13
-rw-r--r--target_explorer/plugins/org.eclipse.tm.te.ui.terminals/plugin.xml48
-rw-r--r--target_explorer/plugins/org.eclipse.tm.te.ui.terminals/pom.xml (renamed from target_explorer/plugins/org.eclipse.tm.te.ui.terminal/pom.xml)2
-rw-r--r--target_explorer/plugins/org.eclipse.tm.te.ui.terminals/src/org/eclipse/tm/te/ui/terminals/actions/AbstractAction.java184
-rw-r--r--target_explorer/plugins/org.eclipse.tm.te.ui.terminals/src/org/eclipse/tm/te/ui/terminals/actions/TabScrollLockAction.java58
-rw-r--r--target_explorer/plugins/org.eclipse.tm.te.ui.terminals/src/org/eclipse/tm/te/ui/terminals/activator/UIPlugin.java143
-rw-r--r--target_explorer/plugins/org.eclipse.tm.te.ui.terminals/src/org/eclipse/tm/te/ui/terminals/events/SelectionChangedBroadcastEvent.java77
-rw-r--r--target_explorer/plugins/org.eclipse.tm.te.ui.terminals/src/org/eclipse/tm/te/ui/terminals/interfaces/IPreferenceKeys.java25
-rw-r--r--target_explorer/plugins/org.eclipse.tm.te.ui.terminals/src/org/eclipse/tm/te/ui/terminals/interfaces/ITerminalsView.java36
-rw-r--r--target_explorer/plugins/org.eclipse.tm.te.ui.terminals/src/org/eclipse/tm/te/ui/terminals/interfaces/IUIConstants.java21
-rw-r--r--target_explorer/plugins/org.eclipse.tm.te.ui.terminals/src/org/eclipse/tm/te/ui/terminals/interfaces/ImageConsts.java65
-rw-r--r--target_explorer/plugins/org.eclipse.tm.te.ui.terminals/src/org/eclipse/tm/te/ui/terminals/internal/PreferenceInitializer.java37
-rw-r--r--target_explorer/plugins/org.eclipse.tm.te.ui.terminals/src/org/eclipse/tm/te/ui/terminals/internal/SettingsStore.java52
-rw-r--r--target_explorer/plugins/org.eclipse.tm.te.ui.terminals/src/org/eclipse/tm/te/ui/terminals/manager/ConnectorManager.java198
-rw-r--r--target_explorer/plugins/org.eclipse.tm.te.ui.terminals/src/org/eclipse/tm/te/ui/terminals/manager/ConsoleManager.java300
-rw-r--r--target_explorer/plugins/org.eclipse.tm.te.ui.terminals/src/org/eclipse/tm/te/ui/terminals/nls/Messages.java47
-rw-r--r--target_explorer/plugins/org.eclipse.tm.te.ui.terminals/src/org/eclipse/tm/te/ui/terminals/nls/Messages.properties20
-rw-r--r--target_explorer/plugins/org.eclipse.tm.te.ui.terminals/src/org/eclipse/tm/te/ui/terminals/process/ProcessConnector.java425
-rw-r--r--target_explorer/plugins/org.eclipse.tm.te.ui.terminals/src/org/eclipse/tm/te/ui/terminals/process/ProcessMonitor.java106
-rw-r--r--target_explorer/plugins/org.eclipse.tm.te.ui.terminals/src/org/eclipse/tm/te/ui/terminals/process/ProcessSettings.java162
-rw-r--r--target_explorer/plugins/org.eclipse.tm.te.ui.terminals/src/org/eclipse/tm/te/ui/terminals/process/ProcessSettingsPage.java187
-rw-r--r--target_explorer/plugins/org.eclipse.tm.te.ui.terminals/src/org/eclipse/tm/te/ui/terminals/streams/AbstractStreamsConnector.java128
-rw-r--r--target_explorer/plugins/org.eclipse.tm.te.ui.terminals/src/org/eclipse/tm/te/ui/terminals/streams/InputStreamMonitor.java215
-rw-r--r--target_explorer/plugins/org.eclipse.tm.te.ui.terminals/src/org/eclipse/tm/te/ui/terminals/streams/OutputStreamMonitor.java222
-rw-r--r--target_explorer/plugins/org.eclipse.tm.te.ui.terminals/src/org/eclipse/tm/te/ui/terminals/streams/StreamsConnector.java113
-rw-r--r--target_explorer/plugins/org.eclipse.tm.te.ui.terminals/src/org/eclipse/tm/te/ui/terminals/streams/StreamsSettings.java135
-rw-r--r--target_explorer/plugins/org.eclipse.tm.te.ui.terminals/src/org/eclipse/tm/te/ui/terminals/tabs/TabDisposeListener.java67
-rw-r--r--target_explorer/plugins/org.eclipse.tm.te.ui.terminals/src/org/eclipse/tm/te/ui/terminals/tabs/TabFolderManager.java720
-rw-r--r--target_explorer/plugins/org.eclipse.tm.te.ui.terminals/src/org/eclipse/tm/te/ui/terminals/tabs/TabFolderMenuHandler.java297
-rw-r--r--target_explorer/plugins/org.eclipse.tm.te.ui.terminals/src/org/eclipse/tm/te/ui/terminals/tabs/TabFolderSelectionListener.java55
-rw-r--r--target_explorer/plugins/org.eclipse.tm.te.ui.terminals/src/org/eclipse/tm/te/ui/terminals/tabs/TabFolderToolbarHandler.java304
-rw-r--r--target_explorer/plugins/org.eclipse.tm.te.ui.terminals/src/org/eclipse/tm/te/ui/terminals/tabs/TabPropertyChangeListener.java84
-rw-r--r--target_explorer/plugins/org.eclipse.tm.te.ui.terminals/src/org/eclipse/tm/te/ui/terminals/tabs/TabTerminalListener.java111
-rw-r--r--target_explorer/plugins/org.eclipse.tm.te.ui.terminals/src/org/eclipse/tm/te/ui/terminals/view/TerminalsView.java309
-rw-r--r--target_explorer/plugins/org.eclipse.tm.te.ui/src/org/eclipse/tm/te/ui/interfaces/IUIConstants.java2
51 files changed, 5067 insertions, 92 deletions
diff --git a/.gitignore b/.gitignore
index e7e51c231..1f4f04464 100644
--- a/.gitignore
+++ b/.gitignore
@@ -114,8 +114,8 @@ tests/test-dwarf/*.ncb
/target_explorer/plugins/org.eclipse.tm.te.ui.forms/bin
/target_explorer/plugins/org.eclipse.tm.te.ui.swt/target
/target_explorer/plugins/org.eclipse.tm.te.ui.swt/bin
-/target_explorer/plugins/org.eclipse.tm.te.ui.terminal/target
-/target_explorer/plugins/org.eclipse.tm.te.ui.terminal/bin
+/target_explorer/plugins/org.eclipse.tm.te.ui.terminals/target
+/target_explorer/plugins/org.eclipse.tm.te.ui.terminals/bin
/target_explorer/plugins/org.eclipse.tm.te.ui.views/target
/target_explorer/plugins/org.eclipse.tm.te.ui.views/bin
/target_explorer/features/org.eclipse.tm.te.feature/target
diff --git a/pom.xml b/pom.xml
index 6294b825a..3feb60644 100644
--- a/pom.xml
+++ b/pom.xml
@@ -62,7 +62,7 @@
<module>target_explorer/plugins/org.eclipse.tm.te.ui.controls</module>
<module>target_explorer/plugins/org.eclipse.tm.te.ui.forms</module>
<module>target_explorer/plugins/org.eclipse.tm.te.ui.swt</module>
- <module>target_explorer/plugins/org.eclipse.tm.te.ui.terminal</module>
+ <module>target_explorer/plugins/org.eclipse.tm.te.ui.terminals</module>
<module>target_explorer/plugins/org.eclipse.tm.te.ui.views</module>
<module>target_explorer/plugins/org.eclipse.tm.te.tcf.core</module>
<module>target_explorer/plugins/org.eclipse.tm.te.tcf.filesystem</module>
diff --git a/target_explorer/features/org.eclipse.tm.te.feature/feature.xml b/target_explorer/features/org.eclipse.tm.te.feature/feature.xml
index b6c5dbf8a..4763ec7bf 100644
--- a/target_explorer/features/org.eclipse.tm.te.feature/feature.xml
+++ b/target_explorer/features/org.eclipse.tm.te.feature/feature.xml
@@ -97,7 +97,7 @@
unpack="false"/>
<plugin
- id="org.eclipse.tm.te.ui.terminal"
+ id="org.eclipse.tm.te.ui.terminals"
download-size="0"
install-size="0"
version="0.0.0"
diff --git a/target_explorer/features/org.eclipse.tm.te.sdk.feature/feature.xml b/target_explorer/features/org.eclipse.tm.te.sdk.feature/feature.xml
index 9795d2a94..272c3f5c7 100644
--- a/target_explorer/features/org.eclipse.tm.te.sdk.feature/feature.xml
+++ b/target_explorer/features/org.eclipse.tm.te.sdk.feature/feature.xml
@@ -92,7 +92,7 @@
unpack="false"/>
<plugin
- id="org.eclipse.tm.te.ui.terminal.source"
+ id="org.eclipse.tm.te.ui.terminals.source"
download-size="0"
install-size="0"
version="0.0.0"
diff --git a/target_explorer/plugins/org.eclipse.tm.te.rcp.application/src/org/eclipse/tm/te/rcp/application/nls/Messages.properties b/target_explorer/plugins/org.eclipse.tm.te.rcp.application/src/org/eclipse/tm/te/rcp/application/nls/Messages.properties
index 338e09e2a..fb56c2f1e 100644
--- a/target_explorer/plugins/org.eclipse.tm.te.rcp.application/src/org/eclipse/tm/te/rcp/application/nls/Messages.properties
+++ b/target_explorer/plugins/org.eclipse.tm.te.rcp.application/src/org/eclipse/tm/te/rcp/application/nls/Messages.properties
@@ -1,5 +1,5 @@
#
-# com.windriver.vtl
+# org.eclipse.tm.te.rcp.application
# Externalized Strings.
#
diff --git a/target_explorer/plugins/org.eclipse.tm.te.runtime/src/org/eclipse/tm/te/runtime/events/DisposedEvent.java b/target_explorer/plugins/org.eclipse.tm.te.runtime/src/org/eclipse/tm/te/runtime/events/DisposedEvent.java
new file mode 100644
index 000000000..fc8eee27c
--- /dev/null
+++ b/target_explorer/plugins/org.eclipse.tm.te.runtime/src/org/eclipse/tm/te/runtime/events/DisposedEvent.java
@@ -0,0 +1,67 @@
+/*******************************************************************************
+ * Copyright (c) 2011 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
+ *
+ * Contributors:
+ * Wind River Systems - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.tm.te.runtime.events;
+
+import java.util.EventObject;
+
+import org.eclipse.tm.te.runtime.activator.CoreBundleActivator;
+import org.eclipse.tm.te.runtime.interfaces.tracing.ITraceIds;
+
+/**
+ * Event used to signal the disposal of an element.
+ */
+public class DisposedEvent extends EventObject {
+ private static final long serialVersionUID = -8900361742097122798L;
+
+ private final Object data;
+
+ /**
+ * Constructor.
+ *
+ * @param source The event source. Must not be <code>null</code>.
+ * <p>
+ * The event source is expected to be of type {@link CTabItem}.
+ *
+ * @param data The custom data object or <code>null</code>.
+ */
+ public DisposedEvent(Object source, Object data) {
+ super(source);
+ this.data = data;
+ }
+
+ /**
+ * Returns the custom data object associated with the disposed terminal console.
+ *
+ * @return The custom data object or <code>null</code>.
+ */
+ public final Object getData() {
+ return data;
+ }
+
+ /* (non-Javadoc)
+ * @see java.util.EventObject#toString()
+ */
+ @Override
+ public String toString() {
+ StringBuffer toString = new StringBuffer(getClass().getName());
+
+ String prefix = ""; //$NON-NLS-1$
+ // if debugging the event, formating them a little bit better readable.
+ if (CoreBundleActivator.getTraceHandler().isSlotEnabled(1, ITraceIds.TRACE_EVENTS))
+ prefix = "\n\t\t"; //$NON-NLS-1$
+
+ toString.append(prefix + "{source="); //$NON-NLS-1$
+ toString.append(source);
+ toString.append("}"); //$NON-NLS-1$
+
+ return toString.toString();
+ }
+
+}
diff --git a/target_explorer/plugins/org.eclipse.tm.te.ui.swt/src/org/eclipse/tm/te/ui/swt/listener/AbstractCheckBoxCellPaintListener.java b/target_explorer/plugins/org.eclipse.tm.te.ui.swt/src/org/eclipse/tm/te/ui/swt/listener/AbstractCheckBoxCellPaintListener.java
index e5f5ecb6e..23f6902aa 100644
--- a/target_explorer/plugins/org.eclipse.tm.te.ui.swt/src/org/eclipse/tm/te/ui/swt/listener/AbstractCheckBoxCellPaintListener.java
+++ b/target_explorer/plugins/org.eclipse.tm.te.ui.swt/src/org/eclipse/tm/te/ui/swt/listener/AbstractCheckBoxCellPaintListener.java
@@ -46,7 +46,7 @@ public abstract class AbstractCheckBoxCellPaintListener extends AbstractCellPain
}
/* (non-Javadoc)
- * @see com.windriver.ui.swt.listener.AbstractCellPaintListener#getPaintOrigin(org.eclipse.swt.widgets.Event, org.eclipse.swt.graphics.Image)
+ * @see org.eclipse.tm.te.ui.swt.listener.AbstractCellPaintListener#getPaintOrigin(org.eclipse.swt.widgets.Event, org.eclipse.swt.graphics.Image)
*/
@Override
protected Point getPaintOrigin(Event event, Image image) {
@@ -60,7 +60,7 @@ public abstract class AbstractCheckBoxCellPaintListener extends AbstractCellPain
}
/* (non-Javadoc)
- * @see com.windriver.ui.swt.listener.AbstractCellPaintListener#getImageToDraw(org.eclipse.swt.widgets.Item, int)
+ * @see org.eclipse.tm.te.ui.swt.listener.AbstractCellPaintListener#getImageToDraw(org.eclipse.swt.widgets.Item, int)
*/
@Override
protected Image getImageToDraw(Item item, int columnIndex) {
diff --git a/target_explorer/plugins/org.eclipse.tm.te.ui.swt/src/org/eclipse/tm/te/ui/swt/listener/AbstractDecorationCellPaintListener.java b/target_explorer/plugins/org.eclipse.tm.te.ui.swt/src/org/eclipse/tm/te/ui/swt/listener/AbstractDecorationCellPaintListener.java
index 94f4cd916..84fac2862 100644
--- a/target_explorer/plugins/org.eclipse.tm.te.ui.swt/src/org/eclipse/tm/te/ui/swt/listener/AbstractDecorationCellPaintListener.java
+++ b/target_explorer/plugins/org.eclipse.tm.te.ui.swt/src/org/eclipse/tm/te/ui/swt/listener/AbstractDecorationCellPaintListener.java
@@ -40,7 +40,7 @@ public abstract class AbstractDecorationCellPaintListener extends AbstractCellPa
}
/* (non-Javadoc)
- * @see com.windriver.ui.swt.listener.AbstractCellPaintListener#getPaintOrigin(org.eclipse.swt.widgets.Event, org.eclipse.swt.graphics.Image)
+ * @see org.eclipse.tm.te.ui.swt.listener.AbstractCellPaintListener#getPaintOrigin(org.eclipse.swt.widgets.Event, org.eclipse.swt.graphics.Image)
*/
@Override
protected Point getPaintOrigin(Event event, Image image) {
@@ -48,7 +48,7 @@ public abstract class AbstractDecorationCellPaintListener extends AbstractCellPa
}
/* (non-Javadoc)
- * @see com.windriver.ui.swt.listener.AbstractCellPaintListener#getImageToDraw(org.eclipse.swt.widgets.Item, int)
+ * @see org.eclipse.tm.te.ui.swt.listener.AbstractCellPaintListener#getImageToDraw(org.eclipse.swt.widgets.Item, int)
*/
@Override
protected Image getImageToDraw(Item item, int columnIndex) {
diff --git a/target_explorer/plugins/org.eclipse.tm.te.ui.terminal/META-INF/MANIFEST.MF b/target_explorer/plugins/org.eclipse.tm.te.ui.terminal/META-INF/MANIFEST.MF
deleted file mode 100644
index 2ce09397a..000000000
--- a/target_explorer/plugins/org.eclipse.tm.te.ui.terminal/META-INF/MANIFEST.MF
+++ /dev/null
@@ -1,12 +0,0 @@
-Manifest-Version: 1.0
-Bundle-ManifestVersion: 2
-Bundle-Name: %pluginName
-Bundle-SymbolicName: org.eclipse.tm.te.ui.terminal;singleton:=true
-Bundle-Version: 1.0.0.qualifier
-Bundle-Activator: org.eclipse.tm.te.ui.terminal.activator.UIPlugin
-Bundle-Vendor: %providerName
-Require-Bundle: org.eclipse.core.runtime;bundle-version="3.7.0",
- org.eclipse.ui;bundle-version="3.7.0"
-Bundle-RequiredExecutionEnvironment: JavaSE-1.6
-Bundle-ActivationPolicy: lazy
-Bundle-Localization: plugin
diff --git a/target_explorer/plugins/org.eclipse.tm.te.ui.terminal/src/org/eclipse/tm/te/ui/terminal/activator/UIPlugin.java b/target_explorer/plugins/org.eclipse.tm.te.ui.terminal/src/org/eclipse/tm/te/ui/terminal/activator/UIPlugin.java
deleted file mode 100644
index 9b6449e37..000000000
--- a/target_explorer/plugins/org.eclipse.tm.te.ui.terminal/src/org/eclipse/tm/te/ui/terminal/activator/UIPlugin.java
+++ /dev/null
@@ -1,64 +0,0 @@
-/*******************************************************************************
- * Copyright (c) 2011 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
- *
- * Contributors:
- * Wind River Systems - initial API and implementation
- *******************************************************************************/
-package org.eclipse.tm.te.ui.terminal.activator;
-
-import org.eclipse.ui.plugin.AbstractUIPlugin;
-import org.osgi.framework.BundleContext;
-
-/**
- * The activator class controls the plug-in life cycle
- */
-public class UIPlugin extends AbstractUIPlugin {
- // The shared instance
- private static UIPlugin plugin;
-
- /**
- * The constructor
- */
- public UIPlugin() {
- }
-
- /**
- * Returns the shared instance
- *
- * @return the shared instance
- */
- public static UIPlugin getDefault() {
- return plugin;
- }
-
- /**
- * Convenience method which returns the unique identifier of this plugin.
- */
- public static String getUniqueIdentifier() {
- if (getDefault() != null && getDefault().getBundle() != null) {
- return getDefault().getBundle().getSymbolicName();
- }
- return null;
- }
-
- /* (non-Javadoc)
- * @see org.eclipse.ui.plugin.AbstractUIPlugin#start(org.osgi.framework.BundleContext)
- */
- @Override
- public void start(BundleContext context) throws Exception {
- super.start(context);
- plugin = this;
- }
-
- /* (non-Javadoc)
- * @see org.eclipse.ui.plugin.AbstractUIPlugin#stop(org.osgi.framework.BundleContext)
- */
- @Override
- public void stop(BundleContext context) throws Exception {
- plugin = null;
- super.stop(context);
- }
-}
diff --git a/target_explorer/plugins/org.eclipse.tm.te.ui.terminal/.classpath b/target_explorer/plugins/org.eclipse.tm.te.ui.terminals/.classpath
index 8a8f1668c..8a8f1668c 100644
--- a/target_explorer/plugins/org.eclipse.tm.te.ui.terminal/.classpath
+++ b/target_explorer/plugins/org.eclipse.tm.te.ui.terminals/.classpath
diff --git a/target_explorer/plugins/org.eclipse.tm.te.ui.terminals/.options b/target_explorer/plugins/org.eclipse.tm.te.ui.terminals/.options
new file mode 100644
index 000000000..2ad378b66
--- /dev/null
+++ b/target_explorer/plugins/org.eclipse.tm.te.ui.terminals/.options
@@ -0,0 +1 @@
+org.eclipse.tm.te.ui.terminals/debugmode = 0
diff --git a/target_explorer/plugins/org.eclipse.tm.te.ui.terminal/.project b/target_explorer/plugins/org.eclipse.tm.te.ui.terminals/.project
index d76249909..ad1ea71d6 100644
--- a/target_explorer/plugins/org.eclipse.tm.te.ui.terminal/.project
+++ b/target_explorer/plugins/org.eclipse.tm.te.ui.terminals/.project
@@ -1,6 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?>
<projectDescription>
- <name>org.eclipse.tm.te.ui.terminal</name>
+ <name>org.eclipse.tm.te.ui.terminals</name>
<comment></comment>
<projects>
</projects>
diff --git a/target_explorer/plugins/org.eclipse.tm.te.ui.terminal/.settings/org.eclipse.jdt.core.prefs b/target_explorer/plugins/org.eclipse.tm.te.ui.terminals/.settings/org.eclipse.jdt.core.prefs
index ea56f8105..ea56f8105 100644
--- a/target_explorer/plugins/org.eclipse.tm.te.ui.terminal/.settings/org.eclipse.jdt.core.prefs
+++ b/target_explorer/plugins/org.eclipse.tm.te.ui.terminals/.settings/org.eclipse.jdt.core.prefs
diff --git a/target_explorer/plugins/org.eclipse.tm.te.ui.terminals/META-INF/MANIFEST.MF b/target_explorer/plugins/org.eclipse.tm.te.ui.terminals/META-INF/MANIFEST.MF
new file mode 100644
index 000000000..dd35637dc
--- /dev/null
+++ b/target_explorer/plugins/org.eclipse.tm.te.ui.terminals/META-INF/MANIFEST.MF
@@ -0,0 +1,22 @@
+Manifest-Version: 1.0
+Bundle-ManifestVersion: 2
+Bundle-Name: %pluginName
+Bundle-SymbolicName: org.eclipse.tm.te.ui.terminals;singleton:=true
+Bundle-Version: 1.0.0.qualifier
+Bundle-Activator: org.eclipse.tm.te.ui.terminals.activator.UIPlugin
+Bundle-Vendor: %providerName
+Require-Bundle: org.eclipse.core.runtime;bundle-version="3.7.0",
+ org.eclipse.core.expressions;bundle-version="3.4.300",
+ org.eclipse.core.resources;bundle-version="3.7.100";resolution:=optional,
+ org.eclipse.ui;bundle-version="3.7.0",
+ org.eclipse.ui.ide;bundle-version="3.7.0",
+ org.eclipse.tm.terminal;bundle-version="3.1.1",
+ org.eclipse.tm.terminal.telnet;bundle-version="2.1.0",
+ org.eclipse.tm.terminal.view;bundle-version="2.2.0",
+ org.eclipse.tm.te.runtime;bundle-version="1.0.0",
+ org.eclipse.tm.te.ui;bundle-version="1.0.0",
+ org.eclipse.tm.te.ui.swt;bundle-version="1.0.0",
+ org.eclipse.cdt.core;bundle-version="5.3.0"
+Bundle-RequiredExecutionEnvironment: JavaSE-1.6
+Bundle-ActivationPolicy: lazy
+Bundle-Localization: plugin
diff --git a/target_explorer/plugins/org.eclipse.tm.te.ui.terminal/build.properties b/target_explorer/plugins/org.eclipse.tm.te.ui.terminals/build.properties
index f4ae97015..73a5119ed 100644
--- a/target_explorer/plugins/org.eclipse.tm.te.ui.terminal/build.properties
+++ b/target_explorer/plugins/org.eclipse.tm.te.ui.terminals/build.properties
@@ -2,4 +2,5 @@ source.. = src/
output.. = bin/
bin.includes = META-INF/,\
.,\
- plugin.properties
+ plugin.properties,\
+ plugin.xml
diff --git a/target_explorer/plugins/org.eclipse.tm.te.ui.terminal/plugin.properties b/target_explorer/plugins/org.eclipse.tm.te.ui.terminals/plugin.properties
index c09addda0..faf90fdb0 100644
--- a/target_explorer/plugins/org.eclipse.tm.te.ui.terminal/plugin.properties
+++ b/target_explorer/plugins/org.eclipse.tm.te.ui.terminals/plugin.properties
@@ -8,5 +8,16 @@
# Wind River Systems - initial API and implementation
##################################################################################
-pluginName = Target Explorer, Terminal Consoles
+pluginName = Target Explorer, Terminals
providerName = Eclipse.org
+
+# ----- Terminals View -----
+
+TerminalsView.name=Terminals
+
+# ----- Terminal Connectors -----
+
+TerminalConnector.process=Process
+TerminalConnector.streams=Streams Connector (hidden)
+
+# ----- Commands and Menu contributions -----
diff --git a/target_explorer/plugins/org.eclipse.tm.te.ui.terminals/plugin.xml b/target_explorer/plugins/org.eclipse.tm.te.ui.terminals/plugin.xml
new file mode 100644
index 000000000..31dc3d21b
--- /dev/null
+++ b/target_explorer/plugins/org.eclipse.tm.te.ui.terminals/plugin.xml
@@ -0,0 +1,48 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<?eclipse version="3.4"?>
+<plugin>
+
+<!-- View contributions -->
+ <extension point="org.eclipse.ui.views">
+ <view
+ category="org.eclipse.tm.te.ui.views.category"
+ class="org.eclipse.tm.te.ui.terminals.view.TerminalsView"
+ icon="platform:/plugin/org.eclipse.ui.console/icons/full/eview16/console_view.gif"
+ id="org.eclipse.tm.te.ui.terminals.TerminalsView"
+ name="%TerminalsView.name">
+ </view>
+ </extension>
+
+<!-- Perspective extension contributions -->
+ <extension point="org.eclipse.ui.perspectiveExtensions">
+ <perspectiveExtension targetID="*">
+ <view
+ id="org.eclipse.tm.te.ui.terminals.TerminalsView"
+ minimized="false"
+ relationship="stack"
+ relative="org.eclipse.ui.views.TaskList"
+ visible="false">
+ </view>
+ </perspectiveExtension>
+ </extension>
+
+<!-- Terminal connector contributions -->
+ <extension point="org.eclipse.tm.terminal.terminalConnectors">
+ <connector
+ name="%TerminalConnector.process"
+ id="org.eclipse.tm.te.ui.terminals.ProcessConnector"
+ class="org.eclipse.tm.te.ui.terminals.process.ProcessConnector"/>
+
+ <connector
+ name="%TerminalConnector.streams"
+ id="org.eclipse.tm.te.ui.terminals.StreamsConnector"
+ hidden="true"
+ class="org.eclipse.tm.te.ui.terminals.streams.StreamsConnector"/>
+ </extension>
+
+<!-- Preferences contributions -->
+ <extension point="org.eclipse.core.runtime.preferences">
+ <initializer class="org.eclipse.tm.te.ui.terminals.internal.PreferenceInitializer"/>
+ </extension>
+
+</plugin>
diff --git a/target_explorer/plugins/org.eclipse.tm.te.ui.terminal/pom.xml b/target_explorer/plugins/org.eclipse.tm.te.ui.terminals/pom.xml
index b9a9b00ec..26a4b4bbd 100644
--- a/target_explorer/plugins/org.eclipse.tm.te.ui.terminal/pom.xml
+++ b/target_explorer/plugins/org.eclipse.tm.te.ui.terminals/pom.xml
@@ -12,6 +12,6 @@
</parent>
<version>1.0.0.qualifier</version>
- <artifactId>org.eclipse.tm.te.ui.terminal</artifactId>
+ <artifactId>org.eclipse.tm.te.ui.terminals</artifactId>
<packaging>eclipse-plugin</packaging>
</project>
diff --git a/target_explorer/plugins/org.eclipse.tm.te.ui.terminals/src/org/eclipse/tm/te/ui/terminals/actions/AbstractAction.java b/target_explorer/plugins/org.eclipse.tm.te.ui.terminals/src/org/eclipse/tm/te/ui/terminals/actions/AbstractAction.java
new file mode 100644
index 000000000..54d2ecee4
--- /dev/null
+++ b/target_explorer/plugins/org.eclipse.tm.te.ui.terminals/src/org/eclipse/tm/te/ui/terminals/actions/AbstractAction.java
@@ -0,0 +1,184 @@
+/*******************************************************************************
+ * Copyright (c) 2011 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
+ *
+ * Contributors:
+ * Wind River Systems - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.tm.te.ui.terminals.actions;
+
+import java.util.Collections;
+
+import org.eclipse.core.commands.Command;
+import org.eclipse.core.commands.ExecutionEvent;
+import org.eclipse.core.expressions.EvaluationContext;
+import org.eclipse.core.runtime.Assert;
+import org.eclipse.core.runtime.IStatus;
+import org.eclipse.core.runtime.Status;
+import org.eclipse.jface.viewers.IStructuredSelection;
+import org.eclipse.jface.viewers.StructuredSelection;
+import org.eclipse.osgi.util.NLS;
+import org.eclipse.swt.custom.CTabItem;
+import org.eclipse.tm.internal.terminal.control.ITerminalViewControl;
+import org.eclipse.tm.internal.terminal.control.actions.AbstractTerminalAction;
+import org.eclipse.tm.te.ui.terminals.activator.UIPlugin;
+import org.eclipse.tm.te.ui.terminals.nls.Messages;
+import org.eclipse.tm.te.ui.terminals.tabs.TabFolderManager;
+import org.eclipse.tm.te.ui.terminals.tabs.TabFolderToolbarHandler;
+import org.eclipse.ui.ISources;
+import org.eclipse.ui.PlatformUI;
+import org.eclipse.ui.commands.ICommandService;
+
+/**
+ * Abstract terminal action wrapper implementation.
+ */
+@SuppressWarnings("restriction")
+public abstract class AbstractAction extends AbstractTerminalAction {
+ // Reference to the parent toolbar handler
+ private final TabFolderToolbarHandler parent;
+
+ /**
+ * Constructor.
+ *
+ * @param parent
+ * The parent toolbar handler instance. Must not be
+ * <code>null</code>.
+ * @param id
+ * The terminal action id. Must not be <code>null</code>.
+ */
+ public AbstractAction(TabFolderToolbarHandler parent, String id) {
+ super(id);
+
+ Assert.isNotNull(parent);
+ this.parent = parent;
+ }
+
+ /**
+ * Returns the parent toolbar handler.
+ *
+ * @return The parent toolbar handler.
+ */
+ protected final TabFolderToolbarHandler getParent() {
+ return parent;
+ }
+
+ /* (non-Javadoc)
+ * @see org.eclipse.tm.internal.terminal.control.actions.AbstractTerminalAction#getTarget()
+ */
+ @Override
+ protected ITerminalViewControl getTarget() {
+ return getParent().getActiveTerminalViewControl();
+ }
+
+ /* (non-Javadoc)
+ * @see org.eclipse.tm.internal.terminal.control.actions.AbstractTerminalAction#run()
+ */
+ @Override
+ public void run() {
+ // Get the active tab item from the tab folder manager
+ TabFolderManager manager = (TabFolderManager)getParent().getAdapter(TabFolderManager.class);
+ if (manager != null) {
+ // If we have the active tab item, we can get the active terminal control
+ CTabItem activeTabItem = manager.getActiveTabItem();
+ if (activeTabItem != null) {
+ // And execute the command
+ executeCommand(activeTabItem.getData("customData")); //$NON-NLS-1$
+ }
+ }
+ }
+
+ /**
+ * Executes the command for the given data node as current and active menu selection.
+ * <p>
+ * <b>Node:</b> If the provided data node is <code>null</code>, the method will trigger
+ * the command with an empty selection.
+ *
+ * @param data The terminal custom data node or <code>null</code>.
+ */
+ protected void executeCommand(Object data) {
+ // Get the command service from the workbench
+ ICommandService service = (ICommandService)PlatformUI.getWorkbench().getAdapter(ICommandService.class);
+ if (service != null && getCommandId() != null) {
+ // Get the command
+ final Command command = service.getCommand(getCommandId());
+ if (command != null && command.isDefined()) {
+ // Construct a selection element
+ IStructuredSelection selection = data != null ? new StructuredSelection(data) : new StructuredSelection();
+ // Construct the application context
+ EvaluationContext context = new EvaluationContext(null, selection);
+ // Apply the selection to the "activeMenuSelection" and "selection" variable too
+ context.addVariable(ISources.ACTIVE_CURRENT_SELECTION_NAME, selection);
+ context.addVariable(ISources.ACTIVE_MENU_SELECTION_NAME, selection);
+ // Construct the execution event
+ ExecutionEvent execEvent = new ExecutionEvent(command, Collections.EMPTY_MAP, this, context);
+ // And execute the event
+ try {
+ command.executeWithChecks(execEvent);
+ } catch (Exception e) {
+ IStatus status = new Status(IStatus.ERROR, UIPlugin.getUniqueIdentifier(),
+ NLS.bind(Messages.AbstractAction_error_commandExecutionFailed, getCommandId(), e.getLocalizedMessage()),
+ e);
+ UIPlugin.getDefault().getLog().log(status);
+ }
+ }
+ }
+ }
+
+ /**
+ * Returns the command id of the command to execute.
+ *
+ * @return The command id. Must be never <code>null</code>.
+ */
+ protected abstract String getCommandId();
+
+ /* (non-Javadoc)
+ * @see org.eclipse.tm.internal.terminal.control.actions.AbstractTerminalAction#updateAction(boolean)
+ */
+ @Override
+ public void updateAction(boolean aboutToShow) {
+ // Ignore the flag given from outside. We have to decide ourself
+ // what the enabled state of the action is
+ boolean enabled = getTarget() != null;
+
+ // If a target terminal control is available, we need to find the corresponding
+ // VLM target object which we need to trigger the handler
+ if (enabled) {
+ // The action will be enabled if we can determine the VLM target object
+ enabled = false;
+ // Get the active tab item from the tab folder manager
+ TabFolderManager manager = (TabFolderManager)getParent().getAdapter(TabFolderManager.class);
+ if (manager != null) {
+ // If we have the active tab item, we can get the active terminal control
+ CTabItem activeTabItem = manager.getActiveTabItem();
+ if (activeTabItem != null) {
+ enabled = checkEnableAction(activeTabItem.getData("customData")); //$NON-NLS-1$
+ }
+ }
+ }
+
+ setEnabled(enabled);
+ }
+
+ /**
+ * Checks if the action should be enabled based on the given terminal data object.
+ *
+ * @param data The terminal data node or <code>null</code>.
+ * @return <code>True</code> to enable the action, <code>false</code> otherwise.
+ */
+ protected boolean checkEnableAction(Object data) {
+ return data != null;
+ }
+
+ /**
+ * Returns if the action is a separator. Returning <code>true</code> here
+ * means that an additional separator toolbar element is added right or
+ * above of the action.
+ *
+ * @return <code>True</code> if the action is separating the parent contribution manager, <code>false</code> otherwise.
+ */
+ public boolean isSeparator() {
+ return false;
+ }
+}
diff --git a/target_explorer/plugins/org.eclipse.tm.te.ui.terminals/src/org/eclipse/tm/te/ui/terminals/actions/TabScrollLockAction.java b/target_explorer/plugins/org.eclipse.tm.te.ui.terminals/src/org/eclipse/tm/te/ui/terminals/actions/TabScrollLockAction.java
new file mode 100644
index 000000000..73d9fd237
--- /dev/null
+++ b/target_explorer/plugins/org.eclipse.tm.te.ui.terminals/src/org/eclipse/tm/te/ui/terminals/actions/TabScrollLockAction.java
@@ -0,0 +1,58 @@
+/*******************************************************************************
+ * Copyright (c) 2011 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
+ *
+ * Contributors:
+ * Wind River Systems - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.tm.te.ui.terminals.actions;
+
+import org.eclipse.jface.action.IAction;
+import org.eclipse.tm.internal.terminal.actions.ActionMessages;
+import org.eclipse.tm.internal.terminal.control.ITerminalViewControl;
+import org.eclipse.tm.internal.terminal.control.actions.AbstractTerminalAction;
+import org.eclipse.tm.te.ui.terminals.activator.UIPlugin;
+import org.eclipse.tm.te.ui.terminals.interfaces.ImageConsts;
+
+/**
+ * Terminal console tab scroll lock action.
+ */
+@SuppressWarnings("restriction")
+public class TabScrollLockAction extends AbstractTerminalAction {
+
+ /**
+ * Constructor.
+ */
+ public TabScrollLockAction() {
+ super(null, TabScrollLockAction.class.getName(), IAction.AS_RADIO_BUTTON);
+
+ setupAction(ActionMessages.SCROLL_LOCK_0,
+ ActionMessages.SCROLL_LOCK_1,
+ UIPlugin.getImageDescriptor(ImageConsts.ACTION_ScrollLock_Hover),
+ UIPlugin.getImageDescriptor(ImageConsts.ACTION_ScrollLock_Enabled),
+ UIPlugin.getImageDescriptor(ImageConsts.ACTION_ScrollLock_Disabled),
+ true);
+ }
+
+ /* (non-Javadoc)
+ * @see org.eclipse.tm.internal.terminal.control.actions.AbstractTerminalAction#run()
+ */
+ @Override
+ public void run() {
+ ITerminalViewControl target = getTarget();
+ if (target != null) {
+ target.setScrollLock(!target.isScrollLock());
+ setChecked(target.isScrollLock());
+ }
+ }
+
+ /* (non-Javadoc)
+ * @see org.eclipse.tm.internal.terminal.control.actions.AbstractTerminalAction#updateAction(boolean)
+ */
+ @Override
+ public void updateAction(boolean aboutToShow) {
+ setEnabled(getTarget() != null && aboutToShow);
+ }
+}
diff --git a/target_explorer/plugins/org.eclipse.tm.te.ui.terminals/src/org/eclipse/tm/te/ui/terminals/activator/UIPlugin.java b/target_explorer/plugins/org.eclipse.tm.te.ui.terminals/src/org/eclipse/tm/te/ui/terminals/activator/UIPlugin.java
new file mode 100644
index 000000000..a919f570e
--- /dev/null
+++ b/target_explorer/plugins/org.eclipse.tm.te.ui.terminals/src/org/eclipse/tm/te/ui/terminals/activator/UIPlugin.java
@@ -0,0 +1,143 @@
+/*******************************************************************************
+ * Copyright (c) 2011 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
+ *
+ * Contributors:
+ * Wind River Systems - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.tm.te.ui.terminals.activator;
+
+import java.net.URL;
+
+import org.eclipse.core.runtime.Platform;
+import org.eclipse.jface.resource.ImageDescriptor;
+import org.eclipse.jface.resource.ImageRegistry;
+import org.eclipse.swt.graphics.Image;
+import org.eclipse.tm.te.runtime.preferences.ScopedEclipsePreferences;
+import org.eclipse.tm.te.runtime.tracing.TraceHandler;
+import org.eclipse.tm.te.ui.terminals.interfaces.ImageConsts;
+import org.eclipse.ui.plugin.AbstractUIPlugin;
+import org.osgi.framework.Bundle;
+import org.osgi.framework.BundleContext;
+
+/**
+ * The activator class controls the plug-in life cycle
+ */
+public class UIPlugin extends AbstractUIPlugin {
+ // The shared instance
+ private static UIPlugin plugin;
+
+ private static ScopedEclipsePreferences scopedPreferences = null;
+ // The trace handler instance
+ private static TraceHandler traceHandler;
+
+ /**
+ * The constructor
+ */
+ public UIPlugin() {
+ }
+
+ /**
+ * Returns the shared instance
+ *
+ * @return the shared instance
+ */
+ public static UIPlugin getDefault() {
+ return plugin;
+ }
+
+ /**
+ * Convenience method which returns the unique identifier of this plugin.
+ */
+ public static String getUniqueIdentifier() {
+ if (getDefault() != null && getDefault().getBundle() != null) {
+ return getDefault().getBundle().getSymbolicName();
+ }
+ return null;
+ }
+
+ /**
+ * Return the scoped preferences for this plugin.
+ */
+ public static ScopedEclipsePreferences getScopedPreferences() {
+ if (scopedPreferences == null) {
+ scopedPreferences = new ScopedEclipsePreferences(getUniqueIdentifier());
+ }
+ return scopedPreferences;
+ }
+
+ /**
+ * Returns the bundles trace handler.
+ *
+ * @return The bundles trace handler.
+ */
+ public static TraceHandler getTraceHandler() {
+ if (traceHandler == null) {
+ traceHandler = new TraceHandler(getUniqueIdentifier());
+ }
+ return traceHandler;
+ }
+
+ /* (non-Javadoc)
+ * @see org.eclipse.ui.plugin.AbstractUIPlugin#start(org.osgi.framework.BundleContext)
+ */
+ @Override
+ public void start(BundleContext context) throws Exception {
+ super.start(context);
+ plugin = this;
+ }
+
+ /* (non-Javadoc)
+ * @see org.eclipse.ui.plugin.AbstractUIPlugin#stop(org.osgi.framework.BundleContext)
+ */
+ @Override
+ public void stop(BundleContext context) throws Exception {
+ plugin = null;
+ scopedPreferences = null;
+ traceHandler = null;
+ super.stop(context);
+ }
+
+ /* (non-Javadoc)
+ * @see org.eclipse.ui.plugin.AbstractUIPlugin#initializeImageRegistry(org.eclipse.jface.resource.ImageRegistry)
+ */
+ @Override
+ protected void initializeImageRegistry(ImageRegistry registry) {
+ Bundle bundle = Platform.getBundle("org.eclipse.ui.console"); //$NON-NLS-1$
+ if (bundle != null && (bundle.getState() == Bundle.RESOLVED || bundle.getState() == Bundle.ACTIVE)) {
+ URL url = bundle.getEntry(ImageConsts.IMAGE_DIR_ROOT + "full/" + ImageConsts.IMAGE_DIR_EVIEW + "console_view.gif"); //$NON-NLS-1$ //$NON-NLS-2$
+ registry.put(ImageConsts.VIEW_Terminals, ImageDescriptor.createFromURL(url));
+
+ url = bundle.getEntry(ImageConsts.IMAGE_DIR_ROOT + "full/" + ImageConsts.IMAGE_DIR_CLCL + "lock_co.gif"); //$NON-NLS-1$ //$NON-NLS-2$
+ registry.put(ImageConsts.ACTION_ScrollLock_Hover, ImageDescriptor.createFromURL(url));
+ url = bundle.getEntry(ImageConsts.IMAGE_DIR_ROOT + "full/" + ImageConsts.IMAGE_DIR_ELCL + "lock_co.gif"); //$NON-NLS-1$ //$NON-NLS-2$
+ registry.put(ImageConsts.ACTION_ScrollLock_Enabled, ImageDescriptor.createFromURL(url));
+ url = bundle.getEntry(ImageConsts.IMAGE_DIR_ROOT + "full/" + ImageConsts.IMAGE_DIR_DLCL + "lock_co.gif"); //$NON-NLS-1$ //$NON-NLS-2$
+ registry.put(ImageConsts.ACTION_ScrollLock_Disabled, ImageDescriptor.createFromURL(url));
+ }
+ }
+
+ /**
+ * Loads the image registered under the specified key from the image
+ * registry and returns the <code>Image</code> object instance.
+ *
+ * @param key The key the image is registered with.
+ * @return The <code>Image</code> object instance or <code>null</code>.
+ */
+ public static Image getImage(String key) {
+ return getDefault().getImageRegistry().get(key);
+ }
+
+ /**
+ * Loads the image registered under the specified key from the image
+ * registry and returns the <code>ImageDescriptor</code> object instance.
+ *
+ * @param key The key the image is registered with.
+ * @return The <code>ImageDescriptor</code> object instance or <code>null</code>.
+ */
+ public static ImageDescriptor getImageDescriptor(String key) {
+ return getDefault().getImageRegistry().getDescriptor(key);
+ }
+}
diff --git a/target_explorer/plugins/org.eclipse.tm.te.ui.terminals/src/org/eclipse/tm/te/ui/terminals/events/SelectionChangedBroadcastEvent.java b/target_explorer/plugins/org.eclipse.tm.te.ui.terminals/src/org/eclipse/tm/te/ui/terminals/events/SelectionChangedBroadcastEvent.java
new file mode 100644
index 000000000..1eb267f5d
--- /dev/null
+++ b/target_explorer/plugins/org.eclipse.tm.te.ui.terminals/src/org/eclipse/tm/te/ui/terminals/events/SelectionChangedBroadcastEvent.java
@@ -0,0 +1,77 @@
+/*******************************************************************************
+ * Copyright (c) 2011 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
+ *
+ * Contributors:
+ * Wind River Systems - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.tm.te.ui.terminals.events;
+
+import java.util.EventObject;
+
+import org.eclipse.jface.viewers.SelectionChangedEvent;
+import org.eclipse.tm.te.runtime.events.EventManager;
+import org.eclipse.tm.te.ui.terminals.tabs.TabFolderManager;
+
+/**
+ * Terminal console selection changed broadcast event. The event is typically fired
+ * by a terminal console tab folder manager to signal a tab switch to all listeners.
+ */
+public class SelectionChangedBroadcastEvent extends EventObject {
+ private static final long serialVersionUID = -4970244776543572896L;
+
+ // The selection changed event to broadcast
+ private final SelectionChangedEvent selectionChangedEvent;
+
+ /**
+ * Constructor.
+ *
+ * @param source The event source. Must not be <code>null</code>.
+ * @param selectionChangedEvent The selection changed event or <code>null</code>.
+ */
+ public SelectionChangedBroadcastEvent(TabFolderManager source, SelectionChangedEvent selectionChangedEvent) {
+ super(source);
+ this.selectionChangedEvent = selectionChangedEvent;
+ }
+
+ /**
+ * Convenience method to return the source tab folder manager.
+ *
+ * @return The source tab folder manager.
+ */
+ public TabFolderManager getSourceTabFolderManager() {
+ return (TabFolderManager)getSource();
+ }
+
+ /**
+ * Returns the broadcasted selection changed event.
+ *
+ * @return The broadcasted selection changed event or <code>null</code>.
+ */
+ public SelectionChangedEvent getSelectionChangedEvent() {
+ return selectionChangedEvent;
+ }
+
+ /* (non-Javadoc)
+ * @see java.util.EventObject#toString()
+ */
+ @Override
+ public String toString() {
+ StringBuilder toString = new StringBuilder(getClass().getName());
+
+ String prefix = ""; //$NON-NLS-1$
+ // if debugging the event, formating them a little bit better readable.
+ if (EventManager.isTracingEnabled())
+ prefix = "\n\t\t"; //$NON-NLS-1$
+
+ toString.append(prefix + "source="); //$NON-NLS-1$
+ toString.append(source);
+ toString.append("," + prefix + "selectionChangedEvent="); //$NON-NLS-1$ //$NON-NLS-2$
+ toString.append(selectionChangedEvent);
+ toString.append("}"); //$NON-NLS-1$
+
+ return toString.toString();
+ }
+}
diff --git a/target_explorer/plugins/org.eclipse.tm.te.ui.terminals/src/org/eclipse/tm/te/ui/terminals/interfaces/IPreferenceKeys.java b/target_explorer/plugins/org.eclipse.tm.te.ui.terminals/src/org/eclipse/tm/te/ui/terminals/interfaces/IPreferenceKeys.java
new file mode 100644
index 000000000..b07359704
--- /dev/null
+++ b/target_explorer/plugins/org.eclipse.tm.te.ui.terminals/src/org/eclipse/tm/te/ui/terminals/interfaces/IPreferenceKeys.java
@@ -0,0 +1,25 @@
+/*******************************************************************************
+ * Copyright (c) 2011 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
+ *
+ * Contributors:
+ * Wind River Systems - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.tm.te.ui.terminals.interfaces;
+
+/**
+ * Terminals plug-in preference key definitions.
+ */
+public interface IPreferenceKeys {
+ /**
+ * Preference keys family prefix.
+ */
+ public final String PREF_TERMINAL = "terminals"; //$NON-NLS-1$
+
+ /**
+ * Preference key: Remove terminated terminals when a new terminal is created.
+ */
+ public final String PREF_REMOVE_TERMINATED_TERMINALS = PREF_TERMINAL + ".removeTerminatedTerminals"; //$NON-NLS-1$
+}
diff --git a/target_explorer/plugins/org.eclipse.tm.te.ui.terminals/src/org/eclipse/tm/te/ui/terminals/interfaces/ITerminalsView.java b/target_explorer/plugins/org.eclipse.tm.te.ui.terminals/src/org/eclipse/tm/te/ui/terminals/interfaces/ITerminalsView.java
new file mode 100644
index 000000000..3c856f0c1
--- /dev/null
+++ b/target_explorer/plugins/org.eclipse.tm.te.ui.terminals/src/org/eclipse/tm/te/ui/terminals/interfaces/ITerminalsView.java
@@ -0,0 +1,36 @@
+/*******************************************************************************
+ * Copyright (c) 2011 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
+ *
+ * Contributors:
+ * Wind River Systems - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.tm.te.ui.terminals.interfaces;
+
+import org.eclipse.ui.IViewPart;
+
+/**
+ * Terminals view public interface.
+ */
+public interface ITerminalsView extends IViewPart {
+
+ /**
+ * Switch to the empty page control.
+ */
+ public void switchToEmptyPageControl();
+
+ /**
+ * Switch to the tab folder control.
+ */
+ public void switchToTabFolderControl();
+
+ /**
+ * Returns the context help id associated with the terminal
+ * console view instance.
+ *
+ * @return The context help id or <code>null</code> if none is associated.
+ */
+ public String getContextHelpId();
+}
diff --git a/target_explorer/plugins/org.eclipse.tm.te.ui.terminals/src/org/eclipse/tm/te/ui/terminals/interfaces/IUIConstants.java b/target_explorer/plugins/org.eclipse.tm.te.ui.terminals/src/org/eclipse/tm/te/ui/terminals/interfaces/IUIConstants.java
new file mode 100644
index 000000000..87fc1307c
--- /dev/null
+++ b/target_explorer/plugins/org.eclipse.tm.te.ui.terminals/src/org/eclipse/tm/te/ui/terminals/interfaces/IUIConstants.java
@@ -0,0 +1,21 @@
+/*******************************************************************************
+ * Copyright (c) 2011 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
+ *
+ * Contributors:
+ * Wind River Systems - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.tm.te.ui.terminals.interfaces;
+
+/**
+ * Terminals common UI constants.
+ */
+public interface IUIConstants {
+ /**
+ * The view id of the terminals view.
+ */
+ public static final String ID = "org.eclipse.tm.te.ui.terminals.TerminalsView"; //$NON-NLS-1$
+
+}
diff --git a/target_explorer/plugins/org.eclipse.tm.te.ui.terminals/src/org/eclipse/tm/te/ui/terminals/interfaces/ImageConsts.java b/target_explorer/plugins/org.eclipse.tm.te.ui.terminals/src/org/eclipse/tm/te/ui/terminals/interfaces/ImageConsts.java
new file mode 100644
index 000000000..0934c14c8
--- /dev/null
+++ b/target_explorer/plugins/org.eclipse.tm.te.ui.terminals/src/org/eclipse/tm/te/ui/terminals/interfaces/ImageConsts.java
@@ -0,0 +1,65 @@
+/*******************************************************************************
+ * Copyright (c) 2011 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
+ *
+ * Contributors:
+ * Wind River Systems - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.tm.te.ui.terminals.interfaces;
+
+/**
+ * Target Explorer: Image registry constants.
+ */
+public interface ImageConsts {
+ /**
+ * The root directory where to load the images from, relative to
+ * the bundle directory.
+ */
+ public final static String IMAGE_DIR_ROOT = "icons/"; //$NON-NLS-1$
+
+ /**
+ * The directory where to load colored local toolbar images from,
+ * relative to the image root directory.
+ */
+ public final static String IMAGE_DIR_CLCL = "clcl16/"; //$NON-NLS-1$
+
+ /**
+ * The directory where to load disabled local toolbar images from,
+ * relative to the image root directory.
+ */
+ public final static String IMAGE_DIR_DLCL = "dlcl16/"; //$NON-NLS-1$
+
+ /**
+ * The directory where to load enabled local toolbar images from,
+ * relative to the image root directory.
+ */
+ public final static String IMAGE_DIR_ELCL = "elcl16/"; //$NON-NLS-1$
+
+ /**
+ * The directory where to load view related images from, relative to
+ * the image root directory.
+ */
+ public final static String IMAGE_DIR_EVIEW = "eview16/"; //$NON-NLS-1$
+
+ /**
+ * The key to access the terminal consoles view image.
+ */
+ public static final String VIEW_Terminals = "TerminalsView"; //$NON-NLS-1$
+
+ /**
+ * The key to access the scroll lock action image (enabled).
+ */
+ public static final String ACTION_ScrollLock_Enabled = "ScrollLockAction_enabled"; //$NON-NLS-1$
+
+ /**
+ * The key to access the scroll lock action image (disabled).
+ */
+ public static final String ACTION_ScrollLock_Disabled = "ScrollLockAction_disabled"; //$NON-NLS-1$
+
+ /**
+ * The key to access the scroll lock action image (hover).
+ */
+ public static final String ACTION_ScrollLock_Hover = "ScrollLockAction_hover"; //$NON-NLS-1$
+}
diff --git a/target_explorer/plugins/org.eclipse.tm.te.ui.terminals/src/org/eclipse/tm/te/ui/terminals/internal/PreferenceInitializer.java b/target_explorer/plugins/org.eclipse.tm.te.ui.terminals/src/org/eclipse/tm/te/ui/terminals/internal/PreferenceInitializer.java
new file mode 100644
index 000000000..8cb06cc34
--- /dev/null
+++ b/target_explorer/plugins/org.eclipse.tm.te.ui.terminals/src/org/eclipse/tm/te/ui/terminals/internal/PreferenceInitializer.java
@@ -0,0 +1,37 @@
+/*******************************************************************************
+ * Copyright (c) 2011 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
+ *
+ * Contributors:
+ * Wind River Systems - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.tm.te.ui.terminals.internal;
+
+import org.eclipse.core.runtime.preferences.AbstractPreferenceInitializer;
+import org.eclipse.tm.te.runtime.preferences.ScopedEclipsePreferences;
+import org.eclipse.tm.te.ui.terminals.activator.UIPlugin;
+import org.eclipse.tm.te.ui.terminals.interfaces.IPreferenceKeys;
+
+/**
+ * Terminals default preferences initializer.
+ */
+public class PreferenceInitializer extends AbstractPreferenceInitializer {
+
+ /**
+ * Constructor.
+ */
+ public PreferenceInitializer() {
+ }
+
+ /* (non-Javadoc)
+ * @see org.eclipse.core.runtime.preferences.AbstractPreferenceInitializer#initializeDefaultPreferences()
+ */
+ @Override
+ public void initializeDefaultPreferences() {
+ ScopedEclipsePreferences prefs = UIPlugin.getScopedPreferences();
+
+ prefs.putDefaultBoolean(IPreferenceKeys.PREF_REMOVE_TERMINATED_TERMINALS, true);
+ }
+}
diff --git a/target_explorer/plugins/org.eclipse.tm.te.ui.terminals/src/org/eclipse/tm/te/ui/terminals/internal/SettingsStore.java b/target_explorer/plugins/org.eclipse.tm.te.ui.terminals/src/org/eclipse/tm/te/ui/terminals/internal/SettingsStore.java
new file mode 100644
index 000000000..250776a6d
--- /dev/null
+++ b/target_explorer/plugins/org.eclipse.tm.te.ui.terminals/src/org/eclipse/tm/te/ui/terminals/internal/SettingsStore.java
@@ -0,0 +1,52 @@
+/*******************************************************************************
+ * Copyright (c) 2011 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
+ *
+ * Contributors:
+ * Wind River Systems - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.tm.te.ui.terminals.internal;
+
+import org.eclipse.tm.internal.terminal.provisional.api.ISettingsStore;
+import org.eclipse.tm.te.runtime.properties.PropertiesContainer;
+
+/**
+ * Simple default Terminal settings store implementation keeping the settings
+ * within memory.
+ */
+@SuppressWarnings("restriction")
+public class SettingsStore extends PropertiesContainer implements ISettingsStore {
+
+ /**
+ * Constructor.
+ */
+ public SettingsStore() {
+ }
+
+ /* (non-Javadoc)
+ * @see org.eclipse.tm.internal.terminal.provisional.api.ISettingsStore#get(java.lang.String, java.lang.String)
+ */
+ @Override
+ public String get(String key, String defaultValue) {
+ String value = getStringProperty(key);
+ return value != null ? value : defaultValue;
+ }
+
+ /* (non-Javadoc)
+ * @see org.eclipse.tm.internal.terminal.provisional.api.ISettingsStore#get(java.lang.String)
+ */
+ @Override
+ public String get(String key) {
+ return getStringProperty(key);
+ }
+
+ /* (non-Javadoc)
+ * @see org.eclipse.tm.internal.terminal.provisional.api.ISettingsStore#put(java.lang.String, java.lang.String)
+ */
+ @Override
+ public void put(String key, String value) {
+ setProperty(key, value);
+ }
+}
diff --git a/target_explorer/plugins/org.eclipse.tm.te.ui.terminals/src/org/eclipse/tm/te/ui/terminals/manager/ConnectorManager.java b/target_explorer/plugins/org.eclipse.tm.te.ui.terminals/src/org/eclipse/tm/te/ui/terminals/manager/ConnectorManager.java
new file mode 100644
index 000000000..3fd6ffc32
--- /dev/null
+++ b/target_explorer/plugins/org.eclipse.tm.te.ui.terminals/src/org/eclipse/tm/te/ui/terminals/manager/ConnectorManager.java
@@ -0,0 +1,198 @@
+/*******************************************************************************
+ * Copyright (c) 2011 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
+ *
+ * Contributors:
+ * Wind River Systems - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.tm.te.ui.terminals.manager;
+
+import java.io.InputStream;
+import java.io.OutputStream;
+
+import org.eclipse.cdt.utils.pty.PTY;
+import org.eclipse.tm.internal.terminal.provisional.api.ISettingsStore;
+import org.eclipse.tm.internal.terminal.provisional.api.ITerminalConnector;
+import org.eclipse.tm.internal.terminal.provisional.api.TerminalConnectorExtension;
+import org.eclipse.tm.internal.terminal.telnet.TelnetSettings;
+import org.eclipse.tm.te.ui.terminals.internal.SettingsStore;
+import org.eclipse.tm.te.ui.terminals.process.ProcessSettings;
+import org.eclipse.tm.te.ui.terminals.streams.StreamsSettings;
+
+
+/**
+ * Terminal connector manager implementation.
+ */
+@SuppressWarnings("restriction")
+public class ConnectorManager {
+
+ /*
+ * Thread save singleton instance creation.
+ */
+ private static class LazyInstanceHolder {
+ public static ConnectorManager instance = new ConnectorManager();
+ }
+
+ /**
+ * Returns the singleton instance for the terminal connector manager.
+ */
+ public static ConnectorManager getInstance() {
+ return LazyInstanceHolder.instance;
+ }
+
+ /**
+ * Constructor.
+ */
+ ConnectorManager() {
+ super();
+ }
+
+ /**
+ * Creates a terminal connector object based on the given telnet server attributes.
+ * <p>
+ * The telnet server attributes must contain 2 elements:
+ * <ul>
+ * <li>attributes[0] --> telnet server host name</li>
+ * <li>attributes[1] --> telnet port</li>
+ * <li>attributes[2] --> timeout</li>
+ * </ul>
+ *
+ * @param attributes The telnet server attributes. Must not be <code>null</code> and must have at least two elements.
+ * @param portOffset Offset to add to the port.
+ *
+ * @return The terminal connector object instance or <code>null</code>.
+ */
+ public ITerminalConnector createTelnetConnector(String[] attributes) {
+ return createTelnetConnector(attributes, 0);
+ }
+
+ /**
+ * Creates a terminal connector object based on the given telnet server attributes.
+ * <p>
+ * The telnet server attributes must contain at least 2 elements:
+ * <ul>
+ * <li>attributes[0] --> telnet server host name</li>
+ * <li>attributes[1] --> telnet port</li>
+ * <li>attributes[2] --> timeout (optional)</li>
+ * </ul>
+ *
+ * @param attributes The telnet server attributes. Must not be <code>null</code> and must have at least two elements.
+ * @param portOffset Offset to add to the port.
+ *
+ * @return The terminal connector object instance or <code>null</code>.
+ */
+ public ITerminalConnector createTelnetConnector(String[] attributes, int portOffset) {
+ assert attributes != null && attributes.length >= 2;
+
+ final String serverName = attributes[0];
+ final String serverPort = Integer.toString(Integer.decode(attributes[1]).intValue() + portOffset);
+ final String timeout = attributes.length >= 3 ? attributes[2] : null;
+
+ // Construct the terminal settings store
+ ISettingsStore store = new SettingsStore();
+
+ // Construct the telnet settings
+ TelnetSettings telnetSettings = new TelnetSettings();
+ telnetSettings.setHost(serverName);
+ telnetSettings.setNetworkPort(serverPort);
+ if (timeout != null) {
+ telnetSettings.setTimeout(timeout);
+ }
+ // And save the settings to the store
+ telnetSettings.save(store);
+
+ // Construct the terminal connector instance
+ ITerminalConnector connector = TerminalConnectorExtension.makeTerminalConnector("org.eclipse.tm.internal.terminal.telnet.TelnetConnector"); //$NON-NLS-1$
+ if (connector != null) {
+ // Apply default settings
+ connector.makeSettingsPage();
+ // And load the real settings
+ connector.load(store);
+ }
+
+ return connector;
+ }
+
+ /**
+ * Creates a terminal connector object based on the given process image
+ * and the corresponding process object.
+ *
+ * @param connectorTypeId Optional ID of the specific process connector implementation to use.
+ * If <code>null</code>, the default process connector will be used.
+ * @param image The process image path. Must not be <code>null</code>.
+ * @param arguments The process arguments or <code>null</code>.
+ * @param process The process. Must not be <code>null</code>.
+ * @param pty The pseudo terminal or <code>null</code>.
+ * @param localEcho <code>True</code> if the terminal widget local echo shall be enabled, <code>false</code> otherwise.
+ *
+ * @return The terminal connector object instance or <code>null</code>.
+ */
+ public ITerminalConnector createProcessConnector(String connectorTypeId, final String image, final String arguments, final Process process, PTY pty, boolean localEcho) {
+ assert image != null || process != null;
+
+ // Normalize the process connector id
+ if (connectorTypeId == null) connectorTypeId = "org.eclipse.tm.te.ui.terminals.ProcessConnector"; //$NON-NLS-1$
+
+ // Construct the terminal settings store
+ ISettingsStore store = new SettingsStore();
+
+ // Construct the process settings
+ ProcessSettings processSettings = new ProcessSettings();
+ processSettings.setImage(image);
+ processSettings.setArguments(arguments);
+ processSettings.setProcess(process);
+ processSettings.setPTY(pty);
+ processSettings.setLocalEcho(localEcho);
+ // And save the settings to the store
+ processSettings.save(store);
+
+ // Construct the terminal connector instance
+ ITerminalConnector connector = TerminalConnectorExtension.makeTerminalConnector(connectorTypeId);
+ if (connector != null) {
+ // Apply default settings
+ connector.makeSettingsPage();
+ // And load the real settings
+ connector.load(store);
+ }
+
+ return connector;
+ }
+
+ /**
+ * Creates a terminal connector object based on the given stream objects.
+ *
+ * @param stdin The stdin stream or <code>null</code>.
+ * @param stdout The stdout stream or <code>null</code>.
+ * @param stderr The stderr stream or <code>null</code>.
+ * @param localEcho <code>True</code> if the terminal widget local echo shall be enabled, <code>false</code> otherwise.
+ *
+ * @return The terminal connector object instance or <code>null</code>.
+ */
+ public ITerminalConnector createStreamsConnector(OutputStream stdin, InputStream stdout, InputStream stderr, boolean localEcho) {
+
+ // Construct the terminal settings store
+ ISettingsStore store = new SettingsStore();
+
+ // Construct the streams settings
+ StreamsSettings streamsSettings = new StreamsSettings();
+ streamsSettings.setStdinStream(stdin);
+ streamsSettings.setStdoutStream(stdout);
+ streamsSettings.setStderrStream(stderr);
+ streamsSettings.setLocalEcho(localEcho);
+ // And save the settings to the store
+ streamsSettings.save(store);
+
+ // Construct the terminal connector instance
+ ITerminalConnector connector = TerminalConnectorExtension.makeTerminalConnector("org.eclipse.tm.te.ui.terminals.StreamsConnector"); //$NON-NLS-1$
+ if (connector != null) {
+ // Apply default settings
+ connector.makeSettingsPage();
+ // And load the real settings
+ connector.load(store);
+ }
+
+ return connector;
+ }
+}
diff --git a/target_explorer/plugins/org.eclipse.tm.te.ui.terminals/src/org/eclipse/tm/te/ui/terminals/manager/ConsoleManager.java b/target_explorer/plugins/org.eclipse.tm.te.ui.terminals/src/org/eclipse/tm/te/ui/terminals/manager/ConsoleManager.java
new file mode 100644
index 000000000..e2ee3c91d
--- /dev/null
+++ b/target_explorer/plugins/org.eclipse.tm.te.ui.terminals/src/org/eclipse/tm/te/ui/terminals/manager/ConsoleManager.java
@@ -0,0 +1,300 @@
+/*******************************************************************************
+ * Copyright (c) 2011 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
+ *
+ * Contributors:
+ * Wind River Systems - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.tm.te.ui.terminals.manager;
+
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.List;
+
+import org.eclipse.core.runtime.IStatus;
+import org.eclipse.core.runtime.Status;
+import org.eclipse.swt.custom.CTabItem;
+import org.eclipse.swt.widgets.Display;
+import org.eclipse.tm.internal.terminal.provisional.api.ITerminalConnector;
+import org.eclipse.tm.te.ui.terminals.activator.UIPlugin;
+import org.eclipse.tm.te.ui.terminals.interfaces.IPreferenceKeys;
+import org.eclipse.tm.te.ui.terminals.interfaces.ITerminalsView;
+import org.eclipse.tm.te.ui.terminals.interfaces.IUIConstants;
+import org.eclipse.tm.te.ui.terminals.tabs.TabFolderManager;
+import org.eclipse.tm.te.ui.terminals.view.TerminalsView;
+import org.eclipse.ui.IPerspectiveDescriptor;
+import org.eclipse.ui.IPerspectiveListener;
+import org.eclipse.ui.IViewPart;
+import org.eclipse.ui.IViewReference;
+import org.eclipse.ui.IWorkbenchPage;
+import org.eclipse.ui.PartInitException;
+import org.eclipse.ui.PerspectiveAdapter;
+import org.eclipse.ui.PlatformUI;
+
+/**
+ * Terminals console manager.
+ */
+@SuppressWarnings("restriction")
+public class ConsoleManager {
+ // Reference to the perspective listener instance
+ private final IPerspectiveListener perspectiveListener;
+
+ // Internal perspective listener implementation
+ static class TerminalConsoleManagerPerspectiveListener extends PerspectiveAdapter {
+ private final List<IViewReference> references = new ArrayList<IViewReference>();
+
+ /* (non-Javadoc)
+ * @see org.eclipse.ui.PerspectiveAdapter#perspectiveActivated(org.eclipse.ui.IWorkbenchPage, org.eclipse.ui.IPerspectiveDescriptor)
+ */
+ @Override
+ public void perspectiveActivated(IWorkbenchPage page, IPerspectiveDescriptor perspective) {
+ // If the old references list is empty, just return
+ if (references.isEmpty()) return;
+ // Create a copy of the old view references list
+ List<IViewReference> oldReferences = new ArrayList<IViewReference>(references);
+
+ // Get the current list of view references
+ List<IViewReference> references = new ArrayList<IViewReference>(Arrays.asList(page.getViewReferences()));
+ for (IViewReference reference : oldReferences) {
+ if (references.contains(reference)) continue;
+ // Previous visible terminal console view reference, make visible again
+ try {
+ page.showView(reference.getId(), reference.getSecondaryId(), IWorkbenchPage.VIEW_VISIBLE);
+ } catch (PartInitException e) { /* Failure on part instantiation is ignored */ }
+ }
+
+ }
+
+ /* (non-Javadoc)
+ * @see org.eclipse.ui.PerspectiveAdapter#perspectivePreDeactivate(org.eclipse.ui.IWorkbenchPage, org.eclipse.ui.IPerspectiveDescriptor)
+ */
+ @Override
+ public void perspectivePreDeactivate(IWorkbenchPage page, IPerspectiveDescriptor perspective) {
+ references.clear();
+ for (IViewReference reference : page.getViewReferences()) {
+ IViewPart part = reference.getView(false);
+ if (part instanceof TerminalsView && !references.contains(reference)) {
+ references.add(reference);
+ }
+ }
+ }
+ }
+
+ /*
+ * Thread save singleton instance creation.
+ */
+ private static class LazyInstanceHolder {
+ public static ConsoleManager fInstance = new ConsoleManager();
+ }
+
+ /**
+ * Returns the singleton instance for the console manager.
+ */
+ public static ConsoleManager getInstance() {
+ return LazyInstanceHolder.fInstance;
+ }
+
+ /**
+ * Constructor.
+ */
+ ConsoleManager() {
+ super();
+
+ // Attach the perspective listener
+ perspectiveListener = new TerminalConsoleManagerPerspectiveListener();
+ if (PlatformUI.isWorkbenchRunning() && PlatformUI.getWorkbench() != null && PlatformUI.getWorkbench().getActiveWorkbenchWindow() != null) {
+ PlatformUI.getWorkbench().getActiveWorkbenchWindow().addPerspectiveListener(perspectiveListener);
+ }
+ }
+
+ /**
+ * Returns the active workbench window page if the workbench is still running.
+ *
+ * @return The active workbench window page or <code>null</code>
+ */
+ private final IWorkbenchPage getActiveWorkbenchPage() {
+ // To lookup the console view, the workbench must be still running
+ if (PlatformUI.isWorkbenchRunning() && PlatformUI.getWorkbench() != null && PlatformUI.getWorkbench().getActiveWorkbenchWindow() != null) {
+ return PlatformUI.getWorkbench().getActiveWorkbenchWindow().getActivePage();
+ }
+ return null;
+ }
+
+ /**
+ * Returns the console view if available within the active workbench window page.
+ * <p>
+ * <b>Note:</b> The method must be called within the UI thread.
+ *
+ * @param id The terminal console view id or <code>null</code> to show the default terminal console view.
+ * @return The console view instance if available or <code>null</code> otherwise.
+ */
+ public ITerminalsView findConsoleView(String id) {
+ assert Display.findDisplay(Thread.currentThread()) != null;
+
+ ITerminalsView view = null;
+
+ // Get the active workbench page
+ IWorkbenchPage page = getActiveWorkbenchPage();
+ if (page != null) {
+ // Look for the view
+ IViewPart part = page.findView(id != null ? id : IUIConstants.ID);
+ // Check the interface
+ if (part instanceof ITerminalsView) {
+ view = (ITerminalsView)part;
+ }
+ }
+
+ return view;
+ }
+
+ /**
+ * Show the terminal console view specified by the given id.
+ * <p>
+ * <b>Note:</b> The method must be called within the UI thread.
+ *
+ * @param id The terminal console view id or <code>null</code> to show the default terminal console view.
+ */
+ public void showConsoleView(String id) {
+ assert Display.findDisplay(Thread.currentThread()) != null;
+
+ // Get the active workbench page
+ IWorkbenchPage page = getActiveWorkbenchPage();
+ if (page != null) {
+ try {
+ // show the view
+ IViewPart part = page.showView(id != null ? id : IUIConstants.ID);
+ // and force the view to the foreground
+ page.bringToTop(part);
+ } catch (PartInitException e) {
+ IStatus status = new Status(IStatus.ERROR, UIPlugin.getUniqueIdentifier(),
+ e.getLocalizedMessage(), e);
+ UIPlugin.getDefault().getLog().log(status);
+ }
+ }
+ }
+
+ /**
+ * Bring the terminal console view, specified by the given id, to the top of the view stack.
+ *
+ * @param id The terminal console view id or <code>null</code> to show the default terminal console view.
+ * @param activate If <code>true</code> activate the console view.
+ */
+ private void bringToTop(String id, boolean activate) {
+ // Get the active workbench page
+ IWorkbenchPage page = getActiveWorkbenchPage();
+ if (page != null) {
+ // Look for the view
+ IViewPart part = page.findView(id != null ? id : IUIConstants.ID);
+ if (part != null) {
+ if (activate) {
+ page.activate(part);
+ }
+ else {
+ page.bringToTop(part);
+ }
+ } else if (activate) showConsoleView(id != null ? id : IUIConstants.ID);
+ }
+ }
+
+ /**
+ * Opens the console with the given title and connector.
+ * <p>
+ * <b>Note:</b> The method must be called within the UI thread.
+ *
+ * @param id The terminal console view id or <code>null</code> to show the default terminal console view.
+ * @param title The console title. Must not be <code>null</code>.
+ * @param connector The terminal connector. Must not be <code>null</code>.
+ * @param data The custom terminal data node or <code>null</code>.
+ * @param activate If <code>true</code> activate the console view.
+ */
+ public void openConsole(String id, String title, ITerminalConnector connector, Object data, boolean activate) {
+ assert title != null && connector != null;
+ assert Display.findDisplay(Thread.currentThread()) != null;
+
+ // make the consoles view visible
+ bringToTop(id, activate);
+
+ // Get the console view
+ ITerminalsView view = findConsoleView(id);
+ if (view == null) return;
+
+ // Get the tab folder manager associated with the view
+ TabFolderManager manager = (TabFolderManager)view.getAdapter(TabFolderManager.class);
+ if (manager == null) return;
+
+ // Lookup an existing console first
+ CTabItem item = findConsole(id, title, connector, data);
+
+ // If no existing console exist -> Create the tab item
+ if (item == null) {
+ // If configured, check all existing tab items if they are associated
+ // with terminated consoles
+ if (UIPlugin.getScopedPreferences().getBoolean(IPreferenceKeys.PREF_REMOVE_TERMINATED_TERMINALS)) {
+ manager.removeTerminatedItems();
+ }
+
+ // Create a new tab item
+ item = manager.createTabItem(title, connector, data);
+ }
+ // If still null, something went wrong
+ if (item == null) {
+ return;
+ }
+
+ // Make the item the active console
+ manager.bringToTop(item);
+
+ // Show the tab folder page
+ view.switchToTabFolderControl();
+ }
+
+ /**
+ * Lookup a console with the given title and the given terminal connector.
+ * <p>
+ * <b>Note:</b> The method must be called within the UI thread.
+ * <b>Note:</b> The method will handle unified console titles itself.
+ *
+ * @param id The terminal console view id or <code>null</code> to show the default terminal console view.
+ * @param title The console title. Must not be <code>null</code>.
+ * @param connector The terminal connector. Must not be <code>null</code>.
+ * @param data The custom terminal data node or <code>null</code>.
+ *
+ * @return The corresponding console tab item or <code>null</code>.
+ */
+ public CTabItem findConsole(String id, String title, ITerminalConnector connector, Object data) {
+ assert title != null && connector != null;
+ assert Display.findDisplay(Thread.currentThread()) != null;
+
+ // Get the console view
+ ITerminalsView view = findConsoleView(id);
+ if (view == null) return null;
+
+ // Get the tab folder manager associated with the view
+ TabFolderManager manager = (TabFolderManager)view.getAdapter(TabFolderManager.class);
+ if (manager == null) return null;
+
+ return manager.findTabItem(title, connector, data);
+ }
+
+ /**
+ * Close the console with the given title and the given terminal connector.
+ * <p>
+ * <b>Note:</b> The method must be called within the UI thread.
+ * <b>Note:</b> The method will handle unified console titles itself.
+ *
+ * @param title The console title. Must not be <code>null</code>.
+ * @param connector The terminal connector. Must not be <code>null</code>.
+ * @param data The custom terminal data node or <code>null</code>.
+ */
+ public void closeConsole(String id, String title, ITerminalConnector connector, Object data) {
+ assert title != null && connector != null;
+ assert Display.findDisplay(Thread.currentThread()) != null;
+
+ // Lookup the console
+ CTabItem console = findConsole(id, title, connector, data);
+ // If found, dispose the console
+ if (console != null) console.dispose();
+ }
+}
diff --git a/target_explorer/plugins/org.eclipse.tm.te.ui.terminals/src/org/eclipse/tm/te/ui/terminals/nls/Messages.java b/target_explorer/plugins/org.eclipse.tm.te.ui.terminals/src/org/eclipse/tm/te/ui/terminals/nls/Messages.java
new file mode 100644
index 000000000..c5cf6b22f
--- /dev/null
+++ b/target_explorer/plugins/org.eclipse.tm.te.ui.terminals/src/org/eclipse/tm/te/ui/terminals/nls/Messages.java
@@ -0,0 +1,47 @@
+/*******************************************************************************
+ * Copyright (c) 2011 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
+ *
+ * Contributors:
+ * Wind River Systems - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.tm.te.ui.terminals.nls;
+
+import org.eclipse.osgi.util.NLS;
+
+/**
+ * Terminals plug-in externalized strings management.
+ */
+public class Messages extends NLS {
+
+ // The plug-in resource bundle name
+ private static final String BUNDLE_NAME = "org.eclipse.tm.te.ui.terminals.nls.Messages"; //$NON-NLS-1$
+
+ /**
+ * Static constructor.
+ */
+ static {
+ // Load message values from bundle file
+ NLS.initializeMessages(BUNDLE_NAME, Messages.class);
+ }
+
+ // **** Declare externalized string id's down here *****
+
+ public static String AbstractAction_error_commandExecutionFailed;
+
+ public static String TabTerminalListener_consoleTerminated;
+
+ public static String ProcessSettingsPage_dialogTitle;
+ public static String ProcessSettingsPage_processImagePathSelectorControl_label;
+ public static String ProcessSettingsPage_processImagePathSelectorControl_button;
+ public static String ProcessSettingsPage_processArgumentsControl_label;
+ public static String ProcessSettingsPage_localEchoSelectorControl_label;
+
+ public static String OutputStreamMonitor_error_readingFromStream;
+
+ public static String InputStreamMonitor_error_writingToStream;
+
+ public static String ProcessConnector_error_creatingProcess;
+}
diff --git a/target_explorer/plugins/org.eclipse.tm.te.ui.terminals/src/org/eclipse/tm/te/ui/terminals/nls/Messages.properties b/target_explorer/plugins/org.eclipse.tm.te.ui.terminals/src/org/eclipse/tm/te/ui/terminals/nls/Messages.properties
new file mode 100644
index 000000000..992eeb80e
--- /dev/null
+++ b/target_explorer/plugins/org.eclipse.tm.te.ui.terminals/src/org/eclipse/tm/te/ui/terminals/nls/Messages.properties
@@ -0,0 +1,20 @@
+#
+# org.eclipse.tm.te.ui.terminals
+# Externalized Strings.
+#
+
+AbstractAction_error_commandExecutionFailed="Failed to execute command (id = {0}). Possibly caused by: {1}
+
+TabTerminalListener_consoleTerminated=<terminated> {0}
+
+ProcessSettingsPage_dialogTitle=Select Process Image
+ProcessSettingsPage_processImagePathSelectorControl_label=Image Path:
+ProcessSettingsPage_processImagePathSelectorControl_button=Browse
+ProcessSettingsPage_processArgumentsControl_label=Arguments:
+ProcessSettingsPage_localEchoSelectorControl_label=Local Echo
+
+OutputStreamMonitor_error_readingFromStream=Exception when reading from stream. Possibly caused by: {0}
+
+InputStreamMonitor_error_writingToStream=Exception when writing to stream. Possibly caused by: {0}
+
+ProcessConnector_error_creatingProcess=Exception when creating process. Possibly caused by: {0}
diff --git a/target_explorer/plugins/org.eclipse.tm.te.ui.terminals/src/org/eclipse/tm/te/ui/terminals/process/ProcessConnector.java b/target_explorer/plugins/org.eclipse.tm.te.ui.terminals/src/org/eclipse/tm/te/ui/terminals/process/ProcessConnector.java
new file mode 100644
index 000000000..84f9df3c0
--- /dev/null
+++ b/target_explorer/plugins/org.eclipse.tm.te.ui.terminals/src/org/eclipse/tm/te/ui/terminals/process/ProcessConnector.java
@@ -0,0 +1,425 @@
+/*******************************************************************************
+ * Copyright (c) 2011 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
+ *
+ * Contributors:
+ * Wind River Systems - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.tm.te.ui.terminals.process;
+
+import java.io.BufferedInputStream;
+import java.io.BufferedReader;
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.InputStreamReader;
+import java.io.StreamTokenizer;
+import java.io.StringReader;
+import java.util.ArrayList;
+import java.util.Enumeration;
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+import java.util.Properties;
+
+import org.eclipse.cdt.utils.pty.PTY;
+import org.eclipse.cdt.utils.spawner.ProcessFactory;
+import org.eclipse.core.runtime.Assert;
+import org.eclipse.core.runtime.IPath;
+import org.eclipse.core.runtime.IStatus;
+import org.eclipse.core.runtime.Platform;
+import org.eclipse.core.runtime.Status;
+import org.eclipse.osgi.service.environment.Constants;
+import org.eclipse.osgi.util.NLS;
+import org.eclipse.tm.internal.terminal.provisional.api.ISettingsPage;
+import org.eclipse.tm.internal.terminal.provisional.api.ISettingsStore;
+import org.eclipse.tm.internal.terminal.provisional.api.ITerminalControl;
+import org.eclipse.tm.internal.terminal.provisional.api.TerminalState;
+import org.eclipse.tm.te.ui.terminals.activator.UIPlugin;
+import org.eclipse.tm.te.ui.terminals.nls.Messages;
+import org.eclipse.tm.te.ui.terminals.streams.AbstractStreamsConnector;
+
+/**
+ * Process connector implementation.
+ */
+@SuppressWarnings("restriction")
+public class ProcessConnector extends AbstractStreamsConnector {
+ // Reference to the process settings
+ private final ProcessSettings settings;
+
+ // Reference to the PTY instance.
+ private PTY pty;
+ // Reference to the launched process instance.
+ private Process process;
+ // Reference to the process monitor
+ private ProcessMonitor monitor;
+
+ // The terminal width and height. Initially unknown.
+ private int width = -1;
+ private int height = -1;
+
+ /**
+ * Constructor.
+ */
+ public ProcessConnector() {
+ this(new ProcessSettings());
+ }
+
+ /**
+ * Constructor.
+ *
+ * @param settings The process settings. Must not be <code>null</code>
+ */
+ public ProcessConnector(ProcessSettings settings) {
+ super();
+
+ Assert.isNotNull(settings);
+ this.settings = settings;
+ }
+
+ /**
+ * Returns the process object or <code>null</code> if the
+ * connector is connector.
+ *
+ * @return The process object or <code>null</code>.
+ */
+ public Process getProcess() {
+ return process;
+ }
+
+ /* (non-Javadoc)
+ * @see org.eclipse.tm.internal.terminal.provisional.api.provider.TerminalConnectorImpl#connect(org.eclipse.tm.internal.terminal.provisional.api.ITerminalControl)
+ */
+ @Override
+ public void connect(ITerminalControl control) {
+ assert control != null;
+ super.connect(control);
+
+ pty = null;
+ width = -1;
+ height = -1;
+
+ try {
+ // Try to determine process and PTY instance from the process settings
+ process = settings.getProcess();
+ pty = settings.getPTY();
+
+ // No process -> create PTY on supported platforms and execute
+ // process image.
+ if (process == null) {
+ if (PTY.isSupported()) {
+ try {
+ pty = new PTY(false);
+ } catch (IOException e) {
+ // PTY not supported on windows
+ }
+ }
+
+ // Build up the command
+ StringBuilder command = new StringBuilder(settings.getImage());
+ String arguments = settings.getArguments();
+ if (arguments != null && !"".equals(arguments.trim())) { //$NON-NLS-1$
+ // Append to the command now
+ command.append(" "); //$NON-NLS-1$
+ command.append(arguments.trim());
+ }
+
+ if (pty != null) {
+ // A PTY is available -> can use the ProcessFactory.
+
+ // Tokenize the command (ProcessFactory takes an array)
+ StreamTokenizer st = new StreamTokenizer(new StringReader(command.toString()));
+ st.resetSyntax();
+ st.whitespaceChars(0, 32);
+ st.whitespaceChars(0xa0, 0xa0);
+ st.wordChars(33, 255);
+ st.quoteChar('"');
+ st.quoteChar('\'');
+
+ List<String> argv = new ArrayList<String>();
+ int ttype = st.nextToken();
+ while (ttype != StreamTokenizer.TT_EOF) {
+ argv.add(st.sval);
+ ttype = st.nextToken();
+ }
+
+ // Execute the process
+ process = ProcessFactory.getFactory().exec(argv.toArray(new String[argv.size()]), getProcessEnvironment(), null, pty);
+ } else {
+ // No PTY -> just execute via the standard Java Runtime implementation.
+ process = Runtime.getRuntime().exec(command.toString());
+ }
+ }
+
+ // connect the streams
+ connectStreams(control, process.getOutputStream(), process.getInputStream(), (pty == null ? process.getErrorStream() : null));
+
+ // Set the terminal control state to CONNECTED
+ control.setState(TerminalState.CONNECTED);
+
+ // Create the process monitor
+ monitor = new ProcessMonitor(this);
+ monitor.startMonitoring();
+ } catch (Exception e) {
+ IStatus status = new Status(IStatus.ERROR, UIPlugin.getUniqueIdentifier(),
+ NLS.bind(Messages.ProcessConnector_error_creatingProcess, e.getLocalizedMessage()), e);
+ UIPlugin.getDefault().getLog().log(status);
+ }
+ }
+
+ /* (non-Javadoc)
+ * @see org.eclipse.tm.internal.terminal.provisional.api.provider.TerminalConnectorImpl#isLocalEcho()
+ */
+ @Override
+ public boolean isLocalEcho() {
+ return settings.isLocalEcho();
+ }
+
+ /* (non-Javadoc)
+ * @see org.eclipse.tm.internal.terminal.provisional.api.provider.TerminalConnectorImpl#doDisconnect()
+ */
+ @Override
+ public void doDisconnect() {
+ // Dispose the process
+ if (process != null) { process.destroy(); process = null; }
+
+ // Dispose the streams
+ super.doDisconnect();
+
+ // Set the terminal control state to CLOSED.
+ fControl.setState(TerminalState.CLOSED);
+ }
+
+ // ***** Process Connector settings handling *****
+
+ /* (non-Javadoc)
+ * @see org.eclipse.tm.internal.terminal.provisional.api.provider.TerminalConnectorImpl#makeSettingsPage()
+ */
+ @Override
+ public ISettingsPage makeSettingsPage() {
+ return new ProcessSettingsPage(settings);
+ }
+
+ /* (non-Javadoc)
+ * @see org.eclipse.tm.internal.terminal.provisional.api.provider.TerminalConnectorImpl#getSettingsSummary()
+ */
+ @Override
+ public String getSettingsSummary() {
+ return settings.getImage() != null ? settings.getImage() : ""; //$NON-NLS-1$
+ }
+
+ /* (non-Javadoc)
+ * @see org.eclipse.tm.internal.terminal.provisional.api.provider.TerminalConnectorImpl#load(org.eclipse.tm.internal.terminal.provisional.api.ISettingsStore)
+ */
+ @Override
+ public void load(ISettingsStore store) {
+ settings.load(store);
+ }
+
+ /* (non-Javadoc)
+ * @see org.eclipse.tm.internal.terminal.provisional.api.provider.TerminalConnectorImpl#save(org.eclipse.tm.internal.terminal.provisional.api.ISettingsStore)
+ */
+ @Override
+ public void save(ISettingsStore store) {
+ settings.save(store);
+ }
+
+ /* (non-Javadoc)
+ * @see org.eclipse.tm.internal.terminal.provisional.api.provider.TerminalConnectorImpl#setTerminalSize(int, int)
+ */
+ @Override
+ public void setTerminalSize(int newWidth, int newHeight) {
+ if (width != newWidth || height != newHeight) {
+ width = newWidth;
+ height = newHeight;
+ if (pty != null) {
+ pty.setTerminalSize(newWidth, newHeight);
+ }
+ }
+ }
+
+ // ***** Process Environment Handling *****
+
+ // Reference to the monitor to lock if determining the native environment
+ private final static Object ENV_GET_MONITOR = new Object();
+
+ // Reference to the native environment once retrieved
+ private static Map<String, String> nativeEnvironment = null;
+ // Reference to the native environment with the case of the variable names preserved
+ private static Map<String, String> nativeEnvironmentCasePreserved = null;
+
+ /**
+ * Returns the specific environment to set for the process to be launched.
+ *
+ * @return The process environment.
+ */
+ private static String[] getProcessEnvironment() {
+ Map<String, String> env = getNativeEnvironment();
+
+ env.put("TERM", "vt100"); //$NON-NLS-1$ //$NON-NLS-2$
+
+ Iterator<Map.Entry<String, String>> iter = env.entrySet().iterator();
+ List<String> strings = new ArrayList<String>(env.size());
+ StringBuffer buffer = null;
+ while (iter.hasNext()) {
+ Map.Entry<String, String>entry = iter.next();
+ buffer = new StringBuffer(entry.getKey());
+ buffer.append('=').append(entry.getValue());
+ strings.add(buffer.toString());
+ }
+
+ return strings.toArray(new String[strings.size()]);
+ }
+
+ /**
+ * Determine the native environment, but returns all environment variable
+ * names in upper case.
+ *
+ * @return The native environment with upper case variable names, or an empty map.
+ */
+ private static Map<String, String> getNativeEnvironment() {
+ synchronized (ENV_GET_MONITOR) {
+ if (nativeEnvironment == null) {
+ Map<String, String> casePreserved = getNativeEnvironmentCasePreserved();
+ if (Platform.getOS().equals(org.eclipse.osgi.service.environment.Constants.OS_WIN32)) {
+ nativeEnvironment = new HashMap<String, String>();
+ Iterator<Map.Entry<String, String>> entries = casePreserved.entrySet().iterator();
+ while (entries.hasNext()) {
+ Map.Entry<String, String> entry = entries.next();
+ nativeEnvironment.put(entry.getKey().toUpperCase(), entry.getValue());
+ }
+ } else {
+ nativeEnvironment = new HashMap<String, String>(casePreserved);
+ }
+ }
+ return new HashMap<String, String>(nativeEnvironment);
+ }
+ }
+
+ /**
+ * Determine the native environment.
+ *
+ * @return The native environment, or an empty map.
+ */
+ private static Map<String, String> getNativeEnvironmentCasePreserved() {
+ synchronized (ENV_GET_MONITOR) {
+ if (nativeEnvironmentCasePreserved == null) {
+ nativeEnvironmentCasePreserved= new HashMap<String, String>();
+ cacheNativeEnvironment(nativeEnvironmentCasePreserved);
+ }
+ return new HashMap<String, String>(nativeEnvironmentCasePreserved);
+ }
+ }
+
+ /**
+ * Query the native environment and store it to the specified cache.
+ *
+ * @param cache The environment cache. Must not be <code>null</code>.
+ */
+ private static void cacheNativeEnvironment(Map<String, String> cache) {
+ Assert.isNotNull(cache);
+
+ try {
+ String nativeCommand = null;
+ boolean isWin9xME = false; // see bug 50567
+ String fileName = null;
+ if (Platform.getOS().equals(Constants.OS_WIN32)) {
+ String osName = System.getProperty("os.name"); //$NON-NLS-1$
+ isWin9xME = osName != null && (osName.startsWith("Windows 9") || osName.startsWith("Windows ME")); //$NON-NLS-1$ //$NON-NLS-2$
+ if (isWin9xME) {
+ // Win 95, 98, and ME
+ // SET might not return therefore we pipe into a file
+ IPath stateLocation = UIPlugin.getDefault().getStateLocation();
+ fileName = stateLocation.toOSString() + File.separator + "env.txt"; //$NON-NLS-1$
+ nativeCommand = "command.com /C set > " + fileName; //$NON-NLS-1$
+ } else {
+ // Win NT, 2K, XP
+ nativeCommand = "cmd.exe /C set"; //$NON-NLS-1$
+ }
+ } else if (!Platform.getOS().equals(Constants.OS_UNKNOWN)) {
+ nativeCommand = "env"; //$NON-NLS-1$
+ }
+ if (nativeCommand == null) { return; }
+ Process process = Runtime.getRuntime().exec(nativeCommand);
+ if (isWin9xME) {
+ // read piped data on Win 95, 98, and ME
+ Properties p = new Properties();
+ File file = new File(fileName);
+ InputStream stream = new BufferedInputStream(new FileInputStream(file));
+ p.load(stream);
+ stream.close();
+ if (!file.delete()) {
+ file.deleteOnExit(); // if delete() fails try again on VM close
+ }
+ for (Enumeration<Object> enumeration = p.keys(); enumeration.hasMoreElements();) {
+ // Win32's environment variables are case insensitive. Put everything
+ // to upper case so that (for example) the "PATH" variable will match
+ // "pAtH" correctly on Windows.
+ String key = (String)enumeration.nextElement();
+ cache.put(key, (String)p.get(key));
+ }
+ } else {
+ // read process directly on other platforms
+ // we need to parse out matching '{' and '}' for function declarations in .bash environments
+ // pattern is [function name]=() { and we must find the '}' on its own line with no trailing ';'
+ InputStream stream = process.getInputStream();
+ InputStreamReader isreader = new InputStreamReader(stream);
+ BufferedReader reader = new BufferedReader(isreader);
+ String line = reader.readLine();
+ String key = null;
+ String value = null;
+ while (line != null) {
+ int func = line.indexOf("=()"); //$NON-NLS-1$
+ if (func > 0) {
+ key = line.substring(0, func);
+ // scan until we find the closing '}' with no following chars
+ value = line.substring(func + 1);
+ while (line != null && !line.equals("}")) { //$NON-NLS-1$
+ line = reader.readLine();
+ if (line != null) {
+ value += line;
+ }
+ }
+ line = reader.readLine();
+ } else {
+ int separator = line.indexOf('=');
+ if (separator > 0) {
+ key = line.substring(0, separator);
+ value = line.substring(separator + 1);
+ line = reader.readLine();
+ if (line != null) {
+ // this line has a '=' read ahead to check next line for '=', might be broken on more
+ // than one line
+ separator = line.indexOf('=');
+ while (separator < 0) {
+ value += line.trim();
+ line = reader.readLine();
+ if (line == null) {
+ // if next line read is the end of the file quit the loop
+ break;
+ }
+ separator = line.indexOf('=');
+ }
+ }
+ }
+ }
+ if (key != null) {
+ cache.put(key, value);
+ key = null;
+ value = null;
+ } else {
+ line = reader.readLine();
+ }
+ }
+ reader.close();
+ }
+ } catch (IOException e) {
+ // Native environment-fetching code failed.
+ // This can easily happen and is not useful to log.
+ }
+ }
+}
diff --git a/target_explorer/plugins/org.eclipse.tm.te.ui.terminals/src/org/eclipse/tm/te/ui/terminals/process/ProcessMonitor.java b/target_explorer/plugins/org.eclipse.tm.te.ui.terminals/src/org/eclipse/tm/te/ui/terminals/process/ProcessMonitor.java
new file mode 100644
index 000000000..98c9d6073
--- /dev/null
+++ b/target_explorer/plugins/org.eclipse.tm.te.ui.terminals/src/org/eclipse/tm/te/ui/terminals/process/ProcessMonitor.java
@@ -0,0 +1,106 @@
+/*******************************************************************************
+ * Copyright (c) 2011 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
+ *
+ * Contributors:
+ * Wind River Systems - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.tm.te.ui.terminals.process;
+
+import org.eclipse.core.runtime.Assert;
+
+
+/**
+ * Process monitor implementation.
+ */
+public class ProcessMonitor {
+ // Reference to the parent process connector
+ private final ProcessConnector processConnector;
+ // Reference to the monitored process
+ private final Process process;
+ // Reference to the monitor thread
+ private Thread thread;
+ // Flag to mark the monitor disposed
+ private boolean disposed;
+
+
+ /**
+ * Constructor.
+ *
+ * @param processConnector The parent process connector. Must not be <code>null</code>.
+ */
+ public ProcessMonitor(ProcessConnector processConnector) {
+ super();
+
+ Assert.isNotNull(processConnector);
+ this.processConnector = processConnector;
+
+ // Query the monitored process for easier access
+ this.process = processConnector.getProcess();
+ }
+
+ /**
+ * Dispose the process monitor.
+ */
+ public void dispose() {
+ // Set the disposed status
+ disposed = true;
+ // Not initialized -> return immediately
+ if (thread == null) return;
+
+ // Copy the reference
+ final Thread oldThread = thread;
+ // Unlink the monitor from the thread
+ thread = null;
+ // And interrupt the writer thread
+ oldThread.interrupt();
+ }
+
+ /**
+ * Starts the terminal output stream monitor.
+ */
+ public void startMonitoring() {
+ // If already initialized -> return immediately
+ if (thread != null) return;
+
+ // Create a new runnable which is constantly reading from the stream
+ Runnable runnable = new Runnable() {
+ @Override
+ public void run() {
+ monitorProcess();
+ }
+ };
+
+ // Create the monitor thread
+ thread = new Thread(runnable, "Terminal Process Monitor Thread"); //$NON-NLS-1$
+
+ // Configure the monitor thread
+ thread.setDaemon(true);
+
+ // Start the processing
+ thread.start();
+ }
+
+ /**
+ * Monitors the associated system process, waiting for it to terminate,
+ * and notifies the associated process monitor's.
+ */
+ @SuppressWarnings("restriction")
+ public void monitorProcess() {
+ // If already disposed -> return immediately
+ if (disposed) return;
+
+ try {
+ // Wait for the monitored process to terminate
+ process.waitFor();
+ } catch (InterruptedException ie) {
+ // clear interrupted state
+ Thread.interrupted();
+ } finally {
+ // Dispose the parent process connector
+ processConnector.disconnect();
+ }
+ }
+}
diff --git a/target_explorer/plugins/org.eclipse.tm.te.ui.terminals/src/org/eclipse/tm/te/ui/terminals/process/ProcessSettings.java b/target_explorer/plugins/org.eclipse.tm.te.ui.terminals/src/org/eclipse/tm/te/ui/terminals/process/ProcessSettings.java
new file mode 100644
index 000000000..5976fdfed
--- /dev/null
+++ b/target_explorer/plugins/org.eclipse.tm.te.ui.terminals/src/org/eclipse/tm/te/ui/terminals/process/ProcessSettings.java
@@ -0,0 +1,162 @@
+/*******************************************************************************
+ * Copyright (c) 2011 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
+ *
+ * Contributors:
+ * Wind River Systems - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.tm.te.ui.terminals.process;
+
+import org.eclipse.cdt.utils.pty.PTY;
+import org.eclipse.core.runtime.Assert;
+import org.eclipse.tm.internal.terminal.provisional.api.ISettingsStore;
+import org.eclipse.tm.te.runtime.interfaces.properties.IPropertiesContainer;
+
+/**
+ * Process connector settings implementation.
+ */
+@SuppressWarnings("restriction")
+public class ProcessSettings {
+ // Reference to the process image
+ private String image;
+ // Reference to the process arguments (space separated string)
+ private String arguments;
+ // Reference to the process object
+ private Process process;
+ // Reference to the pseudo terminal object
+ private PTY pty;
+ // Flag to control the local echo (defaults to true if
+ // the PTY is not supported on the current host platform)
+ private boolean localEcho = !PTY.isSupported();
+
+ /**
+ * Sets the process image.
+ *
+ * @param image The process image or <code>null</code>.
+ */
+ public void setImage(String image) {
+ this.image = image;
+ }
+
+ /**
+ * Returns the process image.
+ *
+ * @return The process image or <code>null</code>.
+ */
+ public String getImage() {
+ return image;
+ }
+
+ /**
+ * Sets the process arguments.
+ * <p>
+ * The arguments are space separated. The caller is responsible for
+ * correct quoting.
+ *
+ * @param arguments The process arguments or <code>null</code>.
+ */
+ public void setArguments(String arguments) {
+ this.arguments = arguments;
+ }
+
+ /**
+ * Returns the process arguments.
+ *
+ * @return The process arguments as space separated list or <code>null</code>.
+ */
+ public String getArguments() {
+ return arguments;
+ }
+
+ /**
+ * Sets the process object.
+ *
+ * @param image The process object or <code>null</code>.
+ */
+ public void setProcess(Process process) {
+ this.process = process;
+ }
+
+ /**
+ * Returns the process object.
+ *
+ * @return The process object or <code>null</code>.
+ */
+ public Process getProcess() {
+ return process;
+ }
+
+ /**
+ * Sets the pseudo terminal object.
+ *
+ * @param pty The pseudo terminal or <code>null</code>.
+ */
+ public void setPTY(PTY pty) {
+ this.pty = pty;
+ // If the PTY is set to "null", the local echo will be set to "true"
+ if (pty == null) setLocalEcho(true);
+ }
+
+ /**
+ * Returns the pseudo terminal object.
+ *
+ * @return The pseudo terminal or <code>null</code>.
+ */
+ public PTY getPTY() {
+ return pty;
+ }
+
+ /**
+ * Sets if the process requires a local echo from the
+ * terminal widget.
+ *
+ * @param value Specify <code>true</code> to enable the local echo, <code>false</code> otherwise.
+ */
+ public void setLocalEcho(boolean value) {
+ this.localEcho = value;
+ }
+
+ /**
+ * Returns <code>true</code> if the process requires a local echo
+ * from the terminal widget.
+ *
+ * @return <code>True</code> if local echo is enabled, <code>false</code> otherwise.
+ */
+ public boolean isLocalEcho() {
+ return localEcho;
+ }
+
+ /**
+ * Loads the process settings from the given settings store.
+ *
+ * @param store The settings store. Must not be <code>null</code>.
+ */
+ public void load(ISettingsStore store) {
+ Assert.isNotNull(store);
+ image = store.get("Path", null);//$NON-NLS-1$
+ arguments = store.get("Arguments", null); //$NON-NLS-1$
+ localEcho = Boolean.parseBoolean(store.get("LocalEcho", Boolean.FALSE.toString())); //$NON-NLS-1$
+ if (store instanceof IPropertiesContainer) {
+ process = (Process)((IPropertiesContainer)store).getProperty("Process"); //$NON-NLS-1$
+ pty = (PTY)((IPropertiesContainer)store).getProperty("PTY"); //$NON-NLS-1$
+ }
+ }
+
+ /**
+ * Saves the process settings to the given settings store.
+ *
+ * @param store The settings store. Must not be <code>null</code>.
+ */
+ public void save(ISettingsStore store) {
+ Assert.isNotNull(store);
+ store.put("Path", image);//$NON-NLS-1$
+ store.put("Arguments", arguments); //$NON-NLS-1$
+ store.put("LocalEcho", Boolean.toString(localEcho)); //$NON-NLS-1$
+ if (store instanceof IPropertiesContainer) {
+ ((IPropertiesContainer)store).setProperty("Process", process); //$NON-NLS-1$
+ ((IPropertiesContainer)store).setProperty("PTY", pty); //$NON-NLS-1$
+ }
+ }
+}
diff --git a/target_explorer/plugins/org.eclipse.tm.te.ui.terminals/src/org/eclipse/tm/te/ui/terminals/process/ProcessSettingsPage.java b/target_explorer/plugins/org.eclipse.tm.te.ui.terminals/src/org/eclipse/tm/te/ui/terminals/process/ProcessSettingsPage.java
new file mode 100644
index 000000000..af7a4e60b
--- /dev/null
+++ b/target_explorer/plugins/org.eclipse.tm.te.ui.terminals/src/org/eclipse/tm/te/ui/terminals/process/ProcessSettingsPage.java
@@ -0,0 +1,187 @@
+/*******************************************************************************
+ * Copyright (c) 2011 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
+ *
+ * Contributors:
+ * Wind River Systems - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.tm.te.ui.terminals.process;
+
+import org.eclipse.cdt.utils.pty.PTY;
+import org.eclipse.core.runtime.Assert;
+import org.eclipse.core.runtime.IPath;
+import org.eclipse.core.runtime.Path;
+import org.eclipse.core.runtime.Platform;
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.events.SelectionAdapter;
+import org.eclipse.swt.events.SelectionEvent;
+import org.eclipse.swt.layout.GridData;
+import org.eclipse.swt.layout.GridLayout;
+import org.eclipse.swt.widgets.Button;
+import org.eclipse.swt.widgets.Composite;
+import org.eclipse.swt.widgets.FileDialog;
+import org.eclipse.swt.widgets.Label;
+import org.eclipse.swt.widgets.Shell;
+import org.eclipse.swt.widgets.Text;
+import org.eclipse.tm.internal.terminal.provisional.api.ISettingsPage;
+import org.eclipse.tm.te.ui.swt.SWTControlUtil;
+import org.eclipse.tm.te.ui.terminals.nls.Messages;
+import org.eclipse.ui.PlatformUI;
+import org.osgi.framework.Bundle;
+
+/**
+ * Process connector settings page implementation.
+ */
+@SuppressWarnings("restriction")
+public class ProcessSettingsPage implements ISettingsPage {
+ private Text processImageSelectorControl;
+ private Button processImageSelectorControlButton;
+ private Text processArgumentsControl;
+ private Button localEchoSelectorControl;
+
+ private final ProcessSettings settings;
+
+ /**
+ * Constructor.
+ *
+ * @param settings
+ */
+ public ProcessSettingsPage(ProcessSettings settings) {
+ super();
+
+ Assert.isNotNull(settings);
+ this.settings = settings;
+ }
+
+ /* (non-Javadoc)
+ * @see org.eclipse.tm.internal.terminal.provisional.api.ISettingsPage#createControl(org.eclipse.swt.widgets.Composite)
+ */
+ @Override
+ public void createControl(Composite parent) {
+ Composite composite = new Composite(parent, SWT.NONE);
+ composite.setLayout(new GridLayout());
+ composite.setLayoutData(new GridData(GridData.FILL_BOTH));
+
+ // The entry fields shall be properly aligned
+ Composite panel = new Composite(composite, SWT.NONE);
+ GridLayout layout = new GridLayout(2, false);
+ layout.marginWidth = 0; layout.marginHeight = 0;
+ panel.setLayout(layout);
+ panel.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
+
+ // Create the process image selector control
+ Label label = new Label(panel, SWT.HORIZONTAL);
+ label.setText(Messages.ProcessSettingsPage_processImagePathSelectorControl_label);
+
+ // Text field and browse button are aligned it their own panel
+ Composite innerPanel = new Composite(panel, SWT.NONE);
+ layout = new GridLayout(2, false);
+ layout.marginWidth = 0; layout.marginHeight = 0;
+ innerPanel.setLayout(layout);
+ innerPanel.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
+
+ processImageSelectorControl = new Text(innerPanel, SWT.SINGLE | SWT.BORDER);
+ processImageSelectorControl.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
+
+ processImageSelectorControlButton = new Button(innerPanel, SWT.PUSH);
+ processImageSelectorControlButton.setText(Messages.ProcessSettingsPage_processImagePathSelectorControl_button);
+ processImageSelectorControlButton.addSelectionListener(new SelectionAdapter() {
+ @Override
+ public void widgetSelected(SelectionEvent e) {
+ onBrowseButtonSelected(e);
+ }
+ });
+
+ // Create the process arguments control
+ label = new Label(panel, SWT.HORIZONTAL);
+ label.setText(Messages.ProcessSettingsPage_processArgumentsControl_label);
+
+ processArgumentsControl = new Text(panel, SWT.SINGLE | SWT.BORDER);
+ processArgumentsControl.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
+
+ // Create the local echo check box
+ localEchoSelectorControl = new Button(composite, SWT.CHECK);
+ localEchoSelectorControl.setText(Messages.ProcessSettingsPage_localEchoSelectorControl_label);
+ localEchoSelectorControl.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
+ localEchoSelectorControl.setSelection(!PTY.isSupported());
+
+ // Initialize the control content
+ loadSettings();
+ }
+
+ /**
+ * Called once the user pressed the browse button.
+ *
+ * @param e The selection event or <code>null</code>.
+ */
+ protected void onBrowseButtonSelected(SelectionEvent e) {
+ // Determine the shell
+ Shell shell = e != null ? e.widget.getDisplay().getActiveShell() : PlatformUI.getWorkbench().getDisplay().getActiveShell();
+
+ // create a standard file dialog
+ FileDialog dialog = new FileDialog(shell, SWT.OPEN);
+ dialog.setText(Messages.ProcessSettingsPage_dialogTitle);
+
+ // the dialog should open within the directory of the currently selected
+ // file. If no file has been currently selected, it should open within the
+ // last browsed directory.
+ String selectedFile = SWTControlUtil.getText(processImageSelectorControl);
+ if (selectedFile != null && selectedFile.trim().length() > 0) {
+ IPath filePath = new Path(selectedFile);
+ // If the selected file points to an directory, use the directory as is
+ IPath filterPath = filePath.toFile().isDirectory() ? filePath : filePath.removeLastSegments(1);
+ String filterFileName = filePath.toFile().isDirectory() || !filePath.toFile().exists() ? null : filePath.lastSegment();
+
+ if (!filterPath.isEmpty()) {
+ dialog.setFilterPath(filterPath.toString());
+ }
+ if (filterFileName != null) {
+ dialog.setFileName(filterFileName);
+ }
+ } else {
+ Bundle bundle = Platform.getBundle("org.eclipse.core.resources"); //$NON-NLS-1$
+ if (bundle != null && (bundle.getState() == Bundle.RESOLVED || bundle.getState() == Bundle.ACTIVE)) {
+ dialog.setFilterPath(org.eclipse.core.resources.ResourcesPlugin.getWorkspace().getRoot().getLocation().toOSString());
+ }
+ }
+
+ // Open the dialog
+ selectedFile = dialog.open();
+ if (selectedFile != null) {
+ SWTControlUtil.setText(processImageSelectorControl, selectedFile);
+ }
+ }
+
+ /* (non-Javadoc)
+ * @see org.eclipse.tm.internal.terminal.provisional.api.ISettingsPage#saveSettings()
+ */
+ @Override
+ public void saveSettings() {
+ settings.setImage(SWTControlUtil.getText(processImageSelectorControl));
+ settings.setArguments(SWTControlUtil.getText(processArgumentsControl));
+ settings.setLocalEcho(SWTControlUtil.getSelection(localEchoSelectorControl));
+ settings.setProcess(null);
+ }
+
+ /* (non-Javadoc)
+ * @see org.eclipse.tm.internal.terminal.provisional.api.ISettingsPage#loadSettings()
+ */
+ @Override
+ public void loadSettings() {
+ SWTControlUtil.setText(processImageSelectorControl, settings.getImage());
+ SWTControlUtil.setText(processArgumentsControl, settings.getArguments());
+ SWTControlUtil.setSelection(localEchoSelectorControl, settings.isLocalEcho());
+ }
+
+ /* (non-Javadoc)
+ * @see org.eclipse.tm.internal.terminal.provisional.api.ISettingsPage#validateSettings()
+ */
+ @Override
+ public boolean validateSettings() {
+ // The settings are considered valid if the selected process image can be read.
+ String selectedFile = SWTControlUtil.getText(processImageSelectorControl);
+ return selectedFile != null && !"".equals(selectedFile.trim()) && new Path(selectedFile).toFile().canRead(); //$NON-NLS-1$
+ }
+}
diff --git a/target_explorer/plugins/org.eclipse.tm.te.ui.terminals/src/org/eclipse/tm/te/ui/terminals/streams/AbstractStreamsConnector.java b/target_explorer/plugins/org.eclipse.tm.te.ui.terminals/src/org/eclipse/tm/te/ui/terminals/streams/AbstractStreamsConnector.java
new file mode 100644
index 000000000..18e14fcfc
--- /dev/null
+++ b/target_explorer/plugins/org.eclipse.tm.te.ui.terminals/src/org/eclipse/tm/te/ui/terminals/streams/AbstractStreamsConnector.java
@@ -0,0 +1,128 @@
+/*******************************************************************************
+ * Copyright (c) 2011 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
+ *
+ * Contributors:
+ * Wind River Systems - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.tm.te.ui.terminals.streams;
+
+import java.io.InputStream;
+import java.io.OutputStream;
+
+import org.eclipse.tm.internal.terminal.provisional.api.ITerminalControl;
+import org.eclipse.tm.internal.terminal.provisional.api.provider.TerminalConnectorImpl;
+import org.eclipse.ui.services.IDisposable;
+
+/**
+ * Streams connector implementation.
+ */
+@SuppressWarnings("restriction")
+public abstract class AbstractStreamsConnector extends TerminalConnectorImpl {
+ // Reference to the stdin monitor
+ private InputStreamMonitor stdInMonitor;
+ // Reference to the stdout monitor
+ private OutputStreamMonitor stdOutMonitor;
+ // Reference to the stderr monitor
+ private OutputStreamMonitor stdErrMonitor;
+
+ /**
+ * Connect the given streams. The streams connector will wrap each stream
+ * with a corresponding terminal stream monitor.
+ *
+ * @param terminalControl The terminal control. Must not be <code>null</code>.
+ * @param stdin The stdin stream or <code>null</code>.
+ * @param stdout The stdout stream or <code>null</code>.
+ * @param stderr The stderr stream or <code>null</code>.
+ */
+ protected void connectStreams(ITerminalControl terminalControl, OutputStream stdin, InputStream stdout, InputStream stderr) {
+ assert terminalControl != null;
+
+ // Create the input stream monitor
+ if (stdin != null) {
+ stdInMonitor = createStdInMonitor(terminalControl, stdin);
+ // Register the connector if it implements IDisposable and stdout/stderr are not monitored
+ if (stdout == null && stderr == null && this instanceof IDisposable) stdInMonitor.addDisposable((IDisposable)this);
+ // Start the monitoring
+ stdInMonitor.startMonitoring();
+ }
+
+ // Create the output stream monitor
+ if (stdout != null) {
+ stdOutMonitor = createStdOutMonitor(terminalControl, stdout);
+ // Register the connector if it implements IDisposable
+ if (this instanceof IDisposable) stdOutMonitor.addDisposable((IDisposable)this);
+ // Start the monitoring
+ stdOutMonitor.startMonitoring();
+ }
+
+ // Create the error stream monitor
+ if (stderr != null) {
+ stdErrMonitor = createStdErrMonitor(terminalControl, stderr);
+ // Register the connector if it implements IDisposable and stdout is not monitored
+ if (stdout == null && this instanceof IDisposable) stdErrMonitor.addDisposable((IDisposable)this);
+ // Start the monitoring
+ stdErrMonitor.startMonitoring();
+ }
+ }
+
+ /**
+ * Creates an stdin monitor for the given terminal control and stdin stream.
+ * Subclasses may override to create a specialized stream monitor.
+ *
+ * @param terminalControl The terminal control. Must not be <code>null</code>.
+ * @param stdin The stdin stream or <code>null</code>.
+ * @return input stream monitor
+ */
+ protected InputStreamMonitor createStdInMonitor(ITerminalControl terminalControl, OutputStream stdin) {
+ return new InputStreamMonitor(terminalControl, stdin);
+ }
+
+ /**
+ * Creates an stdout monitor for the given terminal control and stdout stream.
+ * Subclasses may override to create a specialized stream monitor.
+ *
+ * @param terminalControl The terminal control. Must not be <code>null</code>.
+ * @param stdout The stdout stream or <code>null</code>.
+ * @return output stream monitor
+ */
+ protected OutputStreamMonitor createStdOutMonitor(ITerminalControl terminalControl, InputStream stdout) {
+ return new OutputStreamMonitor(terminalControl, stdout);
+ }
+
+ /**
+ * Creates an stderr monitor for the given terminal control and stderr stream.
+ * Subclasses may override to create a specialized stream monitor.
+ *
+ * @param terminalControl The terminal control. Must not be <code>null</code>.
+ * @param stderr The stderr stream or <code>null</code>.
+ * @return output stream monitor
+ */
+ protected OutputStreamMonitor createStdErrMonitor(ITerminalControl terminalControl, InputStream stderr) {
+ return new OutputStreamMonitor(terminalControl, stderr);
+ }
+
+ /* (non-Javadoc)
+ * @see org.eclipse.tm.internal.terminal.provisional.api.provider.TerminalConnectorImpl#doDisconnect()
+ */
+ @Override
+ protected void doDisconnect() {
+ // Dispose the streams
+ if (stdInMonitor != null) { stdInMonitor.dispose(); stdInMonitor = null; }
+ if (stdOutMonitor != null) { stdOutMonitor.dispose(); stdOutMonitor = null; }
+ if (stdErrMonitor != null) { stdErrMonitor.dispose(); stdErrMonitor = null; }
+
+ super.doDisconnect();
+ }
+
+ /* (non-Javadoc)
+ * @see org.eclipse.tm.internal.terminal.provisional.api.provider.TerminalConnectorImpl#getTerminalToRemoteStream()
+ */
+ @Override
+ public OutputStream getTerminalToRemoteStream() {
+ return stdInMonitor;
+ }
+
+}
diff --git a/target_explorer/plugins/org.eclipse.tm.te.ui.terminals/src/org/eclipse/tm/te/ui/terminals/streams/InputStreamMonitor.java b/target_explorer/plugins/org.eclipse.tm.te.ui.terminals/src/org/eclipse/tm/te/ui/terminals/streams/InputStreamMonitor.java
new file mode 100644
index 000000000..d47c53319
--- /dev/null
+++ b/target_explorer/plugins/org.eclipse.tm.te.ui.terminals/src/org/eclipse/tm/te/ui/terminals/streams/InputStreamMonitor.java
@@ -0,0 +1,215 @@
+/*******************************************************************************
+ * Copyright (c) 2011 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
+ *
+ * Contributors:
+ * Wind River Systems - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.tm.te.ui.terminals.streams;
+
+import java.io.IOException;
+import java.io.OutputStream;
+import java.util.ArrayList;
+import java.util.LinkedList;
+import java.util.List;
+import java.util.Queue;
+
+import org.eclipse.core.runtime.Assert;
+import org.eclipse.core.runtime.IStatus;
+import org.eclipse.core.runtime.Status;
+import org.eclipse.osgi.util.NLS;
+import org.eclipse.tm.internal.terminal.provisional.api.ITerminalControl;
+import org.eclipse.tm.te.ui.terminals.activator.UIPlugin;
+import org.eclipse.tm.te.ui.terminals.nls.Messages;
+import org.eclipse.ui.services.IDisposable;
+
+/**
+ * Input stream monitor implementation.
+ * <p>
+ * <b>Note:</b> The input is coming <i>from</i> the terminal. Therefore, the input
+ * stream monitor is attached to the stdin stream of the monitored (remote) process.
+ */
+@SuppressWarnings("restriction")
+public class InputStreamMonitor extends OutputStream implements IDisposable {
+ // Reference to the parent terminal control
+ @SuppressWarnings("unused")
+ private final ITerminalControl terminalControl;
+
+ // Reference to the monitored (output) stream
+ private final OutputStream stream;
+
+ // Reference to the thread writing the stream
+ private Thread thread;
+
+ // Flag to mark the monitor disposed. When disposed,
+ // no further data is written from the monitored stream.
+ private boolean disposed;
+
+ // A list of object to dispose if this monitor is disposed
+ private final List<IDisposable> disposables = new ArrayList<IDisposable>();
+
+ // Queue to buffer the data to write to the output stream
+ private final Queue<byte[]> queue = new LinkedList<byte[]>();
+
+ /**
+ * Constructor.
+ *
+ * @param terminalControl The parent terminal control. Must not be <code>null</code>.
+ * @param stream The stream. Must not be <code>null</code>.
+ */
+ public InputStreamMonitor(ITerminalControl terminalControl, OutputStream stream) {
+ super();
+
+ Assert.isNotNull(terminalControl);
+ this.terminalControl = terminalControl;
+ Assert.isNotNull(stream);
+ this.stream = stream;
+ }
+
+ /**
+ * Adds the given disposable object to the list. The method will do nothing
+ * if either the disposable object is already part of the list or the monitor
+ * is disposed.
+ *
+ * @param disposable The disposable object. Must not be <code>null</code>.
+ */
+ public final void addDisposable(IDisposable disposable) {
+ assert disposable != null;
+ if (!disposed && !disposables.contains(disposable)) disposables.add(disposable);
+ }
+
+ /**
+ * Removes the disposable object from the list.
+ *
+ * @param disposable The disposable object. Must not be <code>null</code>.
+ */
+ public final void removeDisposable(IDisposable disposable) {
+ assert disposable != null;
+ disposables.remove(disposable);
+ }
+
+ /* (non-Javadoc)
+ * @see org.eclipse.ui.services.IDisposable#dispose()
+ */
+ @Override
+ public void dispose() {
+ // If already disposed --> return immediately
+ if (disposed) return;
+
+ // Mark the monitor disposed
+ disposed = true;
+
+ // Close the stream (ignore exceptions on close)
+ try { stream.close(); } catch (IOException e) { /* ignored on purpose */ }
+ // And interrupt the thread
+ close();
+
+ // Dispose all registered disposable objects
+ for (IDisposable disposable : disposables) disposable.dispose();
+ // Clear the list
+ disposables.clear();
+ }
+
+ /**
+ * Close the terminal input stream monitor.
+ */
+ @Override
+ public void close() {
+ // Not initialized -> return immediately
+ if (thread == null) return;
+
+ // Copy the reference
+ final Thread oldThread = thread;
+ // Unlink the monitor from the thread
+ thread = null;
+ // And interrupt the writer thread
+ oldThread.interrupt();
+ }
+
+ /**
+ * Starts the terminal output stream monitor.
+ */
+ public void startMonitoring() {
+ // If already initialized -> return immediately
+ if (thread != null) return;
+
+ // Create a new runnable which is constantly reading from the stream
+ Runnable runnable = new Runnable() {
+ @Override
+ public void run() {
+ writeStream();
+ }
+ };
+
+ // Create the writer thread
+ thread = new Thread(runnable, "Terminal Input Stream Monitor Thread"); //$NON-NLS-1$
+
+ // Configure the writer thread
+ thread.setDaemon(true);
+
+ // Start the processing
+ thread.start();
+ }
+
+
+ /**
+ * Reads from the queue and writes the read content to the stream.
+ */
+ protected void writeStream() {
+ // Read from the queue and write to the stream until disposed
+ while (thread != null && !disposed) {
+ // If the queue is empty, wait until notified
+ if (queue.isEmpty()) {
+ synchronized(queue) {
+ try { queue.wait(); } catch (InterruptedException e) { /* ignored on purpose */ }
+ }
+ }
+
+ // If the queue is not empty, take the first element
+ // and write the data to the stream
+ while (!queue.isEmpty() && !disposed) {
+ // Retrieves the queue head (is null if queue is empty (should never happen))
+ byte[] data = queue.poll();
+ if (data != null) {
+ try {
+ // Write the data to the stream
+ stream.write(data);
+ // Flush the stream immediately
+ stream.flush();
+ } catch (IOException e) {
+ // IOException received. If this is happening when already disposed -> ignore
+ if (!disposed) {
+ IStatus status = new Status(IStatus.ERROR, UIPlugin.getUniqueIdentifier(),
+ NLS.bind(Messages.InputStreamMonitor_error_writingToStream, e.getLocalizedMessage()), e);
+ UIPlugin.getDefault().getLog().log(status);
+ }
+ }
+ }
+ }
+ }
+
+ // Dispose the stream
+ dispose();
+ }
+
+ /* (non-Javadoc)
+ * @see java.io.OutputStream#write(int)
+ */
+ @Override
+ public void write(int b) throws IOException {
+ synchronized(queue) {
+ queue.add(new byte[] { (byte)b });
+ queue.notifyAll();
+ }
+ }
+
+ @Override
+ public void write(byte[] b, int off, int len) throws IOException {
+ // Make sure that the written block is not interlaced with other input.
+ synchronized(queue) {
+ super.write(b, off, len);
+ }
+ }
+}
diff --git a/target_explorer/plugins/org.eclipse.tm.te.ui.terminals/src/org/eclipse/tm/te/ui/terminals/streams/OutputStreamMonitor.java b/target_explorer/plugins/org.eclipse.tm.te.ui.terminals/src/org/eclipse/tm/te/ui/terminals/streams/OutputStreamMonitor.java
new file mode 100644
index 000000000..ea8ab62fc
--- /dev/null
+++ b/target_explorer/plugins/org.eclipse.tm.te.ui.terminals/src/org/eclipse/tm/te/ui/terminals/streams/OutputStreamMonitor.java
@@ -0,0 +1,222 @@
+/*******************************************************************************
+ * Copyright (c) 2011 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
+ *
+ * Contributors:
+ * Wind River Systems - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.tm.te.ui.terminals.streams;
+
+import java.io.BufferedInputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.util.ArrayList;
+import java.util.List;
+
+import org.eclipse.core.runtime.Assert;
+import org.eclipse.core.runtime.IStatus;
+import org.eclipse.core.runtime.Status;
+import org.eclipse.osgi.util.NLS;
+import org.eclipse.tm.internal.terminal.provisional.api.ITerminalControl;
+import org.eclipse.tm.te.ui.terminals.activator.UIPlugin;
+import org.eclipse.tm.te.ui.terminals.nls.Messages;
+import org.eclipse.ui.services.IDisposable;
+
+/**
+ * Output stream monitor implementation.
+ * <p>
+ * <b>Note:</b> The output is going <i>to</i> the terminal. Therefore, the output
+ * stream monitor is attached to the stdout and/or stderr stream of the monitored
+ * (remote) process.
+ */
+@SuppressWarnings("restriction")
+public class OutputStreamMonitor implements IDisposable {
+ // The default buffer size to use
+ private static final int BUFFER_SIZE = 8192;
+
+ // Reference to the parent terminal control
+ private final ITerminalControl terminalControl;
+
+ // Reference to the monitored (input) stream
+ private final InputStream stream;
+
+ // Reference to the thread reading the stream
+ private Thread thread;
+
+ // Flag to mark the monitor disposed. When disposed,
+ // no further data is read from the monitored stream.
+ private boolean disposed;
+
+ // A list of object to dispose if this monitor is disposed
+ private final List<IDisposable> disposables = new ArrayList<IDisposable>();
+
+ /**
+ * Constructor.
+ *
+ * @param terminalControl The parent terminal control. Must not be <code>null</code>.
+ * @param stream The stream. Must not be <code>null</code>.
+ */
+ public OutputStreamMonitor(ITerminalControl terminalControl, InputStream stream) {
+ super();
+
+ Assert.isNotNull(terminalControl);
+ this.terminalControl = terminalControl;
+ Assert.isNotNull(stream);
+ this.stream = new BufferedInputStream(stream, BUFFER_SIZE);
+ }
+
+ /**
+ * Adds the given disposable object to the list. The method will do nothing
+ * if either the disposable object is already part of the list or the monitor
+ * is disposed.
+ *
+ * @param disposable The disposable object. Must not be <code>null</code>.
+ */
+ public final void addDisposable(IDisposable disposable) {
+ assert disposable != null;
+ if (!disposed && !disposables.contains(disposable)) disposables.add(disposable);
+ }
+
+ /**
+ * Removes the disposable object from the list.
+ *
+ * @param disposable The disposable object. Must not be <code>null</code>.
+ */
+ public final void removeDisposable(IDisposable disposable) {
+ assert disposable != null;
+ disposables.remove(disposable);
+ }
+
+ /* (non-Javadoc)
+ * @see org.eclipse.ui.services.IDisposable#dispose()
+ */
+ @Override
+ public void dispose() {
+ // If already disposed --> return immediately
+ if (disposed) return;
+
+ // Mark the monitor disposed
+ disposed = true;
+
+ // Close the stream (ignore exceptions on close)
+ try { stream.close(); } catch (IOException e) { /* ignored on purpose */ }
+
+ // Dispose all registered disposable objects
+ for (IDisposable disposable : disposables) disposable.dispose();
+ // Clear the list
+ disposables.clear();
+ }
+
+ /**
+ * Starts the terminal output stream monitor.
+ */
+ protected void startMonitoring() {
+ // If already initialized -> return immediately
+ if (thread != null) return;
+
+ // Create a new runnable which is constantly reading from the stream
+ Runnable runnable = new Runnable() {
+ @Override
+ public void run() {
+ readStream();
+ }
+ };
+
+ // Create the reader thread
+ thread = new Thread(runnable, "Terminal Output Stream Monitor Thread"); //$NON-NLS-1$
+
+ // Configure the reader thread
+ thread.setDaemon(true);
+ thread.setPriority(Thread.MIN_PRIORITY);
+
+ // Start the processing
+ thread.start();
+ }
+
+ /**
+ * Returns the terminal control that this stream monitor is associated with.
+ */
+ protected ITerminalControl getTerminalControl() {
+ return terminalControl;
+ }
+
+ /**
+ * Reads from the output stream and write the read content
+ * to the terminal control output stream.
+ */
+ void readStream() {
+ // Creates the read buffer
+ byte[] readBuffer = new byte[BUFFER_SIZE];
+
+ // We need to maintain UI responsiveness but still stream the content
+ // to the terminal control fast. Put the thread to a short sleep each second.
+ long sleepMarker = System.currentTimeMillis();
+
+ // Read from the stream until EOS is reached or the
+ // monitor is marked disposed.
+ int read = 0;
+ while (read >= 0 && !disposed) {
+ try {
+ // Read from the stream
+ read = stream.read(readBuffer);
+ // If some data has been read, append to the terminal
+ // control output stream
+ if (read > 0) {
+ // Allow for post processing the read content before appending
+ byte[] processedReadBuffer = onContentReadFromStream(readBuffer, read);
+ if (processedReadBuffer != readBuffer) {
+ read = processedReadBuffer.length;
+ }
+ terminalControl.getRemoteToTerminalOutputStream().write(processedReadBuffer, 0, read);
+ }
+ } catch (IOException e) {
+ // IOException received. If this is happening when already disposed -> ignore
+ if (!disposed) {
+ IStatus status = new Status(IStatus.ERROR, UIPlugin.getUniqueIdentifier(),
+ NLS.bind(Messages.OutputStreamMonitor_error_readingFromStream, e.getLocalizedMessage()), e);
+ UIPlugin.getDefault().getLog().log(status);
+ }
+ break;
+ } catch (NullPointerException e) {
+ // killing the stream monitor while reading can cause an NPE
+ // when reading from the stream
+ if (!disposed && thread != null) {
+ IStatus status = new Status(IStatus.ERROR, UIPlugin.getUniqueIdentifier(),
+ NLS.bind(Messages.OutputStreamMonitor_error_readingFromStream, e.getLocalizedMessage()), e);
+ UIPlugin.getDefault().getLog().log(status);
+ }
+ break;
+ }
+
+ // See above -> Thread will go to sleep each second
+ if (System.currentTimeMillis() - sleepMarker > 1000) {
+ sleepMarker = System.currentTimeMillis();
+ try { Thread.sleep(1); } catch (InterruptedException e) { /* ignored on purpose */ }
+ }
+ }
+
+ // Dispose ourself
+ dispose();
+ }
+
+ /**
+ * Allow for processing of data from byte stream after it is read from
+ * client but before it is appended to the terminal. If the returned byte
+ * array is different than the one that was passed in with the byteBuffer
+ * argument, then the bytesRead value will be ignored and the full
+ * returned array will be written out.
+ * <p>
+ * The default implementation is returning the byte stream unmodified.
+ *
+ * @param byteBuffer The byte stream. Must not be <code>null</code>.
+ * @param bytesRead The number of bytes that were read into the read buffer.
+ * @return The processed byte stream.
+ *
+ */
+ protected byte[] onContentReadFromStream(byte[] byteBuffer, int bytesRead) {
+ assert byteBuffer != null;
+ return byteBuffer;
+ }
+}
diff --git a/target_explorer/plugins/org.eclipse.tm.te.ui.terminals/src/org/eclipse/tm/te/ui/terminals/streams/StreamsConnector.java b/target_explorer/plugins/org.eclipse.tm.te.ui.terminals/src/org/eclipse/tm/te/ui/terminals/streams/StreamsConnector.java
new file mode 100644
index 000000000..0bc89e64c
--- /dev/null
+++ b/target_explorer/plugins/org.eclipse.tm.te.ui.terminals/src/org/eclipse/tm/te/ui/terminals/streams/StreamsConnector.java
@@ -0,0 +1,113 @@
+/*******************************************************************************
+ * Copyright (c) 2011 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
+ *
+ * Contributors:
+ * Wind River Systems - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.tm.te.ui.terminals.streams;
+
+import org.eclipse.core.runtime.Assert;
+import org.eclipse.tm.internal.terminal.provisional.api.ISettingsStore;
+import org.eclipse.tm.internal.terminal.provisional.api.ITerminalControl;
+import org.eclipse.tm.internal.terminal.provisional.api.TerminalState;
+import org.eclipse.ui.services.IDisposable;
+
+/**
+ * Streams connector implementation.
+ */
+@SuppressWarnings("restriction")
+public class StreamsConnector extends AbstractStreamsConnector implements IDisposable {
+ // Reference to the streams settings
+ private final StreamsSettings settings;
+
+ /**
+ * Constructor.
+ */
+ public StreamsConnector() {
+ this(new StreamsSettings());
+ }
+
+ /**
+ * Constructor.
+ *
+ * @param settings The streams settings. Must not be <code>null</code>
+ */
+ public StreamsConnector(StreamsSettings settings) {
+ super();
+
+ Assert.isNotNull(settings);
+ this.settings = settings;
+ }
+
+ /* (non-Javadoc)
+ * @see org.eclipse.tm.internal.terminal.provisional.api.provider.TerminalConnectorImpl#connect(org.eclipse.tm.internal.terminal.provisional.api.ITerminalControl)
+ */
+ @Override
+ public void connect(ITerminalControl control) {
+ Assert.isNotNull(control);
+ super.connect(control);
+
+ // connect the streams
+ connectStreams(control, settings.getStdinStream(), settings.getStdoutStream(), settings.getStderrStream());
+
+ // Set the terminal control state to CONNECTED
+ control.setState(TerminalState.CONNECTED);
+ }
+
+ /* (non-Javadoc)
+ * @see org.eclipse.tm.internal.terminal.provisional.api.provider.TerminalConnectorImpl#isLocalEcho()
+ */
+ @Override
+ public boolean isLocalEcho() {
+ return settings.isLocalEcho();
+ }
+
+ /* (non-Javadoc)
+ * @see org.eclipse.ui.services.IDisposable#dispose()
+ */
+ @Override
+ public void dispose() {
+ disconnect();
+ }
+
+ /* (non-Javadoc)
+ * @see org.eclipse.tm.internal.terminal.provisional.api.provider.TerminalConnectorImpl#doDisconnect()
+ */
+ @Override
+ public void doDisconnect() {
+ // Dispose the streams
+ super.doDisconnect();
+
+ // Set the terminal control state to CLOSED.
+ fControl.setState(TerminalState.CLOSED);
+ }
+
+ // ***** Process Connector settings handling *****
+
+ /* (non-Javadoc)
+ * @see org.eclipse.tm.internal.terminal.provisional.api.provider.TerminalConnectorImpl#getSettingsSummary()
+ */
+ @Override
+ public String getSettingsSummary() {
+ return ""; //$NON-NLS-1$
+ }
+
+ /* (non-Javadoc)
+ * @see org.eclipse.tm.internal.terminal.provisional.api.provider.TerminalConnectorImpl#load(org.eclipse.tm.internal.terminal.provisional.api.ISettingsStore)
+ */
+ @Override
+ public void load(ISettingsStore store) {
+ settings.load(store);
+ }
+
+ /* (non-Javadoc)
+ * @see org.eclipse.tm.internal.terminal.provisional.api.provider.TerminalConnectorImpl#save(org.eclipse.tm.internal.terminal.provisional.api.ISettingsStore)
+ */
+ @Override
+ public void save(ISettingsStore store) {
+ settings.save(store);
+ }
+}
diff --git a/target_explorer/plugins/org.eclipse.tm.te.ui.terminals/src/org/eclipse/tm/te/ui/terminals/streams/StreamsSettings.java b/target_explorer/plugins/org.eclipse.tm.te.ui.terminals/src/org/eclipse/tm/te/ui/terminals/streams/StreamsSettings.java
new file mode 100644
index 000000000..a3ef45196
--- /dev/null
+++ b/target_explorer/plugins/org.eclipse.tm.te.ui.terminals/src/org/eclipse/tm/te/ui/terminals/streams/StreamsSettings.java
@@ -0,0 +1,135 @@
+/*******************************************************************************
+ * Copyright (c) 2011 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
+ *
+ * Contributors:
+ * Wind River Systems - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.tm.te.ui.terminals.streams;
+
+import java.io.InputStream;
+import java.io.OutputStream;
+
+import org.eclipse.core.runtime.Assert;
+import org.eclipse.tm.internal.terminal.provisional.api.ISettingsStore;
+import org.eclipse.tm.te.runtime.interfaces.properties.IPropertiesContainer;
+
+/**
+ * Streams connector settings implementation.
+ */
+@SuppressWarnings("restriction")
+public class StreamsSettings {
+ // Reference to the stdin stream
+ private OutputStream stdin;
+ // Reference to the stdout stream
+ private InputStream stdout;
+ // Reference to the stderr stream
+ private InputStream stderr;
+ // Flag to control the local echo
+ private boolean localEcho = true;
+
+ /**
+ * Sets the stdin stream instance.
+ *
+ * @param stdin The stream instance or <code>null</code>.
+ */
+ public void setStdinStream(OutputStream stdin) {
+ this.stdin = stdin;
+ }
+
+ /**
+ * Returns the stdin stream instance.
+ *
+ * @return The stream instance or <code>null</code>.
+ */
+ public OutputStream getStdinStream() {
+ return stdin;
+ }
+
+ /**
+ * Sets the stdout stream instance.
+ *
+ * @param stdout The stream instance or <code>null</code>.
+ */
+ public void setStdoutStream(InputStream stdout) {
+ this.stdout = stdout;
+ }
+
+ /**
+ * Returns the stdout stream instance.
+ *
+ * @return The stream instance or <code>null</code>.
+ */
+ public InputStream getStdoutStream() {
+ return stdout;
+ }
+
+ /**
+ * Sets the stderr stream instance.
+ *
+ * @param stderr The stream instance or <code>null</code>.
+ */
+ public void setStderrStream(InputStream stderr) {
+ this.stderr = stderr;
+ }
+
+ /**
+ * Returns the stderr stream instance.
+ *
+ * @return The stream instance or <code>null</code>.
+ */
+ public InputStream getStderrStream() {
+ return stderr;
+ }
+
+ /**
+ * Sets if the process requires a local echo from the terminal widget.
+ *
+ * @param value Specify <code>true</code> to enable the local echo, <code>false</code> otherwise.
+ */
+ public void setLocalEcho(boolean value) {
+ this.localEcho = value;
+ }
+
+ /**
+ * Returns <code>true</code> if the process requires a local echo
+ * from the terminal widget.
+ *
+ * @return <code>True</code> if local echo is enabled, <code>false</code> otherwise.
+ */
+ public boolean isLocalEcho() {
+ return localEcho;
+ }
+
+ /**
+ * Loads the streams settings from the given settings store.
+ *
+ * @param store The settings store. Must not be <code>null</code>.
+ */
+ public void load(ISettingsStore store) {
+ Assert.isNotNull(store);
+ localEcho = Boolean.parseBoolean(store.get("LocalEcho", Boolean.FALSE.toString())); //$NON-NLS-1$
+ if (store instanceof IPropertiesContainer) {
+ stdin = (OutputStream)((IPropertiesContainer)store).getProperty("stdin"); //$NON-NLS-1$
+ stdout = (InputStream)((IPropertiesContainer)store).getProperty("stdout"); //$NON-NLS-1$
+ stderr = (InputStream)((IPropertiesContainer)store).getProperty("stderr"); //$NON-NLS-1$
+ }
+ }
+
+ /**
+ * Saves the process settings to the given settings store.
+ *
+ * @param store The settings store. Must not be <code>null</code>.
+ */
+ public void save(ISettingsStore store) {
+ Assert.isNotNull(store);
+ store.put("LocalEcho", Boolean.toString(localEcho)); //$NON-NLS-1$
+ if (store instanceof IPropertiesContainer) {
+ ((IPropertiesContainer)store).setProperty("stdin", stdin); //$NON-NLS-1$
+ ((IPropertiesContainer)store).setProperty("stdout", stdout); //$NON-NLS-1$
+ ((IPropertiesContainer)store).setProperty("stderr", stderr); //$NON-NLS-1$
+ }
+ }
+}
diff --git a/target_explorer/plugins/org.eclipse.tm.te.ui.terminals/src/org/eclipse/tm/te/ui/terminals/tabs/TabDisposeListener.java b/target_explorer/plugins/org.eclipse.tm.te.ui.terminals/src/org/eclipse/tm/te/ui/terminals/tabs/TabDisposeListener.java
new file mode 100644
index 000000000..09f7783a8
--- /dev/null
+++ b/target_explorer/plugins/org.eclipse.tm.te.ui.terminals/src/org/eclipse/tm/te/ui/terminals/tabs/TabDisposeListener.java
@@ -0,0 +1,67 @@
+/*******************************************************************************
+ * Copyright (c) 2011 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
+ *
+ * Contributors:
+ * Wind River Systems - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.tm.te.ui.terminals.tabs;
+
+import org.eclipse.core.runtime.Assert;
+import org.eclipse.swt.custom.CTabItem;
+import org.eclipse.swt.events.DisposeEvent;
+import org.eclipse.swt.events.DisposeListener;
+import org.eclipse.tm.internal.terminal.control.ITerminalViewControl;
+import org.eclipse.tm.te.runtime.events.DisposedEvent;
+import org.eclipse.tm.te.runtime.events.EventManager;
+
+/**
+ * Terminals tab default dispose listener implementation.
+ */
+@SuppressWarnings("restriction")
+public class TabDisposeListener implements DisposeListener {
+ private final TabFolderManager parentTabFolderManager;
+
+ /**
+ * Constructor.
+ *
+ * @param parentTabFolderManager The parent tab folder manager. Must be not <code>null</code>
+ */
+ public TabDisposeListener(TabFolderManager parentTabFolderManager) {
+ Assert.isNotNull(parentTabFolderManager);
+ this.parentTabFolderManager = parentTabFolderManager;
+ }
+
+ /**
+ * Returns the parent terminal console tab folder manager instance.
+ *
+ * @return The parent terminal console tab folder manager instance.
+ */
+ protected final TabFolderManager getParentTabFolderManager() {
+ return parentTabFolderManager;
+ }
+
+ /* (non-Javadoc)
+ * @see org.eclipse.swt.events.DisposeListener#widgetDisposed(org.eclipse.swt.events.DisposeEvent)
+ */
+ @Override
+ public void widgetDisposed(DisposeEvent e) {
+ // If a tab item gets disposed, we have to dispose the terminal as well
+ if (e.getSource() instanceof CTabItem) {
+ // Get the terminal control (if any) from the tab item
+ Object candidate = ((CTabItem)e.getSource()).getData();
+ if (candidate instanceof ITerminalViewControl) ((ITerminalViewControl)candidate).disposeTerminal();
+
+ // If all items got removed, we have to switch back to the empty page control
+ if (parentTabFolderManager.getTabFolder() != null && parentTabFolderManager.getTabFolder().getItemCount() == 0) {
+ parentTabFolderManager.getParentView().switchToEmptyPageControl();
+ }
+ // Fire selection changed event
+ parentTabFolderManager.fireSelectionChanged();
+ // Fire the terminal console disposed event
+ EventManager.getInstance().fireEvent(new DisposedEvent(e.getSource(), ((CTabItem)e.getSource()).getData("customData"))); //$NON-NLS-1$
+ }
+ }
+}
diff --git a/target_explorer/plugins/org.eclipse.tm.te.ui.terminals/src/org/eclipse/tm/te/ui/terminals/tabs/TabFolderManager.java b/target_explorer/plugins/org.eclipse.tm.te.ui.terminals/src/org/eclipse/tm/te/ui/terminals/tabs/TabFolderManager.java
new file mode 100644
index 000000000..491548ec4
--- /dev/null
+++ b/target_explorer/plugins/org.eclipse.tm.te.ui.terminals/src/org/eclipse/tm/te/ui/terminals/tabs/TabFolderManager.java
@@ -0,0 +1,720 @@
+/*******************************************************************************
+ * Copyright (c) 2011 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
+ *
+ * Contributors:
+ * Wind River Systems - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.tm.te.ui.terminals.tabs;
+
+import java.io.UnsupportedEncodingException;
+import java.util.ArrayList;
+import java.util.EventObject;
+import java.util.Iterator;
+import java.util.List;
+
+import org.eclipse.core.runtime.Assert;
+import org.eclipse.core.runtime.PlatformObject;
+import org.eclipse.jface.resource.JFaceResources;
+import org.eclipse.jface.util.IPropertyChangeListener;
+import org.eclipse.jface.viewers.ISelection;
+import org.eclipse.jface.viewers.ISelectionChangedListener;
+import org.eclipse.jface.viewers.ISelectionProvider;
+import org.eclipse.jface.viewers.IStructuredSelection;
+import org.eclipse.jface.viewers.SelectionChangedEvent;
+import org.eclipse.jface.viewers.StructuredSelection;
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.custom.CTabFolder;
+import org.eclipse.swt.custom.CTabItem;
+import org.eclipse.swt.events.DisposeEvent;
+import org.eclipse.swt.events.DisposeListener;
+import org.eclipse.swt.events.MouseEvent;
+import org.eclipse.swt.events.MouseListener;
+import org.eclipse.swt.events.SelectionListener;
+import org.eclipse.swt.graphics.Image;
+import org.eclipse.swt.layout.FillLayout;
+import org.eclipse.swt.widgets.Composite;
+import org.eclipse.swt.widgets.Menu;
+import org.eclipse.tm.internal.terminal.control.ITerminalListener;
+import org.eclipse.tm.internal.terminal.control.ITerminalViewControl;
+import org.eclipse.tm.internal.terminal.control.TerminalViewControlFactory;
+import org.eclipse.tm.internal.terminal.provisional.api.ITerminalConnector;
+import org.eclipse.tm.internal.terminal.provisional.api.TerminalState;
+import org.eclipse.tm.te.runtime.events.EventManager;
+import org.eclipse.tm.te.ui.events.AbstractEventListener;
+import org.eclipse.tm.te.ui.swt.DisplayUtil;
+import org.eclipse.tm.te.ui.terminals.activator.UIPlugin;
+import org.eclipse.tm.te.ui.terminals.events.SelectionChangedBroadcastEvent;
+import org.eclipse.tm.te.ui.terminals.interfaces.ITerminalsView;
+import org.eclipse.tm.te.ui.terminals.interfaces.ImageConsts;
+import org.eclipse.ui.PlatformUI;
+import org.eclipse.ui.ide.IDEEncoding;
+
+/**
+ * Terminals tab folder manager.
+ */
+@SuppressWarnings("restriction")
+public class TabFolderManager extends PlatformObject implements ISelectionProvider {
+ // Reference to the parent terminal consoles view
+ private final ITerminalsView parentView;
+ // Reference to the selection listener instance
+ private final SelectionListener selectionListener;
+ // Reference to the broadcasted selection changed event listener instance
+ private final BroadcastedSelectionChangedEventListener broadcastedSelectionChangedEventListener;
+
+ /**
+ * List of selection changed listeners.
+ */
+ private final List<ISelectionChangedListener> selectionChangedListeners = new ArrayList<ISelectionChangedListener>();
+
+ /**
+ * The terminal control selection listener implementation.
+ */
+ private class TerminalControlSelectionListener implements DisposeListener, MouseListener {
+ private final ITerminalViewControl terminal;
+ private boolean selectMode;
+
+ /**
+ * Constructor.
+ *
+ * @param terminal The terminal control. Must be not <code>null</code>.
+ */
+ public TerminalControlSelectionListener(ITerminalViewControl terminal) {
+ Assert.isNotNull(terminal);
+ this.terminal = terminal;
+
+ // Register ourself as the required listener
+ terminal.getControl().addDisposeListener(this);
+ terminal.getControl().addMouseListener(this);
+ }
+
+ /**
+ * Returns the associated terminal view control.
+ *
+ * @return The terminal view control.
+ */
+ protected final ITerminalViewControl getTerminal() {
+ return terminal;
+ }
+
+ /* (non-Javadoc)
+ * @see org.eclipse.swt.events.DisposeListener#widgetDisposed(org.eclipse.swt.events.DisposeEvent)
+ */
+ @Override
+ public void widgetDisposed(DisposeEvent e) {
+ // Widget got disposed, check if it is ours
+ // If a tab item gets disposed, we have to dispose the terminal as well
+ if (e.getSource().equals(terminal.getControl())) {
+ // Remove as listener
+ getTerminal().getControl().removeDisposeListener(this);
+ getTerminal().getControl().removeMouseListener(this);
+ }
+ }
+
+ /* (non-Javadoc)
+ * @see org.eclipse.swt.events.MouseListener#mouseDown(org.eclipse.swt.events.MouseEvent)
+ */
+ @Override
+ public void mouseDown(MouseEvent e) {
+ // Left button down -> select mode starts
+ if (e.button == 1) selectMode = true;
+ }
+
+ /* (non-Javadoc)
+ * @see org.eclipse.swt.events.MouseListener#mouseUp(org.eclipse.swt.events.MouseEvent)
+ */
+ @Override
+ public void mouseUp(MouseEvent e) {
+ if (e.button == 1 && selectMode) {
+ selectMode = false;
+ // Fire a selection changed event with the terminal controls selection
+ DisplayUtil.safeAsyncExec(new Runnable() {
+ @Override
+ public void run() {
+ fireSelectionChanged(new StructuredSelection(getTerminal().getSelection()));
+ }
+ });
+ }
+ }
+
+ /* (non-Javadoc)
+ * @see org.eclipse.swt.events.MouseListener#mouseDoubleClick(org.eclipse.swt.events.MouseEvent)
+ */
+ @Override
+ public void mouseDoubleClick(MouseEvent e) {
+ }
+ }
+
+ /**
+ * The event listener to process broadcasted selection changed events
+ */
+ private class BroadcastedSelectionChangedEventListener extends AbstractEventListener {
+ private final TabFolderManager parent;
+
+ /**
+ * Constructor.
+ *
+ * @param parent The parent tab folder manager. Must not be <code>null</code>.
+ */
+ public BroadcastedSelectionChangedEventListener(TabFolderManager parent) {
+ super();
+
+ Assert.isNotNull(parent);
+ this.parent = parent;
+ }
+
+ /* (non-Javadoc)
+ * @see org.eclipse.tm.te.runtime.interfaces.events.IEventListener#eventFired(java.util.EventObject)
+ */
+ @Override
+ public void eventFired(EventObject event) {
+ if (event instanceof SelectionChangedBroadcastEvent && !event.getSource().equals(parent)) {
+ // Don't need to do anything if the parent tab folder is disposed or does not have a open tab
+ CTabFolder tabFolder = parent.getTabFolder();
+ if (tabFolder == null || tabFolder.isDisposed() || tabFolder.getItemCount() == 0) return;
+
+ // Received a broadcasted selection changed event from another tab folder manager.
+ SelectionChangedEvent selectionChangedEvent = ((SelectionChangedBroadcastEvent)event).getSelectionChangedEvent();
+ if (selectionChangedEvent != null && selectionChangedEvent.getSelection() instanceof IStructuredSelection && !selectionChangedEvent.getSelection().isEmpty()) {
+ // Extract the selection from the selection changed event
+ IStructuredSelection selection = (IStructuredSelection)selectionChangedEvent.getSelection();
+ // Determine the first element in the selection being a CTabItem
+ CTabItem item = null;
+ Iterator<?> iterator = selection.iterator();
+ while (iterator.hasNext()) {
+ Object candidate = iterator.next();
+ if (candidate instanceof CTabItem) { item = (CTabItem)candidate; break; }
+ }
+ // If we got an CTabItem from the selection, try to find a CTabItem in our own tab folder manager
+ // which is associated with the exact same data object.
+ if (item != null && item.getData("customData") != null) { //$NON-NLS-1$
+ Object data = item.getData("customData"); //$NON-NLS-1$
+
+ CTabItem[] ourItems = tabFolder.getItems();
+ for (CTabItem ourItem : ourItems) {
+ Object ourData = ourItem.getData("customData"); //$NON-NLS-1$
+ if (data.equals(ourData) && !ourItem.equals(parent.getActiveTabItem())) {
+ // Select this item and we are done
+ parent.setSelection(new StructuredSelection(ourItem));
+ break;
+ }
+ }
+ }
+ }
+ }
+ }
+
+ }
+
+ /**
+ * Constructor.
+ *
+ * @param parentView The parent terminal console view. Must be not <code>null</code>.
+ */
+ public TabFolderManager(ITerminalsView parentView) {
+ super();
+ Assert.isNotNull(parentView);
+ this.parentView = parentView;
+
+ // Attach a selection listener to the tab folder
+ selectionListener = doCreateTabFolderSelectionListener(this);
+ if (getTabFolder() != null) getTabFolder().addSelectionListener(selectionListener);
+
+
+ // Create and register the broadcasted selection changed event listener
+ broadcastedSelectionChangedEventListener = doCreateBroadcastedSelectionChangedEventListener(this);
+ if (isListeningToBroadcastedSelectionChangedEvent() && broadcastedSelectionChangedEventListener != null) {
+ EventManager.getInstance().addEventListener(broadcastedSelectionChangedEventListener, SelectionChangedBroadcastEvent.class);
+ }
+ }
+
+ /**
+ * Creates the terminal console tab folder selection listener instance.
+ *
+ * @param parent The parent terminal console tab folder manager. Must be not <code>null</code>.
+ * @return The selection listener instance.
+ */
+ protected TabFolderSelectionListener doCreateTabFolderSelectionListener(TabFolderManager parent) {
+ Assert.isNotNull(parent);
+ return new TabFolderSelectionListener(parent);
+ }
+
+ /**
+ * Returns the parent terminal consoles view.
+ *
+ * @return The terminal consoles view instance.
+ */
+ protected final ITerminalsView getParentView() {
+ return parentView;
+ }
+
+ /**
+ * Returns the tab folder associated with the parent view.
+ *
+ * @return The tab folder or <code>null</code>.
+ */
+ protected final CTabFolder getTabFolder() {
+ return (CTabFolder)getParentView().getAdapter(CTabFolder.class);
+ }
+
+ /**
+ * Returns the selection changed listeners currently registered.
+ *
+ * @return The registered selection changed listeners or an empty array.
+ */
+ protected final ISelectionChangedListener[] getSelectionChangedListeners() {
+ return selectionChangedListeners.toArray(new ISelectionChangedListener[selectionChangedListeners.size()]);
+ }
+
+ /**
+ * Dispose the tab folder manager instance.
+ */
+ public void dispose() {
+ // Dispose the selection listener
+ if (getTabFolder() != null && !getTabFolder().isDisposed()) getTabFolder().removeSelectionListener(selectionListener);
+ // Remove the broadcasted selection changed event listener from the notification manager
+ if (broadcastedSelectionChangedEventListener != null) {
+ EventManager.getInstance().removeEventListener(broadcastedSelectionChangedEventListener);
+ }
+ }
+
+ /**
+ * Creates a new tab item with the given title and connector.
+ *
+ * @param title The tab title. Must be not <code>null</code>.
+ * @param connector The terminal connector. Must be not <code>null</code>.
+ * @param data The custom terminal data node or <code>null</code>.
+ *
+ * @return The created tab item or <code>null</code> if failed.
+ */
+ @SuppressWarnings("unused")
+ public CTabItem createTabItem(String title, ITerminalConnector connector, Object data) {
+ Assert.isNotNull(title);
+ Assert.isNotNull(connector);
+
+ // The result tab item
+ CTabItem item = null;
+
+ // Get the tab folder from the parent viewer
+ CTabFolder tabFolder = getTabFolder();
+ if (tabFolder != null) {
+ // Generate a unique title string for the new tab item (must be called before creating the item itself)
+ title = makeUniqueTitle(title, tabFolder);
+ // Create the tab item
+ item = new CTabItem(tabFolder, SWT.CLOSE);
+ // Set the tab item title
+ item.setText(title);
+ // Set the tab icon
+ Image image = getTabItemImage(connector, data);
+ if (image != null) item.setImage(image);
+
+ // Setup the tab item listeners
+ setupTerminalTabListeners(item);
+
+ // Create the composite to create the terminal control within
+ Composite composite = new Composite(tabFolder, SWT.NONE);
+ composite.setLayout(new FillLayout());
+ // Associate the composite with the tab item
+ item.setControl(composite);
+
+ // Refresh the layout
+ tabFolder.getParent().layout(true);
+
+ // Create the terminal control
+ ITerminalViewControl terminal = TerminalViewControlFactory.makeControl(doCreateTerminalTabTerminalListener(item), composite, new ITerminalConnector[] { connector });
+ // Add the "selection" listener to the terminal control
+ new TerminalControlSelectionListener(terminal);
+ // Use the default Eclipse IDE encoding setting to configure the terminals encoding
+ try { terminal.setEncoding(IDEEncoding.getResourceEncoding()); } catch (UnsupportedEncodingException e) { /* ignored on purpose */ }
+ // Associated the terminal with the tab item
+ item.setData(terminal);
+ // Associated the custom data node with the tab item (if any)
+ if (data != null) item.setData("customData", data); //$NON-NLS-1$
+
+ // Overwrite the text canvas help id
+ String contextHelpId = getParentView().getContextHelpId();
+ if (contextHelpId != null) {
+ PlatformUI.getWorkbench().getHelpSystem().setHelp(terminal.getControl(), contextHelpId);
+ }
+
+ // Set the context menu
+ TabFolderMenuHandler menuHandler = (TabFolderMenuHandler)getParentView().getAdapter(TabFolderMenuHandler.class);
+ if (menuHandler != null) {
+ Menu menu = (Menu)menuHandler.getAdapter(Menu.class);
+ if (menu != null) {
+ // One weird occurrence of IllegalArgumentException: Widget has wrong parent.
+ // Inspecting the code, this seem extremely unlikely. The terminal is created
+ // from a composite parent, the composite parent from the tab folder and the menu
+ // from the tab folder. Means, at the end all should have the same menu shell, shouldn't they?
+ try {
+ terminal.getControl().setMenu(menu);
+ } catch (IllegalArgumentException e) {
+ // Log exception only if debug mode is set to 1.
+ if (UIPlugin.getTraceHandler().isSlotEnabled(1, null)) {
+ e.printStackTrace();
+ }
+ }
+ }
+ }
+
+ // Select the created item within the tab folder
+ tabFolder.setSelection(item);
+
+ // Set the connector
+ terminal.setConnector(connector);
+
+ // And connect the terminal
+ terminal.connectTerminal();
+
+ // Fire selection changed event
+ fireSelectionChanged();
+ }
+
+ // Return the create tab item finally.
+ return item;
+ }
+
+ /**
+ * Generate a unique title string based on the given proposal.
+ *
+ * @param proposal The proposal. Must be not <code>null</code>.
+ * @return The unique title string.
+ */
+ protected String makeUniqueTitle(String proposal, CTabFolder tabFolder) {
+ Assert.isNotNull(proposal);
+ Assert.isNotNull(tabFolder);
+
+ String title = proposal;
+ int index = 0;
+
+ // Loop all existing tab items and check the titles. We have to remember
+ // all found titles as modifying the proposal might in turn conflict again
+ // with the title of a tab already checked.
+ List<String> titles = new ArrayList<String>();
+ for (CTabItem item : tabFolder.getItems()) {
+ // Get the tab item title
+ titles.add(item.getText());
+ // Make the proposal unique be appending (<n>) against all known titles.
+ while (titles.contains(title)) title = proposal + " (" + index++ + ")"; //$NON-NLS-1$ //$NON-NLS-2$
+ }
+
+ return title;
+ }
+
+ /**
+ * Setup the terminal console tab item listeners.
+ *
+ * @param item The tab item. Must be not <code>null</code>.
+ */
+ protected void setupTerminalTabListeners(CTabItem item) {
+ Assert.isNotNull(item);
+
+ // Create and associate the disposal listener
+ item.addDisposeListener(doCreateTerminalTabDisposeListener(this));
+
+ // Create and register the property change listener
+ final IPropertyChangeListener propertyChangeListener = doCreateTerminalTabPropertyChangeListener(item);
+ // Register to the JFace font registry
+ JFaceResources.getFontRegistry().addListener(propertyChangeListener);
+ // Remove the listener from the JFace font registry if the tab gets disposed
+ item.addDisposeListener(new DisposeListener() {
+ @Override
+ public void widgetDisposed(DisposeEvent e) {
+ JFaceResources.getFontRegistry().removeListener(propertyChangeListener);
+ }
+ });
+ }
+
+ /**
+ * Creates a new terminal console tab terminal listener instance.
+ *
+ * @param item The tab item. Must be not <code>null</code>.
+ * @return The terminal listener instance.
+ */
+ protected ITerminalListener doCreateTerminalTabTerminalListener(CTabItem item) {
+ Assert.isNotNull(item);
+ return new TabTerminalListener(item);
+ }
+
+ /**
+ * Creates a new terminal console tab dispose listener instance.
+ *
+ * @param parent The parent terminal console tab folder manager. Must be not <code>null</code>.
+ * @return The dispose listener instance.
+ */
+ protected DisposeListener doCreateTerminalTabDisposeListener(TabFolderManager parent) {
+ Assert.isNotNull(parent);
+ return new TabDisposeListener(parent);
+ }
+
+ /**
+ * Creates a new terminal console tab property change listener instance.
+ *
+ * @param item The tab item. Must be not <code>null</code>.
+ * @return The property change listener instance.
+ */
+ protected IPropertyChangeListener doCreateTerminalTabPropertyChangeListener(CTabItem item) {
+ Assert.isNotNull(item);
+ return new TabPropertyChangeListener(item);
+ }
+
+ /**
+ * Returns the tab item image.
+ *
+ * @param connector The terminal connector. Must be not <code>null</code>.
+ * @param data The custom terminal data node or <code>null</code>.
+ *
+ * @return The tab item image or <code>null</code>.
+ */
+ protected Image getTabItemImage(ITerminalConnector connector, Object data) {
+ Assert.isNotNull(connector);
+ return UIPlugin.getImage(ImageConsts.VIEW_Terminals);
+ }
+
+ /**
+ * Lookup a tab item with the given title and the given terminal connector.
+ * <p>
+ * <b>Note:</b> The method will handle unified tab item titles itself.
+ *
+ * @param title The tab item title. Must be not <code>null</code>.
+ * @param connector The terminal connector. Must be not <code>null</code>.
+ * @param data The custom terminal data node or <code>null</code>.
+ *
+ * @return The corresponding tab item or <code>null</code>.
+ */
+ public CTabItem findTabItem(String title, ITerminalConnector connector, Object data) {
+ Assert.isNotNull(title);
+ Assert.isNotNull(connector);
+
+ // Get the tab folder
+ CTabFolder tabFolder = getTabFolder();
+ if (tabFolder == null) return null;
+
+ // Loop all existing tab items and try to find a matching title
+ for (CTabItem item : tabFolder.getItems()) {
+ // Disposed items cannot be matched
+ if (item.isDisposed()) continue;
+ // Get the title from the current tab item
+ String itemTitle = item.getText();
+ // The terminal console state might be signaled to the user via the
+ // terminal console tab title. Filter out any prefix "<.*>\s*".
+ itemTitle = itemTitle.replaceFirst("^<.*>\\s*", ""); //$NON-NLS-1$ //$NON-NLS-2$
+ if (itemTitle.startsWith(title)) {
+ // The title string matches -> double check with the terminal connector
+ ITerminalViewControl terminal = (ITerminalViewControl)item.getData();
+ ITerminalConnector connector2 = terminal.getTerminalConnector();
+ // If the connector id and name matches -> check on the settings
+ if (connector.getId().equals(connector2.getId()) && connector.getName().equals(connector2.getName())) {
+ if (!connector.isInitialized()) {
+ // an uninitialized connector does not yield a sensible summary
+ return item;
+ }
+ String summary = connector.getSettingsSummary();
+ String summary2 = connector2.getSettingsSummary();
+ // If we have matching settings -> we've found the matching item
+ if (summary.equals(summary2)) return item;
+ }
+ }
+ }
+
+ return null;
+ }
+
+ /**
+ * Make the given tab item the active tab and bring the tab to the top.
+ *
+ * @param item The tab item. Must be not <code>null</code>.
+ */
+ public void bringToTop(CTabItem item) {
+ Assert.isNotNull(item);
+
+ // Get the tab folder
+ CTabFolder tabFolder = getTabFolder();
+ if (tabFolder == null) return;
+
+ // Set the given tab item as selection to the tab folder
+ tabFolder.setSelection(item);
+ // Fire selection changed event
+ fireSelectionChanged();
+ }
+
+ /**
+ * Returns the currently active tab.
+ *
+ * @return The active tab item or <code>null</code> if none.
+ */
+ public CTabItem getActiveTabItem() {
+ // Get the tab folder
+ CTabFolder tabFolder = getTabFolder();
+ if (tabFolder == null) return null;
+
+ return tabFolder.getSelection();
+ }
+
+ /**
+ * Remove all terminated tab items.
+ */
+ public void removeTerminatedItems() {
+ // Get the tab folder
+ CTabFolder tabFolder = getTabFolder();
+ if (tabFolder == null) return;
+
+ // Loop the items and check for terminated status
+ for (CTabItem item: tabFolder.getItems()) {
+ // Disposed items cannot be matched
+ if (item.isDisposed()) continue;
+ // Check if the item is terminated
+ if (isTerminatedTabItem(item)) {
+ // item is terminated -> dispose
+ item.dispose();
+ }
+ }
+ }
+
+ /**
+ * Checks if the given tab item represents a terminated console. Subclasses may
+ * overwrite this method to extend the definition of terminated.
+ *
+ * @param item The tab item or <code>null</code>.
+ * @return <code>True</code> if the tab item represents a terminated console, <code>false</code> otherwise.
+ */
+ protected boolean isTerminatedTabItem(CTabItem item) {
+ // Null items or disposed items cannot be matched
+ if (item == null || item.isDisposed()) return false;
+
+ // First, match the item title. If it contains "<terminated>", the item can be removed
+ String itemTitle = item.getText();
+ if (itemTitle != null && itemTitle.contains("<terminated>")) { //$NON-NLS-1$
+ return true;
+ }
+ // Second, check if the associated terminal control is closed
+ // The title string matches -> double check with the terminal connector
+ ITerminalViewControl terminal = (ITerminalViewControl)item.getData();
+ if (terminal != null && terminal.getState() == TerminalState.CLOSED) {
+ return true;
+ }
+
+ return false;
+ }
+
+ /* (non-Javadoc)
+ * @see org.eclipse.jface.viewers.ISelectionProvider#addSelectionChangedListener(org.eclipse.jface.viewers.ISelectionChangedListener)
+ */
+ @Override
+ public void addSelectionChangedListener(ISelectionChangedListener listener) {
+ if (listener != null && !selectionChangedListeners.contains(listener)) selectionChangedListeners.add(listener);
+ }
+
+ /* (non-Javadoc)
+ * @see org.eclipse.jface.viewers.ISelectionProvider#removeSelectionChangedListener(org.eclipse.jface.viewers.ISelectionChangedListener)
+ */
+ @Override
+ public void removeSelectionChangedListener(ISelectionChangedListener listener) {
+ if (listener != null) selectionChangedListeners.remove(listener);
+ }
+
+ /* (non-Javadoc)
+ * @see org.eclipse.jface.viewers.ISelectionProvider#getSelection()
+ */
+ @Override
+ public ISelection getSelection() {
+ CTabItem activeTabItem = getActiveTabItem();
+ return activeTabItem != null ? new StructuredSelection(activeTabItem) : new StructuredSelection();
+ }
+
+ /* (non-Javadoc)
+ * @see org.eclipse.jface.viewers.ISelectionProvider#setSelection(org.eclipse.jface.viewers.ISelection)
+ */
+ @Override
+ public void setSelection(ISelection selection) {
+ if (selection instanceof IStructuredSelection && !selection.isEmpty()) {
+ // The first selection element which is a CTabItem will become the active item
+ Iterator<?> iterator = ((IStructuredSelection)selection).iterator();
+ while (iterator.hasNext()) {
+ Object candidate = iterator.next();
+ if (candidate instanceof CTabItem) { bringToTop((CTabItem)candidate); return; }
+ }
+ }
+ // fire a changed event in any case
+ fireSelectionChanged(selection);
+ }
+
+ /**
+ * Fire the selection changed event to the registered listeners.
+ */
+ protected void fireSelectionChanged() {
+ fireSelectionChanged(getSelection());
+ }
+
+ /**
+ * Fire the selection changed event to the registered listeners.
+ */
+ protected final void fireSelectionChanged(ISelection selection) {
+ // Create the selection changed event
+ SelectionChangedEvent event = new SelectionChangedEvent(TabFolderManager.this, selection);
+
+ // First, invoke the registered listeners and let them do their job
+ for (ISelectionChangedListener listener : selectionChangedListeners) {
+ listener.selectionChanged(event);
+ }
+
+ // Second, broadcast the event if desired
+ if (isBroadcastSelectionChangedEvent()) onBroadcastSelectionChangedEvent(event);
+ }
+
+ /**
+ * Controls if or if not a selection changed event, processed by this tab
+ * folder manager shall be broadcasted to via the global Workbench notification
+ * mechanism.
+ *
+ * @return <code>True</code> to broadcast the selection changed event, <code>false</code> otherwise.
+ */
+ protected boolean isBroadcastSelectionChangedEvent() {
+ return false;
+ }
+
+ /**
+ * Broadcasts the given selection changed event via the global Workbench notification mechanism.
+ *
+ * @param selectionChangedEvent The selection changed event or <code>null</code>.
+ */
+ protected void onBroadcastSelectionChangedEvent(SelectionChangedEvent selectionChangedEvent) {
+ SelectionChangedBroadcastEvent event = doCreateSelectionChangedBroadcastEvent(this, selectionChangedEvent);
+ if (event != null) EventManager.getInstance().fireEvent(event);
+ }
+
+ /**
+ * Creates the selection changed broadcast event.
+ *
+ * @param source The event source. Must not be <code>null</code>.
+ * @param selectionChangedEvent The selection changed event or <code>null</code>.
+ *
+ * @return The selection changed broadcast event or <code>null</code>.
+ */
+ protected SelectionChangedBroadcastEvent doCreateSelectionChangedBroadcastEvent(TabFolderManager source, SelectionChangedEvent selectionChangedEvent) {
+ return new SelectionChangedBroadcastEvent(source, selectionChangedEvent);
+ }
+
+ /**
+ * Returns if or if not this tab folder manager is listening to broadcasted selection
+ * changed events. Broadcasted events by the same tab folder manager are ignored independent
+ * of the methods return value.
+ *
+ * @return <code>True</code> to listen to broadcasted selection changed events, <code>false</code> to not listen.
+ */
+ protected boolean isListeningToBroadcastedSelectionChangedEvent() {
+ return false;
+ }
+
+ /**
+ * Creates a new broadcasted selection changed event listener instance.
+ *
+ * @param parent The parent tab folder manager. Must not be <code>null</code>.
+ * @return The event listener instance or <code>null</code>.
+ */
+ protected BroadcastedSelectionChangedEventListener doCreateBroadcastedSelectionChangedEventListener(TabFolderManager parent) {
+ return new BroadcastedSelectionChangedEventListener(parent);
+ }
+}
diff --git a/target_explorer/plugins/org.eclipse.tm.te.ui.terminals/src/org/eclipse/tm/te/ui/terminals/tabs/TabFolderMenuHandler.java b/target_explorer/plugins/org.eclipse.tm.te.ui.terminals/src/org/eclipse/tm/te/ui/terminals/tabs/TabFolderMenuHandler.java
new file mode 100644
index 000000000..91d6fb19a
--- /dev/null
+++ b/target_explorer/plugins/org.eclipse.tm.te.ui.terminals/src/org/eclipse/tm/te/ui/terminals/tabs/TabFolderMenuHandler.java
@@ -0,0 +1,297 @@
+/*******************************************************************************
+ * Copyright (c) 2011 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
+ *
+ * Contributors:
+ * Wind River Systems - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.tm.te.ui.terminals.tabs;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import org.eclipse.core.runtime.Assert;
+import org.eclipse.core.runtime.PlatformObject;
+import org.eclipse.jface.action.IMenuListener2;
+import org.eclipse.jface.action.IMenuManager;
+import org.eclipse.jface.action.MenuManager;
+import org.eclipse.jface.action.Separator;
+import org.eclipse.swt.custom.CTabFolder;
+import org.eclipse.swt.custom.CTabItem;
+import org.eclipse.swt.widgets.Menu;
+import org.eclipse.tm.internal.terminal.control.ITerminalViewControl;
+import org.eclipse.tm.internal.terminal.control.actions.AbstractTerminalAction;
+import org.eclipse.tm.internal.terminal.control.actions.TerminalActionClearAll;
+import org.eclipse.tm.internal.terminal.control.actions.TerminalActionCopy;
+import org.eclipse.tm.internal.terminal.control.actions.TerminalActionPaste;
+import org.eclipse.tm.internal.terminal.control.actions.TerminalActionSelectAll;
+import org.eclipse.tm.te.ui.terminals.actions.TabScrollLockAction;
+import org.eclipse.tm.te.ui.terminals.interfaces.ITerminalsView;
+import org.eclipse.ui.IWorkbenchActionConstants;
+
+/**
+ * Terminals tab folder menu handler.
+ */
+@SuppressWarnings("restriction")
+public class TabFolderMenuHandler extends PlatformObject {
+ // Reference to the parent terminal console view
+ private final ITerminalsView parentView;
+ // Reference to the tab folder context menu manager
+ private MenuManager contextMenuManager;
+ // Reference to the tab folder context menu
+ private Menu contextMenu;
+ // The list of actions available within the context menu
+ private final List<AbstractTerminalAction> contextMenuActions = new ArrayList<AbstractTerminalAction>();
+
+ /**
+ * Default menu listener implementation.
+ */
+ protected class MenuListener implements IMenuListener2 {
+
+ /* (non-Javadoc)
+ * @see org.eclipse.jface.action.IMenuListener2#menuAboutToHide(org.eclipse.jface.action.IMenuManager)
+ */
+ @Override
+ public void menuAboutToHide(IMenuManager manager) {
+ // CQ:WIND00192293 and CQ:WIND194204 - don't update actions on menuAboutToHide
+ // See also http://bugs.eclipse.org/296212
+ // updateMenuItems(false);
+ }
+
+ /* (non-Javadoc)
+ * @see org.eclipse.jface.action.IMenuListener#menuAboutToShow(org.eclipse.jface.action.IMenuManager)
+ */
+ @Override
+ public void menuAboutToShow(IMenuManager manager) {
+ updateMenuItems(true);
+ }
+
+ }
+
+ /**
+ * Constructor.
+ *
+ * @param parentView The parent terminal console view. Must not be <code>null</code>.
+ */
+ public TabFolderMenuHandler(ITerminalsView parentView) {
+ super();
+ Assert.isNotNull(parentView);
+ this.parentView = parentView;
+ }
+
+ /**
+ * Returns the parent terminal console view.
+ *
+ * @return The parent terminal console view instance.
+ */
+ protected final ITerminalsView getParentView() {
+ return parentView;
+ }
+
+ /**
+ * Returns the tab folder associated with the parent view.
+ *
+ * @return The tab folder or <code>null</code>.
+ */
+ protected final CTabFolder getTabFolder() {
+ return (CTabFolder)getParentView().getAdapter(CTabFolder.class);
+ }
+
+ /**
+ * Dispose the tab folder menu handler instance.
+ */
+ public void dispose() {
+ // Dispose the context menu
+ if (contextMenu != null) { contextMenu.dispose(); contextMenu = null; }
+ // Dispose the context menu manager
+ if (contextMenuManager != null) { contextMenuManager.dispose(); contextMenuManager = null; }
+ // Clear all actions
+ contextMenuActions.clear();
+ }
+
+ /**
+ * Setup the context menu for the tab folder. The method will return
+ * immediately if the menu handler had been initialized before.
+ *
+ * @param tabFolder The tab folder control. Must not be <code>null</code>.
+ */
+ public void initialize() {
+ // Return immediately if the menu manager and menu got initialized already
+ if (contextMenuManager != null && contextMenu != null) {
+ return;
+ }
+
+ // Get the tab folder
+ CTabFolder tabFolder = getTabFolder();
+ if (tabFolder == null) {
+ return;
+ }
+
+ // Create the menu manager if not done before
+ contextMenuManager = new MenuManager("#PopupMenu"); //$NON-NLS-1$
+ // Create and associated the menu listener
+ contextMenuManager.addMenuListener(new MenuListener());
+ // Create the context menu
+ contextMenu = contextMenuManager.createContextMenu(tabFolder);
+
+ // Create the context menu action instances
+ doCreateContextMenuActions();
+
+ // Fill the context menu
+ doFillContextMenu(contextMenuManager);
+
+ // Register to the view site to open the menu for contributions
+ getParentView().getSite().registerContextMenu(contextMenuManager, getParentView().getSite().getSelectionProvider());
+ }
+
+ /**
+ * Adds the given action to the context menu actions list.
+ *
+ * @param action The action instance. Must be not <code>null</code>.
+ */
+ protected final void add(AbstractTerminalAction action) {
+ Assert.isNotNull(action);
+ contextMenuActions.add(action);
+ }
+
+ /**
+ * Create the context menu actions.
+ */
+ protected void doCreateContextMenuActions() {
+ // Create and add the copy action
+ add(new TerminalActionCopy() {
+ /* (non-Javadoc)
+ * @see org.eclipse.tm.internal.terminal.control.actions.AbstractTerminalAction#getTarget()
+ */
+ @Override
+ protected ITerminalViewControl getTarget() {
+ return getActiveTerminalViewControl();
+ }
+ });
+
+ // Create and add the paste action
+ add(new TerminalActionPaste() {
+ /* (non-Javadoc)
+ * @see org.eclipse.tm.internal.terminal.control.actions.AbstractTerminalAction#getTarget()
+ */
+ @Override
+ protected ITerminalViewControl getTarget() {
+ return getActiveTerminalViewControl();
+ }
+ });
+
+ // Create and add the clear all action
+ add(new TerminalActionClearAll() {
+ /* (non-Javadoc)
+ * @see org.eclipse.tm.internal.terminal.control.actions.AbstractTerminalAction#getTarget()
+ */
+ @Override
+ protected ITerminalViewControl getTarget() {
+ return getActiveTerminalViewControl();
+ }
+ });
+
+ // Create and add the select all action
+ add(new TerminalActionSelectAll() {
+ /* (non-Javadoc)
+ * @see org.eclipse.tm.internal.terminal.control.actions.AbstractTerminalAction#getTarget()
+ */
+ @Override
+ protected ITerminalViewControl getTarget() {
+ return getActiveTerminalViewControl();
+ }
+ });
+
+ // Create and add the scroll lock action
+ add (new TabScrollLockAction() {
+ /* (non-Javadoc)
+ * @see org.eclipse.tm.internal.terminal.control.actions.AbstractTerminalAction#getTarget()
+ */
+ @Override
+ protected ITerminalViewControl getTarget() {
+ return getActiveTerminalViewControl();
+ }
+ });
+ }
+
+ /**
+ * Returns the currently active terminal control.
+ *
+ * @return The currently active terminal control or <code>null</code>.
+ */
+ protected ITerminalViewControl getActiveTerminalViewControl() {
+ ITerminalViewControl terminal = null;
+
+ // Get the active tab item from the tab folder manager
+ TabFolderManager manager = (TabFolderManager)getParentView().getAdapter(TabFolderManager.class);
+ if (manager != null) {
+ // If we have the active tab item, we can get the active terminal control
+ CTabItem activeTabItem = manager.getActiveTabItem();
+ if (activeTabItem != null) {
+ terminal = (ITerminalViewControl)activeTabItem.getData();
+ }
+ }
+
+ return terminal;
+ }
+
+ /**
+ * Fill in the context menu content within the given manager.
+ *
+ * @param manager The menu manager. Must not be <code>null</code>.
+ */
+ protected void doFillContextMenu(MenuManager manager) {
+ assert manager != null;
+
+ // Loop all actions and add them to the menu manager
+ for (AbstractTerminalAction action : contextMenuActions) {
+ manager.add(action);
+ // Add a separator after the paste action
+ if (action instanceof TerminalActionPaste) {
+ manager.add(new Separator());
+ }
+ // Add a separator after the select all action
+ if (action instanceof TerminalActionSelectAll) {
+ manager.add(new Separator());
+ }
+ }
+
+ // Menu contributions will end up here
+ manager.add(new Separator());
+ manager.add(new Separator(IWorkbenchActionConstants.MB_ADDITIONS));
+ }
+
+ /**
+ * Update the context menu items on showing or hiding the context menu.
+ *
+ * @param aboutToShow <code>True</code> if the menu is about to show, <code>false</code> otherwise.
+ */
+ protected void updateMenuItems(boolean aboutToShow) {
+ // Loop all actions and update the status
+ for (AbstractTerminalAction action : contextMenuActions) {
+ action.updateAction(aboutToShow);
+ }
+ }
+
+ /* (non-Javadoc)
+ * @see org.eclipse.ui.part.WorkbenchPart#getAdapter(java.lang.Class)
+ */
+ @Override
+ public Object getAdapter(Class adapter) {
+ if (MenuManager.class.isAssignableFrom(adapter)) {
+ return contextMenuManager;
+ } else if (Menu.class.isAssignableFrom(adapter)) {
+ return contextMenu;
+ }
+
+ // Try the parent view
+ Object adapted = getParentView().getAdapter(adapter);
+ if (adapted != null) {
+ return adapted;
+ }
+
+ return super.getAdapter(adapter);
+ }
+}
diff --git a/target_explorer/plugins/org.eclipse.tm.te.ui.terminals/src/org/eclipse/tm/te/ui/terminals/tabs/TabFolderSelectionListener.java b/target_explorer/plugins/org.eclipse.tm.te.ui.terminals/src/org/eclipse/tm/te/ui/terminals/tabs/TabFolderSelectionListener.java
new file mode 100644
index 000000000..de25ec3ea
--- /dev/null
+++ b/target_explorer/plugins/org.eclipse.tm.te.ui.terminals/src/org/eclipse/tm/te/ui/terminals/tabs/TabFolderSelectionListener.java
@@ -0,0 +1,55 @@
+/*******************************************************************************
+ * Copyright (c) 2011 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
+ *
+ * Contributors:
+ * Wind River Systems - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.tm.te.ui.terminals.tabs;
+
+import org.eclipse.core.runtime.Assert;
+import org.eclipse.swt.events.SelectionEvent;
+import org.eclipse.swt.events.SelectionListener;
+
+/**
+ * Terminals tab folder default selection listener implementation.
+ */
+public class TabFolderSelectionListener implements SelectionListener {
+ private final TabFolderManager parentTabFolderManager;
+
+ /**
+ * Constructor.
+ *
+ * @param parentTabFolderManager The parent tab folder manager. Must be not <code>null</code>
+ */
+ public TabFolderSelectionListener(TabFolderManager parentTabFolderManager) {
+ Assert.isNotNull(parentTabFolderManager);
+ this.parentTabFolderManager = parentTabFolderManager;
+ }
+
+ /**
+ * Returns the parent terminal console tab folder manager instance.
+ *
+ * @return The parent terminal console tab folder manager instance.
+ */
+ protected final TabFolderManager getParentTabFolderManager() {
+ return parentTabFolderManager;
+ }
+
+ /* (non-Javadoc)
+ * @see org.eclipse.swt.events.SelectionListener#widgetDefaultSelected(org.eclipse.swt.events.SelectionEvent)
+ */
+ @Override
+ public void widgetDefaultSelected(SelectionEvent e) {
+ }
+
+ /* (non-Javadoc)
+ * @see org.eclipse.swt.events.SelectionListener#widgetSelected(org.eclipse.swt.events.SelectionEvent)
+ */
+ @Override
+ public void widgetSelected(SelectionEvent e) {
+ parentTabFolderManager.fireSelectionChanged();
+ }
+}
diff --git a/target_explorer/plugins/org.eclipse.tm.te.ui.terminals/src/org/eclipse/tm/te/ui/terminals/tabs/TabFolderToolbarHandler.java b/target_explorer/plugins/org.eclipse.tm.te.ui.terminals/src/org/eclipse/tm/te/ui/terminals/tabs/TabFolderToolbarHandler.java
new file mode 100644
index 000000000..4215771c9
--- /dev/null
+++ b/target_explorer/plugins/org.eclipse.tm.te.ui.terminals/src/org/eclipse/tm/te/ui/terminals/tabs/TabFolderToolbarHandler.java
@@ -0,0 +1,304 @@
+/*******************************************************************************
+ * Copyright (c) 2011 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
+ *
+ * Contributors:
+ * Wind River Systems - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.tm.te.ui.terminals.tabs;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import org.eclipse.core.runtime.Assert;
+import org.eclipse.core.runtime.PlatformObject;
+import org.eclipse.jface.action.IToolBarManager;
+import org.eclipse.jface.action.Separator;
+import org.eclipse.jface.viewers.ISelectionChangedListener;
+import org.eclipse.jface.viewers.SelectionChangedEvent;
+import org.eclipse.jface.viewers.StructuredSelection;
+import org.eclipse.swt.custom.CTabFolder;
+import org.eclipse.swt.custom.CTabItem;
+import org.eclipse.tm.internal.terminal.control.ITerminalViewControl;
+import org.eclipse.tm.internal.terminal.control.actions.AbstractTerminalAction;
+import org.eclipse.tm.internal.terminal.control.actions.TerminalActionClearAll;
+import org.eclipse.tm.internal.terminal.control.actions.TerminalActionCopy;
+import org.eclipse.tm.internal.terminal.control.actions.TerminalActionPaste;
+import org.eclipse.tm.te.ui.terminals.actions.AbstractAction;
+import org.eclipse.tm.te.ui.terminals.actions.TabScrollLockAction;
+import org.eclipse.tm.te.ui.terminals.interfaces.ITerminalsView;
+import org.eclipse.ui.IActionBars;
+import org.eclipse.ui.IWorkbenchActionConstants;
+
+
+/**
+ * Terminals tab folder toolbar handler.
+ */
+@SuppressWarnings("restriction")
+public class TabFolderToolbarHandler extends PlatformObject {
+ // Reference to the parent terminal console view
+ private final ITerminalsView parentView;
+ // Reference to the toolbar manager
+ private IToolBarManager toolbarManager;
+ // Reference to the selection listener
+ private ToolbarSelectionChangedListener selectionChangedListener;
+ // The list of actions available within the toolbar
+ private final List<AbstractTerminalAction> toolbarActions = new ArrayList<AbstractTerminalAction>();
+
+ /**
+ * Default selection listener implementation.
+ */
+ protected class ToolbarSelectionChangedListener implements ISelectionChangedListener {
+
+ /* (non-Javadoc)
+ * @see org.eclipse.jface.viewers.ISelectionChangedListener#selectionChanged(org.eclipse.jface.viewers.SelectionChangedEvent)
+ */
+ @Override
+ public void selectionChanged(SelectionChangedEvent event) {
+ boolean enable = event != null;
+
+ // The VlmConsoleTabFolderManager is listening to the selection changes of the
+ // TabFolder and fires selection changed events.
+ if (enable && event.getSource() instanceof TabFolderManager) {
+ enable = event.getSelection() instanceof StructuredSelection
+ && !event.getSelection().isEmpty()
+ && (((StructuredSelection)event.getSelection()).getFirstElement() instanceof CTabItem
+ || ((StructuredSelection)event.getSelection()).getFirstElement() instanceof String);
+ }
+
+ updateToolbarItems(enable);
+ }
+ }
+
+ /**
+ * Constructor.
+ *
+ * @param parentView The parent terminal console view. Must not be <code>null</code>.
+ */
+ public TabFolderToolbarHandler(ITerminalsView parentView) {
+ super();
+ Assert.isNotNull(parentView);
+ this.parentView = parentView;
+ }
+
+ /**
+ * Returns the parent terminal console view.
+ *
+ * @return The terminal console view instance.
+ */
+ protected final ITerminalsView getParentView() {
+ return parentView;
+ }
+
+ /**
+ * Returns the tab folder associated with the parent view.
+ *
+ * @return The tab folder or <code>null</code>.
+ */
+ protected final CTabFolder getTabFolder() {
+ return (CTabFolder)getParentView().getAdapter(CTabFolder.class);
+ }
+
+ /**
+ * Returns the currently active terminal control.
+ *
+ * @return The currently active terminal control or <code>null</code>.
+ */
+ public ITerminalViewControl getActiveTerminalViewControl() {
+ ITerminalViewControl terminal = null;
+
+ // Get the active tab item from the tab folder manager
+ TabFolderManager manager = (TabFolderManager)getParentView().getAdapter(TabFolderManager.class);
+ if (manager != null) {
+ // If we have the active tab item, we can get the active terminal control
+ CTabItem activeTabItem = manager.getActiveTabItem();
+ if (activeTabItem != null && !activeTabItem.isDisposed()) {
+ terminal = (ITerminalViewControl)activeTabItem.getData();
+ }
+ }
+
+ return terminal;
+ }
+
+ /**
+ * Dispose the tab folder menu handler instance.
+ */
+ public void dispose() {
+ // Dispose the selection changed listener
+ if (selectionChangedListener != null) {
+ getParentView().getViewSite().getSelectionProvider().removeSelectionChangedListener(selectionChangedListener);
+ selectionChangedListener = null;
+ }
+
+ // Clear all actions
+ toolbarActions.clear();
+ }
+
+ /**
+ * Setup the context menu for the tab folder. The method will return
+ * immediately if the toolbar handler had been initialized before.
+ *
+ * @param tabFolder The tab folder control. Must not be <code>null</code>.
+ */
+ public void initialize() {
+ // Return immediately if the toolbar manager got initialized already
+ if (toolbarManager != null) {
+ return;
+ }
+
+ // Register ourself as selection listener to the tab folder
+ selectionChangedListener = doCreateSelectionChangedListener();
+ assert selectionChangedListener != null;
+ getParentView().getViewSite().getSelectionProvider().addSelectionChangedListener(selectionChangedListener);
+
+ // Get the parent view action bars
+ IActionBars bars = getParentView().getViewSite().getActionBars();
+
+ // From the action bars, get the toolbar manager
+ toolbarManager = bars.getToolBarManager();
+
+ // Create the toolbar action instances
+ doCreateToolbarActions();
+
+ // Fill the toolbar
+ doFillToolbar(toolbarManager);
+
+ // Update actions
+ updateToolbarItems(false);
+ }
+
+ /**
+ * Creates a new selection changed listener instance.
+ *
+ * @return The new selection changed listener instance.
+ */
+ protected ToolbarSelectionChangedListener doCreateSelectionChangedListener() {
+ return new ToolbarSelectionChangedListener();
+ }
+
+ /**
+ * Adds the given action to the toolbar actions list.
+ *
+ * @param action The action instance. Must be not <code>null</code>.
+ */
+ protected final void add(AbstractTerminalAction action) {
+ Assert.isNotNull(action);
+ toolbarActions.add(action);
+ }
+
+ /**
+ * Create the toolbar actions.
+ */
+ protected void doCreateToolbarActions() {
+ // Create and add the paste action
+ add(new TerminalActionPaste() {
+ /* (non-Javadoc)
+ * @see org.eclipse.tm.internal.terminal.control.actions.AbstractTerminalAction#getTarget()
+ */
+ @Override
+ protected ITerminalViewControl getTarget() {
+ return getActiveTerminalViewControl();
+ }
+ });
+
+ // Create and add the copy action
+ add(new TerminalActionCopy() {
+ /* (non-Javadoc)
+ * @see org.eclipse.tm.internal.terminal.control.actions.AbstractTerminalAction#getTarget()
+ */
+ @Override
+ protected ITerminalViewControl getTarget() {
+ return getActiveTerminalViewControl();
+ }
+ });
+
+ // Create and add the scroll lock action
+ add (new TabScrollLockAction() {
+ /* (non-Javadoc)
+ * @see org.eclipse.tm.internal.terminal.control.actions.AbstractTerminalAction#getTarget()
+ */
+ @Override
+ protected ITerminalViewControl getTarget() {
+ return getActiveTerminalViewControl();
+ }
+ });
+
+ // Create and add the clear all action
+ add(new TerminalActionClearAll() {
+ /* (non-Javadoc)
+ * @see org.eclipse.tm.internal.terminal.control.actions.AbstractTerminalAction#getTarget()
+ */
+ @Override
+ protected ITerminalViewControl getTarget() {
+ return getActiveTerminalViewControl();
+ }
+ });
+ }
+
+ /**
+ * Fill in the context menu content within the given manager.
+ *
+ * @param manager The menu manager. Must not be <code>null</code>.
+ */
+ protected void doFillToolbar(IToolBarManager manager) {
+ assert manager != null;
+
+ // Note: For the toolbar, the actions are added from left to right!
+ // So we start with the additions marker here which is the most
+ // left contribution item.
+ manager.add(new Separator(IWorkbenchActionConstants.MB_ADDITIONS));
+ manager.add(new Separator("anchor")); //$NON-NLS-1$
+
+ // Loop all actions and add them to the menu manager
+ for (AbstractTerminalAction action : toolbarActions) {
+ // Add a separator before the clear all action or if the action is a separator
+ if (action instanceof TabScrollLockAction
+ || (action instanceof AbstractAction && ((AbstractAction)action).isSeparator())) {
+ manager.insertAfter("anchor", new Separator()); //$NON-NLS-1$
+ }
+ // Add the action itself
+ manager.insertAfter("anchor", action); //$NON-NLS-1$
+ }
+ }
+
+ /**
+ * Update the toolbar items.
+ *
+ * @param enabled <code>True</code> if the items shall be enabled, <code>false</code> otherwise.
+ */
+ protected void updateToolbarItems(boolean enabled) {
+ // Determine the currently active terminal control
+ ITerminalViewControl control = getActiveTerminalViewControl();
+ // Loop all actions and update the status
+ for (AbstractTerminalAction action : toolbarActions) {
+ // If the terminal control is not available, the updateAction
+ // method of certain actions enable the action (bugzilla #260372).
+ // Workaround by forcing the action to get disabled with setEnabled.
+ if (control == null) {
+ action.setEnabled(false);
+ }
+ else {
+ action.updateAction(enabled);
+ }
+ }
+ }
+
+ /* (non-Javadoc)
+ * @see org.eclipse.ui.part.WorkbenchPart#getAdapter(java.lang.Class)
+ */
+ @Override
+ public Object getAdapter(Class adapter) {
+ if (IToolBarManager.class.isAssignableFrom(adapter)) {
+ return toolbarManager;
+ }
+ // Try the parent view
+ Object adapted = getParentView().getAdapter(adapter);
+ if (adapted != null) {
+ return adapted;
+ }
+
+ return super.getAdapter(adapter);
+ }
+}
diff --git a/target_explorer/plugins/org.eclipse.tm.te.ui.terminals/src/org/eclipse/tm/te/ui/terminals/tabs/TabPropertyChangeListener.java b/target_explorer/plugins/org.eclipse.tm.te.ui.terminals/src/org/eclipse/tm/te/ui/terminals/tabs/TabPropertyChangeListener.java
new file mode 100644
index 000000000..b84b8ee83
--- /dev/null
+++ b/target_explorer/plugins/org.eclipse.tm.te.ui.terminals/src/org/eclipse/tm/te/ui/terminals/tabs/TabPropertyChangeListener.java
@@ -0,0 +1,84 @@
+/*******************************************************************************
+ * Copyright (c) 2011 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
+ *
+ * Contributors:
+ * Wind River Systems - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.tm.te.ui.terminals.tabs;
+
+import org.eclipse.core.runtime.Assert;
+import org.eclipse.jface.resource.JFaceResources;
+import org.eclipse.jface.util.IPropertyChangeListener;
+import org.eclipse.jface.util.PropertyChangeEvent;
+import org.eclipse.swt.custom.CTabItem;
+import org.eclipse.swt.graphics.Font;
+import org.eclipse.tm.internal.terminal.control.ITerminalViewControl;
+import org.eclipse.tm.internal.terminal.view.TerminalView;
+
+/**
+ * Terminals tab default property change listener implementation.
+ */
+@SuppressWarnings("restriction")
+public class TabPropertyChangeListener implements IPropertyChangeListener {
+ /**
+ * Default terminal font property key.
+ *
+ * @see TerminalView#FONT_DEFINITION
+ */
+ public static final String FONT_DEFINITION = "terminal.views.view.font.definition"; //$NON-NLS-1$
+
+ // Reference to the parent tab item
+ private final CTabItem tabItem;
+
+ /**
+ * Constructor.
+ *
+ * @param tabItem The parent tab item. Must not be <code>null</code>.
+ */
+ public TabPropertyChangeListener(CTabItem tabItem) {
+ super();
+ Assert.isNotNull(tabItem);
+ this.tabItem = tabItem;
+ }
+
+ /**
+ * Returns the associated parent tab item.
+ *
+ * @return The parent tab item.
+ */
+ protected final CTabItem getTabItem() {
+ return tabItem;
+ }
+
+ /* (non-Javadoc)
+ * @see org.eclipse.jface.util.IPropertyChangeListener#propertyChange(org.eclipse.jface.util.PropertyChangeEvent)
+ */
+ @Override
+ public void propertyChange(PropertyChangeEvent event) {
+ // In case we are called once after the tab item got disposed
+ // --> Do nothing
+ if (getTabItem() == null || getTabItem().isDisposed()) return;
+
+ // Listen to changes of the Font settings
+ if (event.getProperty().equals(FONT_DEFINITION)) {
+ onFontDefinitionProperyChanged();
+ }
+ }
+
+ /**
+ * Called if a property change event for the terminal font
+ * definition is received.
+ */
+ protected void onFontDefinitionProperyChanged() {
+ // Get the current font from JFace
+ Font font = JFaceResources.getFont(FONT_DEFINITION);
+ // Get the terminal control from the tab item
+ if (getTabItem().getData() instanceof ITerminalViewControl) {
+ ITerminalViewControl terminal = (ITerminalViewControl)getTabItem().getData();
+ terminal.setFont(font);
+ }
+ }
+}
diff --git a/target_explorer/plugins/org.eclipse.tm.te.ui.terminals/src/org/eclipse/tm/te/ui/terminals/tabs/TabTerminalListener.java b/target_explorer/plugins/org.eclipse.tm.te.ui.terminals/src/org/eclipse/tm/te/ui/terminals/tabs/TabTerminalListener.java
new file mode 100644
index 000000000..4d3824fca
--- /dev/null
+++ b/target_explorer/plugins/org.eclipse.tm.te.ui.terminals/src/org/eclipse/tm/te/ui/terminals/tabs/TabTerminalListener.java
@@ -0,0 +1,111 @@
+/*******************************************************************************
+ * Copyright (c) 2011 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
+ *
+ * Contributors:
+ * Wind River Systems - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.tm.te.ui.terminals.tabs;
+
+import java.util.regex.Pattern;
+
+import org.eclipse.core.runtime.Assert;
+import org.eclipse.osgi.util.NLS;
+import org.eclipse.swt.custom.CTabItem;
+import org.eclipse.swt.widgets.Display;
+import org.eclipse.tm.internal.terminal.control.ITerminalListener;
+import org.eclipse.tm.internal.terminal.provisional.api.TerminalState;
+import org.eclipse.tm.te.ui.terminals.nls.Messages;
+
+/**
+ * Terminals tab default terminal listener implementation.
+ */
+@SuppressWarnings("restriction")
+public class TabTerminalListener implements ITerminalListener {
+ private final CTabItem tabItem;
+
+ /**
+ * Constructor.
+ *
+ * @param tabItem The parent tab item. Must not be <code>null</code>.
+ */
+ public TabTerminalListener(CTabItem tabItem) {
+ super();
+ Assert.isNotNull(tabItem);
+ this.tabItem = tabItem;
+ }
+
+ /**
+ * Returns the associated parent tab item.
+ *
+ * @return The parent tab item.
+ */
+ protected final CTabItem getTabItem() {
+ return tabItem;
+ }
+
+ /* (non-Javadoc)
+ * @see org.eclipse.tm.internal.terminal.control.ITerminalListener#setState(org.eclipse.tm.internal.terminal.provisional.api.TerminalState)
+ */
+ @Override
+ public void setState(final TerminalState state) {
+ // The tab item must have been not yet disposed
+ final CTabItem item = getTabItem();
+ if (item == null || item.isDisposed()) return;
+
+ // Update the tab item title
+ item.getDisplay().asyncExec(new Runnable() {
+ @Override
+ public void run() {
+ String newTitle = getTerminalConsoleTabTitle(state);
+ if (newTitle != null) item.setText(newTitle);
+ }
+ });
+ }
+
+ // The pattern will not change over the session life-time
+ private static final Pattern TERMINAL_TITLE_TERMINATED_PATTERN = Pattern.compile(Messages.TabTerminalListener_consoleTerminated.replaceAll("\\{[0-9]+\\}", ".*")); //$NON-NLS-1$ //$NON-NLS-2$
+
+ /**
+ * Returns the title to set to the terminal console tab for the given state.
+ * <p>
+ * <b>Note:</b> This method is called from {@link #setState(TerminalState)} and
+ * is expected to by called within the UI thread.
+ *
+ * @param state The terminal state. Must be not <code>null</code>.
+ * @return The terminal console tab title to set or <code>null</code> to leave the title unchanged.
+ */
+ protected String getTerminalConsoleTabTitle(TerminalState state) {
+ assert state != null && Display.findDisplay(Thread.currentThread()) != null;
+
+ // The tab item must have been not yet disposed
+ CTabItem item = getTabItem();
+ if (item == null || item.isDisposed()) return null;
+
+ // Get the current tab title
+ String oldTitle = item.getText();
+
+ // Construct the new title
+ String newTitle = null;
+
+ if (TerminalState.CLOSED.equals(state)) {
+ // Avoid multiple decorations of the closed state
+ if (!TERMINAL_TITLE_TERMINATED_PATTERN.matcher(oldTitle).matches()) {
+ newTitle = NLS.bind(Messages.TabTerminalListener_consoleTerminated, oldTitle);
+ } else {
+ newTitle = oldTitle;
+ }
+ }
+
+ return newTitle != null && !newTitle.equals(oldTitle) ? newTitle : null;
+ }
+
+ /* (non-Javadoc)
+ * @see org.eclipse.tm.internal.terminal.control.ITerminalListener#setTerminalTitle(java.lang.String)
+ */
+ @Override
+ public void setTerminalTitle(String title) {
+ }
+}
diff --git a/target_explorer/plugins/org.eclipse.tm.te.ui.terminals/src/org/eclipse/tm/te/ui/terminals/view/TerminalsView.java b/target_explorer/plugins/org.eclipse.tm.te.ui.terminals/src/org/eclipse/tm/te/ui/terminals/view/TerminalsView.java
new file mode 100644
index 000000000..29445d972
--- /dev/null
+++ b/target_explorer/plugins/org.eclipse.tm.te.ui.terminals/src/org/eclipse/tm/te/ui/terminals/view/TerminalsView.java
@@ -0,0 +1,309 @@
+/*******************************************************************************
+ * Copyright (c) 2011 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
+ *
+ * Contributors:
+ * Wind River Systems - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.tm.te.ui.terminals.view;
+
+import org.eclipse.core.runtime.Assert;
+import org.eclipse.jface.resource.JFaceResources;
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.custom.CTabFolder;
+import org.eclipse.swt.graphics.Color;
+import org.eclipse.swt.layout.GridData;
+import org.eclipse.swt.layout.GridLayout;
+import org.eclipse.swt.widgets.Composite;
+import org.eclipse.swt.widgets.Control;
+import org.eclipse.tm.te.ui.terminals.interfaces.ITerminalsView;
+import org.eclipse.tm.te.ui.terminals.tabs.TabFolderManager;
+import org.eclipse.tm.te.ui.terminals.tabs.TabFolderMenuHandler;
+import org.eclipse.tm.te.ui.terminals.tabs.TabFolderToolbarHandler;
+import org.eclipse.ui.IWorkbenchPreferenceConstants;
+import org.eclipse.ui.PlatformUI;
+import org.eclipse.ui.part.PageBook;
+import org.eclipse.ui.part.ViewPart;
+
+/**
+ * Terminals view.
+ */
+public class TerminalsView extends ViewPart implements ITerminalsView {
+
+ // Reference to the main page book control
+ private PageBook pageBookControl;
+ // Reference to the tab folder maintaining the consoles
+ private CTabFolder tabFolderControl;
+ // Reference to the tab folder manager
+ private TabFolderManager tabFolderManager;
+ // Reference to the tab folder menu handler
+ private TabFolderMenuHandler tabFolderMenuHandler;
+ // Reference to the tab folder toolbar handler
+ private TabFolderToolbarHandler tabFolderToolbarHandler;
+ // Reference to the empty page control (to be show if no console is open)
+ private Control emptyPageControl;
+
+ /**
+ * Constructor.
+ */
+ public TerminalsView() {
+ super();
+ }
+
+ /* (non-Javadoc)
+ * @see org.eclipse.ui.part.WorkbenchPart#dispose()
+ */
+ @Override
+ public void dispose() {
+ // Dispose the tab folder manager
+ if (tabFolderManager != null) { tabFolderManager.dispose(); tabFolderManager = null; }
+ // Dispose the tab folder menu handler
+ if (tabFolderMenuHandler != null) { tabFolderMenuHandler.dispose(); tabFolderMenuHandler = null; }
+ // Dispose the tab folder toolbar handler
+ if (tabFolderToolbarHandler != null) { tabFolderToolbarHandler.dispose(); tabFolderToolbarHandler = null; }
+
+ super.dispose();
+ }
+
+ /* (non-Javadoc)
+ * @see org.eclipse.ui.part.WorkbenchPart#createPartControl(org.eclipse.swt.widgets.Composite)
+ */
+ @Override
+ public void createPartControl(Composite parent) {
+ // Create the page book control
+ pageBookControl = doCreatePageBookControl(parent);
+ Assert.isNotNull(pageBookControl);
+ // Configure the page book control
+ doConfigurePageBookControl(pageBookControl);
+
+ // Create the empty page control
+ emptyPageControl = doCreateEmptyPageControl(pageBookControl);
+ Assert.isNotNull(emptyPageControl);
+ // Configure the empty page control
+ doConfigureEmptyPageControl(emptyPageControl);
+
+ // Create the tab folder control (empty)
+ tabFolderControl = doCreateTabFolderControl(pageBookControl);
+ Assert.isNotNull(tabFolderControl);
+ // Configure the tab folder control
+ doConfigureTabFolderControl(tabFolderControl);
+
+ // Create the tab folder manager
+ tabFolderManager = doCreateTabFolderManager(this);
+ Assert.isNotNull(tabFolderManager);
+ // Set the tab folder manager as the selection provider
+ getSite().setSelectionProvider(tabFolderManager);
+
+ // Setup the tab folder menu handler
+ tabFolderMenuHandler = doCreateTabFolderMenuHandler(this);
+ Assert.isNotNull(tabFolderMenuHandler);
+ doConfigureTabFolderMenuHandler(tabFolderMenuHandler);
+
+ // Setup the tab folder toolbar handler
+ tabFolderToolbarHandler = doCreateTabFolderToolbarHandler(this);
+ Assert.isNotNull(tabFolderToolbarHandler);
+ doConfigureTabFolderToolbarHandler(tabFolderToolbarHandler);
+
+ // Show the empty page control by default
+ switchToEmptyPageControl();
+ }
+
+ /**
+ * Creates the {@link PageBook} instance.
+ *
+ * @param parent The parent composite. Must not be <code>null</code>.
+ * @return The page book instance. Must never be <code>null</code>.
+ */
+ protected PageBook doCreatePageBookControl(Composite parent) {
+ return new PageBook(parent, SWT.NONE);
+ }
+
+ /**
+ * Configure the given page book control.
+ *
+ * @param pagebook The page book control. Must not be <code>null</code>.
+ */
+ protected void doConfigurePageBookControl(PageBook pagebook) {
+ Assert.isNotNull(pagebook);
+
+ if (getContextHelpId() != null)
+ PlatformUI.getWorkbench().getHelpSystem().setHelp(pagebook, getContextHelpId());
+ }
+
+ /**
+ * Returns the context help id associated with the terminal console view instance.
+ * <p>
+ * <b>Note:</b> The default implementation returns the view id as context help id.
+ *
+ * @return The context help id or <code>null</code> if none is associated.
+ */
+ @Override
+ public String getContextHelpId() {
+ return getViewSite().getId();
+ }
+
+ /**
+ * Creates the empty page control instance.
+ *
+ * @param parent The parent composite. Must not be <code>null</code>.
+ * @return The empty page control instance. Must never be <code>null</code>.
+ */
+ protected Control doCreateEmptyPageControl(Composite parent) {
+ Composite composite = new Composite(parent, SWT.NONE);
+ composite.setLayout(new GridLayout());
+ composite.setLayoutData(new GridData(GridData.FILL_BOTH));
+ return composite;
+ }
+
+ /**
+ * Configures the empty page control.
+ *
+ * @param control The empty page control. Must not be <code>null</code>.
+ */
+ protected void doConfigureEmptyPageControl(Control control) {
+ Assert.isNotNull(control);
+ }
+
+ /**
+ * Creates the tab folder control instance.
+ *
+ * @param parent The parent composite. Must not be <code>null</code>.
+ * @return The tab folder control instance. Must never be <code>null</code>.
+ */
+ protected CTabFolder doCreateTabFolderControl(Composite parent) {
+ return new CTabFolder(parent, SWT.NO_REDRAW_RESIZE | SWT.NO_TRIM | SWT.FLAT | SWT.BORDER);
+ }
+
+ /**
+ * Configures the tab folder control.
+ *
+ * @param tabFolder The tab folder control. Must not be <code>null</code>.
+ */
+ protected void doConfigureTabFolderControl(CTabFolder tabFolder) {
+ Assert.isNotNull(tabFolder);
+
+ // Set the layout data
+ tabFolder.setLayoutData(new GridData(GridData.FILL_BOTH));
+
+ // Set the tab gradient coloring from the global preferences
+ if (useGradientTabBackgroundColor()) {
+ tabFolder.setSelectionBackground(new Color[] {
+ JFaceResources.getColorRegistry().get("org.eclipse.ui.workbench.ACTIVE_TAB_BG_START"), //$NON-NLS-1$
+ JFaceResources.getColorRegistry().get("org.eclipse.ui.workbench.ACTIVE_TAB_BG_END") //$NON-NLS-1$
+ },
+ new int[] {100}, true);
+ }
+ // Apply the tab folder selection foreground color
+ tabFolder.setSelectionForeground(JFaceResources.getColorRegistry().get("org.eclipse.ui.workbench.ACTIVE_TAB_TEXT_COLOR")); //$NON-NLS-1$
+
+ // Set the tab style from the global preferences
+ tabFolder.setSimple(PlatformUI.getPreferenceStore().getBoolean(IWorkbenchPreferenceConstants.SHOW_TRADITIONAL_STYLE_TABS));
+ }
+
+ /**
+ * If <code>True</code> is returned, the inner tabs are colored with
+ * gradient coloring set in the Eclipse workbench color settings.
+ *
+ * @return <code>True</code> to use gradient tab colors, <code>false</code> otherwise.
+ */
+ protected boolean useGradientTabBackgroundColor() {
+ return false;
+ }
+
+ /**
+ * Creates the tab folder manager.
+ *
+ * @param parentView The parent view instance. Must be not <code>null</code>.
+ * @return The tab folder manager. Must never be <code>null</code>.
+ */
+ protected TabFolderManager doCreateTabFolderManager(ITerminalsView parentView) {
+ Assert.isNotNull(parentView);
+ return new TabFolderManager(parentView);
+ }
+
+ /**
+ * Creates the tab folder menu handler.
+ *
+ * @param parentView The parent view instance. Must be not <code>null</code>.
+ * @return The tab folder menu handler. Must never be <code>null</code>.
+ */
+ protected TabFolderMenuHandler doCreateTabFolderMenuHandler(ITerminalsView parentView) {
+ Assert.isNotNull(parentView);
+ return new TabFolderMenuHandler(parentView);
+ }
+
+ /**
+ * Configure the tab folder menu handler
+ *
+ * @param menuHandler The tab folder menu handler. Must not be <code>null</code>.
+ */
+ protected void doConfigureTabFolderMenuHandler(TabFolderMenuHandler menuHandler) {
+ Assert.isNotNull(menuHandler);
+ menuHandler.initialize();
+ }
+
+ /**
+ * Creates the tab folder toolbar handler.
+ *
+ * @param parentView The parent view instance. Must be not <code>null</code>.
+ * @return The tab folder toolbar handler. Must never be <code>null</code>.
+ */
+ protected TabFolderToolbarHandler doCreateTabFolderToolbarHandler(ITerminalsView parentView) {
+ Assert.isNotNull(parentView);
+ return new TabFolderToolbarHandler(parentView);
+ }
+
+ /**
+ * Configure the tab folder toolbar handler
+ *
+ * @param toolbarHandler The tab folder toolbar handler. Must not be <code>null</code>.
+ */
+ protected void doConfigureTabFolderToolbarHandler(TabFolderToolbarHandler toolbarHandler) {
+ Assert.isNotNull(toolbarHandler);
+ toolbarHandler.initialize();
+ }
+
+ /* (non-Javadoc)
+ * @see org.eclipse.ui.part.WorkbenchPart#setFocus()
+ */
+ @Override
+ public void setFocus() {
+ pageBookControl.setFocus();
+ }
+
+ /* (non-Javadoc)
+ * @see org.eclipse.tm.te.ui.terminals.interfaces.ITerminalsView#switchToEmptyPageControl()
+ */
+ @Override
+ public void switchToEmptyPageControl() {
+ if (!pageBookControl.isDisposed() && !emptyPageControl.isDisposed()) pageBookControl.showPage(emptyPageControl);
+ }
+
+ /* (non-Javadoc)
+ * @see org.eclipse.tm.te.ui.terminals.interfaces.ITerminalsView#switchToTabFolderControl()
+ */
+ @Override
+ public void switchToTabFolderControl() {
+ if (!pageBookControl.isDisposed() && !tabFolderControl.isDisposed()) pageBookControl.showPage(tabFolderControl);
+ }
+
+ /* (non-Javadoc)
+ * @see org.eclipse.ui.part.WorkbenchPart#getAdapter(java.lang.Class)
+ */
+ @Override
+ public Object getAdapter(Class adapter) {
+ if (CTabFolder.class.isAssignableFrom(adapter)) {
+ return tabFolderControl;
+ } else if (TabFolderManager.class.isAssignableFrom(adapter)) {
+ return tabFolderManager;
+ } else if (TabFolderMenuHandler.class.isAssignableFrom(adapter)) {
+ return tabFolderMenuHandler;
+ } else if (TabFolderToolbarHandler.class.isAssignableFrom(adapter)) {
+ return tabFolderToolbarHandler;
+ }
+
+ return super.getAdapter(adapter);
+ }
+}
diff --git a/target_explorer/plugins/org.eclipse.tm.te.ui/src/org/eclipse/tm/te/ui/interfaces/IUIConstants.java b/target_explorer/plugins/org.eclipse.tm.te.ui/src/org/eclipse/tm/te/ui/interfaces/IUIConstants.java
index d5170d922..9ac6f85f5 100644
--- a/target_explorer/plugins/org.eclipse.tm.te.ui/src/org/eclipse/tm/te/ui/interfaces/IUIConstants.java
+++ b/target_explorer/plugins/org.eclipse.tm.te.ui/src/org/eclipse/tm/te/ui/interfaces/IUIConstants.java
@@ -13,8 +13,6 @@ import org.eclipse.tm.te.ui.activator.UIPlugin;
/**
* Target Explorer: Common UI constants.
- *
- * @author uwe.stieber@windriver.com
*/
public interface IUIConstants {

Back to the top