package org.eclipse.linuxtools.internal.docker.ui.views;
import java.util.Collection;
import org.eclipse.jface.action.IAction;
import org.eclipse.jface.action.IMenuManager;
import org.eclipse.jface.action.MenuManager;
import org.eclipse.jface.layout.GridDataFactory;
import org.eclipse.jface.layout.GridLayoutFactory;
import org.eclipse.jface.viewers.ColumnLabelProvider;
import org.eclipse.jface.viewers.ISelection;
import org.eclipse.jface.viewers.IStructuredSelection;
import org.eclipse.jface.viewers.ITreeSelection;
import org.eclipse.jface.viewers.TreeViewer;
import org.eclipse.jface.viewers.TreeViewerColumn;
import org.eclipse.linuxtools.docker.core.IDockerConnection;
import org.eclipse.linuxtools.docker.core.IDockerImageHierarchyNode;
import org.eclipse.swt.SWT;
import org.eclipse.swt.dnd.Clipboard;
import org.eclipse.swt.events.FocusEvent;
import org.eclipse.swt.events.FocusListener;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Display;
import org.eclipse.swt.widgets.Menu;
import org.eclipse.swt.widgets.Tree;
import org.eclipse.ui.IActionBars;
import org.eclipse.ui.IWorkbenchPart;
import org.eclipse.ui.actions.ActionFactory;
import org.eclipse.ui.part.IPageSite;
import org.eclipse.ui.views.properties.tabbed.AbstractPropertySection;
import org.eclipse.ui.views.properties.tabbed.TabbedPropertySheetPage;
public abstract class BasePropertySection extends AbstractPropertySection {
private TreeViewer treeViewer;
private CopyValueAction copyAction;
private Clipboard clipboard;
private IPageSite pageSite;
@Override
public void setInput(final IWorkbenchPart part,
final ISelection selection) {
super.setInput(part, selection);
final Object input = getSelection(selection);
if (getTreeViewer() == null) {
return;
}
if (input instanceof IDockerImageHierarchyNode) {
getTreeViewer()
.setInput(((IDockerImageHierarchyNode) input).getElement());
} else {
getTreeViewer().setInput(input);
}
}
IDockerConnection getConnection(final IWorkbenchPart part,
final ISelection selection) {
final Object input = getSelection(selection);
if (part instanceof DockerContainersView) {
return ((DockerContainersView) part).getConnection();
} else if (part instanceof DockerImagesView) {
return ((DockerImagesView) part).getConnection();
} else if (part instanceof DockerImageHierarchyView) {
return ((DockerImageHierarchyView) part).getConnection();
} else {
final ITreeSelection treeSelection = (ITreeSelection) selection;
return (IDockerConnection) treeSelection.getPathsFor(input)[0]
.getFirstSegment();
}
}
Object getSelection(final ISelection selection) {
if (selection instanceof ITreeSelection) {
return ((ITreeSelection) selection).getFirstElement();
} else if (selection instanceof IStructuredSelection) {
return ((IStructuredSelection) selection).getFirstElement();
}
return null;
}
@Override
public void createControls(final Composite parent, final TabbedPropertySheetPage propertySheetPage) {
GridLayoutFactory.fillDefaults().numColumns(1).applyTo(parent);
GridDataFactory.fillDefaults().align(SWT.FILL, SWT.FILL).grab(true, true).applyTo(parent);
final Composite container = new Composite(parent, SWT.NONE);
container.setBackground(Display.getDefault().getSystemColor(SWT.COLOR_LIST_BACKGROUND));
GridLayoutFactory.fillDefaults().numColumns(1).margins(5, 5).applyTo(container);
GridDataFactory.fillDefaults().align(SWT.FILL, SWT.FILL).grab(true, true).hint(400, 180).applyTo(container);
this.treeViewer = createTableTreeViewer(container);
if (this.clipboard != null)
this.clipboard.dispose();
this.clipboard = new Clipboard(Display.getCurrent());
this.pageSite = propertySheetPage.getSite();
initContextMenu(pageSite, clipboard);
GridDataFactory.fillDefaults().align(SWT.FILL, SWT.FILL).grab(true, true).applyTo(treeViewer.getControl());
}
private TreeViewer createTableTreeViewer(final Composite container) {
final TreeViewer treeViewer = new TreeViewer(container, SWT.V_SCROLL | SWT.H_SCROLL);
final Tree tree = treeViewer.getTree();
tree.setLinesVisible(true);
tree.setHeaderVisible(true);
final TreeViewerColumn propertyColumn = new TreeViewerColumn(treeViewer, SWT.BORDER);
propertyColumn.getColumn().setWidth(150);
propertyColumn.getColumn().setText("Property");
propertyColumn.setLabelProvider(new ColumnLabelProvider() {
@Override
public String getText(final Object element) {
if(element instanceof Object[]) {
final Object property = ((Object[])element)[0];
return property.toString();
}
return super.getText(element);
}
});
final TreeViewerColumn valueColumn = new TreeViewerColumn(treeViewer, SWT.BORDER);
valueColumn.getColumn().setWidth(500);
valueColumn.getColumn().setText("Value");
valueColumn.setLabelProvider(new ColumnLabelProvider() {
@Override
public String getText(final Object element) {
if(element instanceof Object[]) {
final Object value = ((Object[])element)[1];
// do not show values of a collection. There will be nested elements in the treeview for them.
if(value instanceof Collection) {
return "";
} else if(value instanceof String || value instanceof Boolean || value instanceof Integer) {
return value.toString();
}
return "";
}
return super.getText(element);
}
});
return treeViewer;
}
TreeViewer getTreeViewer() {
return treeViewer;
}
/**
* Initializes the viewer context menu.
*
* @param pageSite
* page
* @param clipboard
* clipboard
*/
private void initContextMenu(IPageSite pageSite, Clipboard clipboard) {
TreeViewer treeViewer = getTreeViewer();
copyAction = new CopyValueAction(getTreeViewer(), clipboard);
MenuManager menuMgr = new MenuManager("#PopupMenu"); //$NON-NLS-1$
menuMgr.addMenuListener(manager -> handleMenuAboutToShow(manager));
pageSite.registerContextMenu(
"org.eclipse.linuxtools.docker.ui.BaseProperySection.menuid", //$NON-NLS-1$
menuMgr, treeViewer);
Menu menu = menuMgr.createContextMenu(treeViewer.getTree());
treeViewer.getTree().setMenu(menu);
menuMgr.add(copyAction);
configureCopy();
}
/**
* Configures the view copy action which should be run on CTRL+C. We have to
* track widget focus to select the actual action because we have a few
* widgets that should provide copy action (at least tests hierarchy viewer
* and messages viewer).
*/
private void configureCopy() {
getTreeViewer().getTree().addFocusListener(new FocusListener() {
IAction viewCopyHandler;
@Override
public void focusLost(FocusEvent e) {
if (viewCopyHandler != null) {
switchTo(viewCopyHandler);
}
}
@Override
public void focusGained(FocusEvent e) {
switchTo(copyAction);
}
private void switchTo(IAction copyAction) {
IActionBars actionBars = pageSite.getActionBars();
viewCopyHandler = actionBars
.getGlobalActionHandler(ActionFactory.COPY.getId());
actionBars.setGlobalActionHandler(ActionFactory.COPY.getId(),
copyAction);
actionBars.updateActionBars();
}
});
}
/**
* Handles the context menu showing.
*
* @param manager
* context menu manager
*/
private void handleMenuAboutToShow(
@SuppressWarnings("unused") IMenuManager manager) {
ISelection selection = treeViewer.getSelection();
copyAction.setEnabled(!selection.isEmpty());
}
@Override
public void dispose() {
super.dispose();
if (this.clipboard != null) {
this.clipboard.dispose();
}
}
}