| /******************************************************************************* |
| * Copyright (c) 2009, 2015 Ericsson |
| * |
| * 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: |
| * Francois Chouinard - Initial API and implementation |
| * Bernd Hufmann - Filled with content |
| * Markus Schorn - Bug 448058: Use org.eclipse.remote in favor of RSE |
| *******************************************************************************/ |
| |
| package org.eclipse.tracecompass.internal.lttng2.control.ui.views; |
| |
| import java.util.ArrayList; |
| import java.util.List; |
| |
| import org.eclipse.core.runtime.IProgressMonitor; |
| import org.eclipse.core.runtime.IStatus; |
| import org.eclipse.core.runtime.Status; |
| import org.eclipse.jface.action.MenuManager; |
| import org.eclipse.jface.viewers.ColumnViewerToolTipSupport; |
| import org.eclipse.jface.viewers.ISelection; |
| import org.eclipse.jface.viewers.StructuredSelection; |
| import org.eclipse.jface.viewers.TreeViewer; |
| import org.eclipse.jface.viewers.Viewer; |
| import org.eclipse.remote.core.IRemoteConnection; |
| import org.eclipse.swt.SWT; |
| import org.eclipse.swt.widgets.Composite; |
| import org.eclipse.swt.widgets.Menu; |
| import org.eclipse.tracecompass.internal.lttng2.control.ui.views.model.ITraceControlComponent; |
| import org.eclipse.tracecompass.internal.lttng2.control.ui.views.model.ITraceControlComponentChangedListener; |
| import org.eclipse.tracecompass.internal.lttng2.control.ui.views.model.impl.TargetNodeComponent; |
| import org.eclipse.tracecompass.internal.lttng2.control.ui.views.model.impl.TraceControlContentProvider; |
| import org.eclipse.tracecompass.internal.lttng2.control.ui.views.model.impl.TraceControlLabelProvider; |
| import org.eclipse.tracecompass.internal.lttng2.control.ui.views.model.impl.TraceControlRoot; |
| import org.eclipse.tracecompass.tmf.remote.core.proxy.TmfRemoteConnectionFactory; |
| import org.eclipse.ui.IMemento; |
| import org.eclipse.ui.IViewSite; |
| import org.eclipse.ui.PartInitException; |
| import org.eclipse.ui.dialogs.FilteredTree; |
| import org.eclipse.ui.dialogs.PatternFilter; |
| import org.eclipse.ui.part.ViewPart; |
| import org.eclipse.ui.progress.UIJob; |
| |
| /** |
| * <p> |
| * View implementation for Trace Control. |
| * </p> |
| * |
| * @author Bernd Hufmann |
| */ |
| public class ControlView extends ViewPart implements ITraceControlComponentChangedListener { |
| |
| // ------------------------------------------------------------------------ |
| // Constants |
| // ------------------------------------------------------------------------ |
| |
| /** |
| * View ID. |
| */ |
| public static final String ID = "org.eclipse.linuxtools.internal.lttng2.ui.views.control"; //$NON-NLS-1$ |
| |
| private static final String KEY_REMOTE_CONNECTION_NAME = "rc_name_"; //$NON-NLS-1$ |
| private static final String KEY_REMOTE_PROVIDER = "rc_id_"; //$NON-NLS-1$ |
| /** |
| * The default expand level. |
| */ |
| private static final int DEFAULT_EXPAND_LEVEL = 3; |
| |
| // ------------------------------------------------------------------------ |
| // Attributes |
| // ------------------------------------------------------------------------ |
| |
| /** |
| * The tree viewer. |
| */ |
| private TreeViewer fTreeViewer = null; |
| /** |
| * The trace control root node. This provides access to the whole model. |
| */ |
| private ITraceControlComponent fRoot = null; |
| |
| private List<IRemoteConnection> fInitialConnections; |
| |
| // ------------------------------------------------------------------------ |
| // Accessors |
| // ------------------------------------------------------------------------ |
| |
| /** |
| * Returns the trace control tree node (model) |
| * |
| * @return the trace control tree node (model). |
| */ |
| public ITraceControlComponent getTraceControlRoot() { |
| return fRoot; |
| } |
| |
| // ------------------------------------------------------------------------ |
| // Operations |
| // ------------------------------------------------------------------------ |
| |
| @Override |
| public void createPartControl(Composite parent) { |
| // Filter that shows all children of a match node |
| PatternFilter filter = new PatternFilter() { |
| @Override |
| protected boolean isLeafMatch(Viewer viewer, Object element) { |
| ITraceControlComponent parentElement = (ITraceControlComponent) element; |
| while (parentElement != null) { |
| if (super.isLeafMatch(viewer, parentElement)) { |
| return true; |
| } |
| parentElement = parentElement.getParent(); |
| } |
| return false; |
| } |
| }; |
| |
| // Create filtered tree |
| FilteredTree filteredTree = new FilteredTree(parent, SWT.MULTI | SWT.H_SCROLL | SWT.V_SCROLL, filter, true) { |
| @Override |
| protected void updateToolbar(boolean visible) { |
| super.updateToolbar(visible); |
| treeViewer.expandToLevel(DEFAULT_EXPAND_LEVEL); |
| } |
| }; |
| |
| fTreeViewer = filteredTree.getViewer(); |
| ColumnViewerToolTipSupport.enableFor(fTreeViewer); |
| |
| fTreeViewer.setContentProvider(new TraceControlContentProvider()); |
| fTreeViewer.setLabelProvider(new TraceControlLabelProvider()); |
| |
| // Create model root |
| fRoot = new TraceControlRoot(); |
| fRoot.addComponentListener(this); |
| if (fInitialConnections != null) { |
| for (IRemoteConnection rc : fInitialConnections) { |
| TargetNodeComponent node = new TargetNodeComponent(rc.getName(), fRoot, rc); |
| fRoot.addChild(node); |
| } |
| fInitialConnections = null; |
| } |
| fTreeViewer.setInput(fRoot); |
| |
| // Create context menu for the tree viewer |
| createContextMenu(); |
| |
| getSite().setSelectionProvider(fTreeViewer); |
| } |
| |
| @Override |
| public void saveState(IMemento memento) { |
| int i = 0; |
| for (ITraceControlComponent cmp : fRoot.getChildren()) { |
| if (cmp instanceof TargetNodeComponent) { |
| IRemoteConnection rc = ((TargetNodeComponent) cmp).getRemoteSystemProxy().getRemoteConnection(); |
| memento.putString(KEY_REMOTE_PROVIDER + i, rc.getConnectionType().getId()); |
| memento.putString(KEY_REMOTE_CONNECTION_NAME + i, rc.getName()); |
| i++; |
| } |
| } |
| super.saveState(memento); |
| } |
| |
| |
| @Override |
| public void init(IViewSite site, IMemento memento) throws PartInitException { |
| super.init(site, memento); |
| if (memento != null) { |
| fInitialConnections = new ArrayList<>(); |
| for(int i = 0; ; i++) { |
| String id = memento.getString(KEY_REMOTE_PROVIDER + i); |
| String name = memento.getString(KEY_REMOTE_CONNECTION_NAME + i); |
| if ((id == null) || (name == null)) { |
| break; |
| } |
| IRemoteConnection conn = TmfRemoteConnectionFactory.getRemoteConnection(id, name); |
| if (conn != null) { |
| fInitialConnections.add(conn); |
| } |
| } |
| } |
| } |
| |
| @Override |
| public void setFocus() { |
| fTreeViewer.getControl().setFocus(); |
| } |
| |
| @Override |
| public void componentAdded(ITraceControlComponent parent, ITraceControlComponent component) { |
| componentChanged(parent); |
| } |
| |
| @Override |
| public void componentRemoved(ITraceControlComponent parent, ITraceControlComponent component) { |
| componentChanged(parent); |
| } |
| |
| @Override |
| public void componentChanged(final ITraceControlComponent component) { |
| if (fTreeViewer.getTree().isDisposed()) { |
| return; |
| } |
| |
| UIJob myJob = new UIJob("Refresh") { //$NON-NLS-1$ |
| @Override |
| public IStatus runInUIThread(IProgressMonitor monitor) { |
| if (fTreeViewer.getTree().isDisposed()) { |
| return Status.OK_STATUS; |
| } |
| |
| fTreeViewer.refresh(component); |
| |
| // Change selection needed |
| final ISelection sel = fTreeViewer.getSelection(); |
| fTreeViewer.setSelection(null); |
| fTreeViewer.setSelection(sel); |
| |
| // Show component that was changed |
| fTreeViewer.reveal(component); |
| |
| return Status.OK_STATUS; |
| } |
| }; |
| myJob.setUser(false); |
| myJob.setSystem(true); |
| myJob.schedule(); |
| } |
| |
| /** |
| * Sets the selected component in the tree |
| * @param component - component to select |
| */ |
| public void setSelection(ITraceControlComponent component) { |
| ITraceControlComponent[] components = new ITraceControlComponent[1]; |
| components[0] = component; |
| setSelection(components); |
| } |
| |
| /** |
| * Sets the selected components in the tree |
| * @param components - array of components to select |
| */ |
| public void setSelection(ITraceControlComponent[] components) { |
| final StructuredSelection selection = new StructuredSelection(components); |
| UIJob myJob = new UIJob("Select") { //$NON-NLS-1$ |
| @Override |
| public IStatus runInUIThread(IProgressMonitor monitor) { |
| fTreeViewer.setSelection(selection); |
| return Status.OK_STATUS; |
| } |
| }; |
| myJob.setUser(false); |
| myJob.schedule(); |
| } |
| |
| // ------------------------------------------------------------------------ |
| // Helper methods |
| // ------------------------------------------------------------------------ |
| /** |
| * Creates the context sensitive menu. |
| */ |
| private void createContextMenu() { |
| // First we create a menu Manager |
| final MenuManager menuManager = new MenuManager(); |
| final Menu menu = menuManager.createContextMenu(fTreeViewer.getTree()); |
| // Set the MenuManager |
| fTreeViewer.getTree().setMenu(menu); |
| getSite().registerContextMenu(menuManager, fTreeViewer); |
| } |
| } |