/******************************************************************************* * 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.Assert; 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 ConsoleManagerPerspectiveListener 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 ConsoleManagerPerspectiveListener(); 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.isNotNull(Display.findDisplay(Thread.currentThread())); 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.isNotNull(Display.findDisplay(Thread.currentThread())); // 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.isNotNull(title); Assert.isNotNull(connector); Assert.isNotNull(Display.findDisplay(Thread.currentThread())); // 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.isNotNull(title); Assert.isNotNull(connector); Assert.isNotNull(Display.findDisplay(Thread.currentThread())); // 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.isNotNull(title); Assert.isNotNull(connector); Assert.isNotNull(Display.findDisplay(Thread.currentThread())); // Lookup the console CTabItem console = findConsole(id, title, connector, data); // If found, dispose the console if (console != null) console.dispose(); } }