blob: 21e026cce1be80105a9c8bf2980e57fdb5e3dca8 [file] [log] [blame]
/*******************************************************************************
* 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);
}
}