blob: 5f557044aca161c2eb2e87c81299053614d8af9f [file] [log] [blame]
/*******************************************************************************
* Copyright (c) 2013 OPCoach.
* 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:
* OPCoach - initial API and implementation
*******************************************************************************/
package org.eclipse.e4.internal.tools.context.spy;
import javax.annotation.PostConstruct;
import javax.annotation.PreDestroy;
import javax.inject.Inject;
import javax.inject.Named;
import org.eclipse.e4.core.contexts.ContextInjectionFactory;
import org.eclipse.e4.core.contexts.IEclipseContext;
import org.eclipse.e4.core.di.annotations.Optional;
import org.eclipse.e4.core.internal.contexts.EclipseContext;
import org.eclipse.e4.ui.di.Focus;
import org.eclipse.e4.ui.services.IServiceConstants;
import org.eclipse.jface.viewers.ColumnViewerToolTipSupport;
import org.eclipse.jface.viewers.ILabelProvider;
import org.eclipse.jface.viewers.TreeViewer;
import org.eclipse.jface.viewers.TreeViewerColumn;
import org.eclipse.jface.viewers.Viewer;
import org.eclipse.jface.viewers.ViewerComparator;
import org.eclipse.jface.viewers.ViewerFilter;
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.Composite;
import org.eclipse.swt.widgets.Tree;
import org.eclipse.swt.widgets.TreeColumn;
/**
* This part listen to selection, and if it is an EclipseContext,
* it displays its information It is used in the integrated ContextSpyPart
* and (in the future) it could be used outside to display the context of focused part for instance
* */
public class ContextDataPart
{
private TreeViewer contextDataViewer;
private ContextDataProvider dataProvider;
private ContextEntryComparator comparator;
/**
* Create contents of the view part.
*/
@PostConstruct
public void createControls(Composite parent, IEclipseContext ctx)
{
parent.setLayout(new GridLayout(1, false));
// TreeViewer on the top
contextDataViewer = new TreeViewer(parent);
dataProvider = ContextInjectionFactory.make(ContextDataProvider.class, ctx);
contextDataViewer.setContentProvider(dataProvider);
contextDataViewer.setLabelProvider(dataProvider);
// contextContentTv.setSorter(new ViewerSorter());
final Tree cTree = contextDataViewer.getTree();
cTree.setHeaderVisible(true);
cTree.setLinesVisible(true);
cTree.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true));
// tv.setInput(a);
contextDataViewer.setInput("Foo"); // getElements starts alone
// Add columns in the tree
// Create the first column for the key
TreeViewerColumn keyCol = new TreeViewerColumn(contextDataViewer, SWT.NONE);
keyCol.getColumn().setWidth(400);
keyCol.getColumn().setText("Key");
ContextDataProvider keyLabelProvider = ContextInjectionFactory.make(ContextDataProvider.class, ctx);
keyLabelProvider.setDisplayKey(true);
keyCol.setLabelProvider(keyLabelProvider);
keyCol.getColumn().setToolTipText("Key in context");
keyCol.getColumn().addSelectionListener(
getHeaderSelectionAdapter(contextDataViewer, keyCol.getColumn(), 0, keyLabelProvider));
comparator = new ContextEntryComparator(0, keyLabelProvider);
contextDataViewer.setComparator(comparator);
// Create the second column for the value
TreeViewerColumn valueCol = new TreeViewerColumn(contextDataViewer, SWT.NONE);
valueCol.getColumn().setWidth(600);
valueCol.getColumn().setText("Value");
ContextDataProvider valueLabelProvider = ContextInjectionFactory.make(ContextDataProvider.class, ctx);
valueCol.setLabelProvider(dataProvider);
valueCol.getColumn().addSelectionListener(
getHeaderSelectionAdapter(contextDataViewer, valueCol.getColumn(), 1, valueLabelProvider));
// Open all the tree
contextDataViewer.expandAll();
ColumnViewerToolTipSupport.enableFor(contextDataViewer);
}
@PreDestroy
public void dispose()
{
}
@Focus
public void setFocus()
{
contextDataViewer.getControl().setFocus();
}
@SuppressWarnings("restriction")
@Inject
@Optional
public void listenToContext(@Named(IServiceConstants.ACTIVE_SELECTION) EclipseContext ctx)
{
// Must check if dataviewer is created or not (when we reopen the window @postconstruct has not been called yet)
if ((ctx == null) || (contextDataViewer == null))
{
return;
}
contextDataViewer.setInput(ctx);
contextDataViewer.expandToLevel(2);
}
/**
* An entry comparator for the table, dealing with column index, keys and
* values
*/
public class ContextEntryComparator extends ViewerComparator
{
private int columnIndex;
private int direction;
private ILabelProvider labelProvider;
public ContextEntryComparator(int columnIndex, ILabelProvider defaultLabelProvider)
{
this.columnIndex = columnIndex;
direction = SWT.UP;
labelProvider = defaultLabelProvider;
}
public int getDirection()
{
return direction;
}
/** Called when click on table header, reverse order */
public void setColumn(int column)
{
if (column == columnIndex)
{
// Same column as last sort; toggle the direction
direction = (direction == SWT.UP) ? SWT.DOWN : SWT.UP;
} else
{
// New column; do a descending sort
columnIndex = column;
direction = SWT.DOWN;
}
}
@Override
public int compare(Viewer viewer, Object e1, Object e2)
{
// For root elements at first level, we keep Local before Inherited
if ((e1 == ContextDataProvider.LOCAL_VALUE_NODE) || (e2 == ContextDataProvider.LOCAL_VALUE_NODE))
return -1;
// Now can compare the text from label provider.
String lp1 = labelProvider.getText(e1);
String lp2 = labelProvider.getText(e2);
String s1 = lp1 == null ? "" : lp1.toLowerCase();
String s2 = lp2 == null ? "" : lp2.toLowerCase();
int rc = s1.compareTo(s2);
// If descending order, flip the direction
return (direction == SWT.DOWN) ? -rc : rc;
}
public void setLabelProvider(ILabelProvider textProvider)
{
labelProvider = textProvider;
}
}
private SelectionAdapter getHeaderSelectionAdapter(final TreeViewer viewer, final TreeColumn column, final int columnIndex,
final ILabelProvider textProvider)
{
SelectionAdapter selectionAdapter = new SelectionAdapter()
{
@Override
public void widgetSelected(SelectionEvent e)
{
viewer.setComparator(comparator);
comparator.setColumn(columnIndex);
comparator.setLabelProvider(textProvider);
viewer.getTree().setSortDirection(comparator.getDirection());
viewer.getTree().setSortColumn(column);
viewer.refresh();
}
};
return selectionAdapter;
}
public void refresh(boolean refreshLabel)
{
contextDataViewer.refresh(refreshLabel);
}
private static final ViewerFilter[] NO_FILTER = new ViewerFilter[0];
public void setFilter(ViewerFilter filter)
{
contextDataViewer.setFilters((filter == null) ? NO_FILTER : new ViewerFilter[] { filter });
}
}