blob: bd2879456229a94fc913a9d9b1261574b16729d8 [file] [log] [blame]
/*******************************************************************************
* Copyright (c) 2011, 2018 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 2.0 which accompanies this distribution, and is
* available at https://www.eclipse.org/legal/epl-2.0/
*
* SPDX-License-Identifier: EPL-2.0
*
* Contributors:
* Wind River Systems - initial API and implementation
*******************************************************************************/
package org.eclipse.tm.terminal.view.ui.tabs;
import java.io.UnsupportedEncodingException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import org.eclipse.core.runtime.Assert;
import org.eclipse.core.runtime.PlatformObject;
import org.eclipse.jface.action.IStatusLineManager;
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.osgi.util.NLS;
import org.eclipse.swt.SWT;
import org.eclipse.swt.custom.CTabFolder;
import org.eclipse.swt.custom.CTabItem;
import org.eclipse.swt.dnd.Clipboard;
import org.eclipse.swt.dnd.DND;
import org.eclipse.swt.dnd.TextTransfer;
import org.eclipse.swt.events.DisposeEvent;
import org.eclipse.swt.events.DisposeListener;
import org.eclipse.swt.events.MouseAdapter;
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.Display;
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.ITerminalControl;
import org.eclipse.tm.internal.terminal.provisional.api.TerminalState;
import org.eclipse.tm.terminal.view.core.interfaces.constants.ITerminalsConnectorConstants;
import org.eclipse.tm.terminal.view.ui.activator.UIPlugin;
import org.eclipse.tm.terminal.view.ui.interfaces.ITerminalsView;
import org.eclipse.tm.terminal.view.ui.interfaces.ImageConsts;
import org.eclipse.tm.terminal.view.ui.nls.Messages;
import org.eclipse.ui.PlatformUI;
/**
* Terminal tab folder manager.
*/
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;
/**
* List of selection changed listeners.
*/
private final List<ISelectionChangedListener> selectionChangedListeners = new ArrayList<>();
/**
* Map of tab command input field handler per tab item
*/
private final Map<CTabItem, TabCommandFieldHandler> commandFieldHandler = new HashMap<>();
/**
* 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 not be <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;
}
@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);
}
}
@Override
public void mouseDown(MouseEvent e) {
// Left button down -> select mode starts
if (e.button == 1)
selectMode = true;
}
@Override
public void mouseUp(MouseEvent e) {
if (e.button == 1 && selectMode) {
selectMode = false;
// Fire a selection changed event with the terminal controls selection
try {
Display display = PlatformUI.getWorkbench().getDisplay();
display.asyncExec(
() -> fireSelectionChanged(new StructuredSelection(getTerminal().getSelection())));
} catch (Exception ex) {
// if display is disposed, silently ignore.
}
}
}
@Override
public void mouseDoubleClick(MouseEvent e) {
}
}
/**
* Constructor.
*
* @param parentView The parent terminals console view. Must not be <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);
}
/**
* Creates the terminal console tab folder selection listener instance.
*
* @param parent The parent terminal console tab folder manager. Must not be <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 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);
// Dispose the tab command field handler
for (TabCommandFieldHandler handler : commandFieldHandler.values()) {
handler.dispose();
}
commandFieldHandler.clear();
}
/**
* Creates a new tab item with the given title and connector.
*
* @param title The tab title. Must not be <code>null</code>.
* @param encoding The terminal encoding or <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 flags The flags controlling how the console is opened or <code>null</code> to use defaults.
*
* @return The created tab item or <code>null</code> if failed.
*/
@SuppressWarnings({ "unused" })
public CTabItem createTabItem(String title, String encoding, ITerminalConnector connector, Object data,
Map<String, Boolean> flags) {
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(this, item), composite, new ITerminalConnector[] { connector },
true);
if (terminal instanceof ITerminalControl) {
Object value = flags != null ? flags.get(ITerminalsConnectorConstants.PROP_DATA_NO_RECONNECT) : null;
boolean noReconnect = value instanceof Boolean ? ((Boolean) value).booleanValue() : false;
((ITerminalControl) terminal).setConnectOnEnterIfClosed(!noReconnect);
}
// Add middle mouse button paste support
addMiddleMouseButtonPasteSupport(terminal);
// Add the "selection" listener to the terminal control
new TerminalControlSelectionListener(terminal);
// Configure the terminal encoding
try {
terminal.setEncoding(encoding);
} 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 = getParentView().getAdapter(TabFolderMenuHandler.class);
if (menuHandler != null) {
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;
}
/**
* Used for DnD of terminal tab items between terminal views
* <p>
* Create a new tab item in the "dropped" terminal view using the
* information stored in the given item.
*
* @param oldItem The old dragged tab item. Must not be <code>null</code>.
* @return The new dropped tab item.
*/
@SuppressWarnings({ "unchecked" })
public CTabItem cloneTabItemAfterDrop(CTabItem oldItem) {
Assert.isNotNull(oldItem);
ITerminalViewControl terminal = (ITerminalViewControl) oldItem.getData();
ITerminalConnector connector = terminal.getTerminalConnector();
Object data = oldItem.getData("customData"); //$NON-NLS-1$
Map<String, Object> properties = (Map<String, Object>) oldItem.getData("properties"); //$NON-NLS-1$
String title = oldItem.getText();
// 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);
// Move the terminal listener to the new item
TabTerminalListener.move(oldItem, 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);
// Remember terminal state
TerminalState oldState = terminal.getState();
// Keep the context menu from being disposed
terminal.getControl().setMenu(null);
// change the "parent".
Assert.isTrue(terminal instanceof ITerminalControl);
((ITerminalControl) terminal).setupTerminal(composite);
// Add middle mouse button paste support
addMiddleMouseButtonPasteSupport(terminal);
item.setData(terminal);
// Associate the custom data node with the tab item (if any)
if (data != null)
item.setData("customData", data); //$NON-NLS-1$
// Associate the properties with the tab item (if any)
if (properties != null)
item.setData("properties", properties); //$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 = getParentView().getAdapter(TabFolderMenuHandler.class);
if (menuHandler != null) {
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);
// needed to get the focus and cursor
Assert.isTrue(terminal instanceof ITerminalControl);
((ITerminalControl) terminal).setState(oldState);
// Fire selection changed event
fireSelectionChanged();
}
// Return the create tab item finally.
return item;
}
protected void addMiddleMouseButtonPasteSupport(final ITerminalViewControl terminal) {
terminal.getControl().addMouseListener(new MouseAdapter() {
@Override
public void mouseDown(MouseEvent e) {
// paste when the middle button is clicked
if (e.button == 2) {
Clipboard clipboard = terminal.getClipboard();
if (clipboard.isDisposed())
return;
int clipboardType = DND.SELECTION_CLIPBOARD;
if (clipboard.getAvailableTypes(clipboardType).length == 0)
// use normal clipboard if selection clipboard is not available
clipboardType = DND.CLIPBOARD;
String text = (String) clipboard.getContents(TextTransfer.getInstance(), clipboardType);
if (text != null && text.length() > 0)
terminal.pasteString(text);
}
}
});
}
/**
* Generate a unique title string based on the given proposal.
*
* @param proposal The proposal. Must not be <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<>();
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 not be <code>null</code>.
*/
protected void setupTerminalTabListeners(final CTabItem item) {
Assert.isNotNull(item);
// Create and associate the disposal listener
DisposeListener disposeListener = doCreateTerminalTabDisposeListener(this);
// store the listener to make access easier e.g. needed in DnD
item.setData("disposeListener", disposeListener); //$NON-NLS-1$
item.addDisposeListener(disposeListener);
}
/**
* Creates a new terminal console tab terminal listener instance.
*
* @param tabFolderManager The tab folder manager. Must not be <code>null</code>.
* @param item The tab item. Must not be <code>null</code>.
*
* @return The terminal listener instance.
*/
protected ITerminalListener doCreateTerminalTabTerminalListener(TabFolderManager tabFolderManager, CTabItem item) {
Assert.isNotNull(item);
return new TabTerminalListener(tabFolderManager, item);
}
/**
* Creates a new terminal console tab dispose listener instance.
*
* @param parent The parent terminal console tab folder manager. Must not be <code>null</code>.
* @return The dispose listener instance.
*/
protected DisposeListener doCreateTerminalTabDisposeListener(TabFolderManager parent) {
Assert.isNotNull(parent);
return new TabDisposeListener(parent);
}
/**
* Returns the tab item image.
*
* @param connector The terminal connector. Must not be <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 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 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 not be <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;
}
/**
* Returns the command input field handler for the given tab item.
*
* @param item The tab item or <code>null</code>.
* @return The command input field handler or <code>null</code>.
*/
public final TabCommandFieldHandler getTabCommandFieldHandler(CTabItem item) {
// Null items or disposed items cannot be matched
if (item == null || item.isDisposed())
return null;
TabCommandFieldHandler handler = commandFieldHandler.get(item);
if (handler == null) {
handler = createTabCommandFieldHandler(this, item);
Assert.isNotNull(handler);
commandFieldHandler.put(item, handler);
}
return handler;
}
/**
* Create the command input field handler for the given tab item.
*
* @param tabFolderManager The parent tab folder manager. Must not be <code>null</code>
* @param item The associated tab item. Must not be <code>null</code>.
*
* @return The command input field handler. Must not be <code>null</code>.
*
* @since 4.1
*/
protected TabCommandFieldHandler createTabCommandFieldHandler(TabFolderManager tabFolderManager, CTabItem item) {
return new TabCommandFieldHandler(tabFolderManager, item);
}
/**
* Dispose the command input field handler for the given tab item.
*
* @param item The tab item or <code>null</code>.
*/
protected void disposeTabCommandFieldHandler(CTabItem item) {
// Null items or disposed items cannot be matched
if (item == null || item.isDisposed())
return;
TabCommandFieldHandler handler = commandFieldHandler.remove(item);
if (handler != null)
handler.dispose();
}
@Override
public void addSelectionChangedListener(ISelectionChangedListener listener) {
if (listener != null && !selectionChangedListeners.contains(listener))
selectionChangedListeners.add(listener);
}
@Override
public void removeSelectionChangedListener(ISelectionChangedListener listener) {
if (listener != null)
selectionChangedListeners.remove(listener);
}
@Override
public ISelection getSelection() {
CTabItem activeTabItem = getActiveTabItem();
return activeTabItem != null ? new StructuredSelection(activeTabItem) : new StructuredSelection();
}
@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() {
updateStatusLine();
fireSelectionChanged(getSelection());
}
/**
* Fire the selection changed event with the terminal text!
* to the registered listeners.
* see also TerminalControlSelectionListener- mouseUp
*
* @since 4.1
*/
protected void fireTerminalSelectionChanged() {
updateStatusLine();
CTabItem item = getActiveTabItem();
if (item != null && !item.isDisposed()) {
ITerminalViewControl terminal = (ITerminalViewControl) item.getData();
if (terminal != null && !terminal.isDisposed()) {
fireSelectionChanged(new StructuredSelection(terminal.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);
}
}
/**
* Update the parent view status line.
*/
public final void updateStatusLine() {
String message = null;
IStatusLineManager manager = parentView.getViewSite().getActionBars().getStatusLineManager();
CTabItem item = getActiveTabItem();
if (item != null && !item.isDisposed()) {
ITerminalViewControl terminal = (ITerminalViewControl) item.getData();
if (terminal != null && !terminal.isDisposed()) {
StringBuilder buffer = new StringBuilder();
buffer.append(state2msg(item, terminal.getState()));
buffer.append(" - "); //$NON-NLS-1$
String encoding = terminal.getEncoding();
if (encoding == null || "ISO-8859-1".equals(encoding)) { //$NON-NLS-1$
encoding = "Default (ISO-8859-1)"; //$NON-NLS-1$
}
buffer.append(NLS.bind(Messages.TabFolderManager_encoding, encoding));
message = buffer.toString();
}
}
manager.setMessage(message);
}
/**
* Returns the string representation of the given terminal state.
*
* @param item The tab folder item. Must not be <code>null</code>.
* @param state The terminal state. Must not be <code>null</code>.
*
* @return The string representation.
*/
@SuppressWarnings("unchecked")
protected String state2msg(CTabItem item, TerminalState state) {
Assert.isNotNull(item);
Assert.isNotNull(state);
// Determine the terminal properties of the tab folder
Map<String, Object> properties = (Map<String, Object>) item.getData("properties"); //$NON-NLS-1$
// Get he current terminal state as string
String stateStr = state.toString();
// Lookup a matching text representation of the state
String key = "TabFolderManager_state_" + stateStr.replaceAll("\\.", " ").trim().toLowerCase(); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
String stateMsg = null;
if (properties != null)
stateMsg = properties.get(key) instanceof String ? (String) properties.get(key) : null;
if (stateMsg == null)
stateMsg = Messages.getString(key);
if (stateMsg == null)
stateMsg = stateStr;
return stateMsg;
}
}