package au.gov.ga.earthsci.catalog.ui; import java.util.List; import javax.annotation.PostConstruct; import javax.annotation.PreDestroy; import javax.inject.Inject; import javax.inject.Named; import org.eclipse.core.databinding.beans.BeanProperties; import org.eclipse.core.databinding.beans.IBeanListProperty; import org.eclipse.core.databinding.observable.list.IObservableList; import org.eclipse.core.databinding.observable.masterdetail.IObservableFactory; import org.eclipse.core.runtime.IStatus; import org.eclipse.core.runtime.Status; import org.eclipse.e4.core.contexts.IEclipseContext; import org.eclipse.e4.core.di.annotations.Optional; import org.eclipse.e4.ui.model.application.ui.basic.MPart; import org.eclipse.e4.ui.services.EMenuService; import org.eclipse.e4.ui.services.IServiceConstants; import org.eclipse.e4.ui.workbench.modeling.ESelectionService; import org.eclipse.jface.viewers.DecoratingStyledCellLabelProvider; import org.eclipse.jface.viewers.ISelectionChangedListener; import org.eclipse.jface.viewers.IStructuredSelection; import org.eclipse.jface.viewers.SelectionChangedEvent; import org.eclipse.jface.viewers.StructuredSelection; import org.eclipse.jface.viewers.TreeViewer; import org.eclipse.swt.SWT; import org.eclipse.swt.dnd.DND; import org.eclipse.swt.dnd.FileTransfer; import org.eclipse.swt.dnd.Transfer; import org.eclipse.swt.events.SelectionAdapter; import org.eclipse.swt.events.SelectionEvent; import org.eclipse.swt.widgets.Composite; import au.gov.ga.earthsci.application.Activator; import au.gov.ga.earthsci.application.tree.LazyObservableListTreeContentProvider; import au.gov.ga.earthsci.catalog.ErrorCatalogTreeNode; import au.gov.ga.earthsci.catalog.ICatalogModel; import au.gov.ga.earthsci.catalog.ICatalogTreeNode; import au.gov.ga.earthsci.common.databinding.ObservableListTreeSupport; import au.gov.ga.earthsci.common.databinding.TreeChangeAdapter; import au.gov.ga.earthsci.common.ui.dialogs.StackTraceDialog; import au.gov.ga.earthsci.common.ui.viewers.ControlTreeViewer; import au.gov.ga.earthsci.layer.ui.dnd.LayerTransfer; /** * A part that renders a tree-view of the current {@link ICatalogModel} and * allows the user to browse and interact with elements in the model. * * @author James Navin (james.navin@ga.gov.au) */ public class CatalogBrowserPart { private TreeViewer viewer; @Inject private ICatalogModel model; @Inject private CatalogTreeLabelProvider labelProvider; @Inject private IEclipseContext context; @Inject private ICatalogBrowserController controller; @Inject private ESelectionService selectionService; private boolean settingSelection = false; private ObservableListTreeSupport<ICatalogTreeNode> observableListTreeSupport; @PostConstruct public void init(final Composite parent, final MPart part, final EMenuService menuService) { initViewer(parent, part, menuService); } @PreDestroy private void packup() { observableListTreeSupport.dispose(); labelProvider.dispose(); } private void initViewer(final Composite parent, final MPart part, final EMenuService menuService) { viewer = new ControlTreeViewer(parent, SWT.MULTI); viewer.setLabelProvider(new DecoratingStyledCellLabelProvider(labelProvider, labelProvider, null)); viewer.setSorter(null); IBeanListProperty<ICatalogTreeNode, ICatalogTreeNode> childrenProperty = BeanProperties.list(ICatalogTreeNode.class, "children", ICatalogTreeNode.class); //$NON-NLS-1$ IObservableFactory<ICatalogTreeNode, IObservableList<ICatalogTreeNode>> listFactory = childrenProperty.listFactory(); LazyObservableListTreeContentProvider<ICatalogTreeNode> contentProvider = new LazyObservableListTreeContentProvider<ICatalogTreeNode>(listFactory, null); viewer.setContentProvider(contentProvider); observableListTreeSupport = new ObservableListTreeSupport<ICatalogTreeNode>(listFactory); observableListTreeSupport.addListener(new TreeChangeAdapter<ICatalogTreeNode>() { @Override public void elementAdded(ICatalogTreeNode element) { if (element.isRoot() || element.getParent().isRoot()) { viewer.expandToLevel(element, 1); } } }); viewer.setInput(model.getRoot()); observableListTreeSupport.setInput(model.getRoot()); viewer.addDropSupport(DND.DROP_DEFAULT | DND.DROP_COPY | DND.DROP_MOVE, new Transfer[] { FileTransfer.getInstance() }, new CatalogTreeDropAdapter(viewer, model, context)); viewer.addDragSupport(DND.DROP_DEFAULT | DND.DROP_COPY, new Transfer[] { LayerTransfer.getInstance() }, new CatalogTreeDragSourceListener(viewer, controller)); viewer.addSelectionChangedListener(new ISelectionChangedListener() { @Override public void selectionChanged(SelectionChangedEvent event) { IStructuredSelection selection = (IStructuredSelection) viewer.getSelection(); List<?> list = selection.toList(); ICatalogTreeNode[] array; try { array = list.toArray(new ICatalogTreeNode[list.size()]); } catch (ArrayStoreException e) { //occurs when the selection contains a loading node, which is not an ICatalogTreeNode array = new ICatalogTreeNode[0]; } settingSelection = true; selectionService.setSelection(array); settingSelection = false; } }); viewer.getTree().addSelectionListener(new SelectionAdapter() { @Override public void widgetDefaultSelected(SelectionEvent e) { IStructuredSelection selection = (IStructuredSelection) viewer.getSelection(); ICatalogTreeNode firstElement = (ICatalogTreeNode) selection.getFirstElement(); if (firstElement != null) { selectNode(firstElement); } } }); menuService.registerContextMenu(viewer.getTree(), "au.gov.ga.earthsci.application.catalogbrowser.popupmenu"); //$NON-NLS-1$ } private void selectNode(ICatalogTreeNode node) { if (node instanceof ErrorCatalogTreeNode) { ErrorCatalogTreeNode errorNode = (ErrorCatalogTreeNode) node; IStatus status = new Status(IStatus.ERROR, Activator.getBundleName(), errorNode.getMessage(), errorNode.getError()); StackTraceDialog.openError(viewer.getTree().getShell(), Messages.CatalogBrowserPart_ErrorDialogTitle, null, status); } else if (node.isLayerNode()) { controller.addToLayerModel(node); } viewer.expandToLevel(node, 1); } public TreeViewer getTreeViewer() { return viewer; } public CatalogTreeLabelProvider getLabelProvider() { return labelProvider; } @Inject private void select(@Optional @Named(IServiceConstants.ACTIVE_SELECTION) ICatalogTreeNode[] nodes) { if (nodes == null || viewer == null || settingSelection) { return; } StructuredSelection selection = new StructuredSelection(nodes); viewer.setSelection(selection, true); for (ICatalogTreeNode node : nodes) { viewer.expandToLevel(node, 1); } } @Inject private void select(@Optional @Named(IServiceConstants.ACTIVE_SELECTION) ICatalogTreeNode node) { if (node == null) { return; } select(new ICatalogTreeNode[] { node }); } }