package org.openlca.app.editors.graphical; import java.util.List; import org.eclipse.core.runtime.IProgressMonitor; import org.eclipse.draw2d.ConnectionRouter; import org.eclipse.gef.DefaultEditDomain; import org.eclipse.gef.GraphicalViewer; import org.eclipse.gef.commands.CommandStack; import org.eclipse.gef.editparts.ScalableRootEditPart; import org.eclipse.gef.editparts.ZoomManager; import org.eclipse.gef.ui.parts.GraphicalEditor; import org.eclipse.jface.dialogs.ProgressMonitorDialog; import org.eclipse.jface.viewers.ISelection; import org.eclipse.ui.IEditorInput; import org.eclipse.ui.IEditorSite; import org.eclipse.ui.IWorkbenchPart; import org.eclipse.ui.PartInitException; import org.eclipse.ui.views.contentoutline.IContentOutlinePage; import org.openlca.app.M; import org.openlca.app.db.Cache; import org.openlca.app.editors.graphical.layout.LayoutType; import org.openlca.app.editors.graphical.layout.NodeLayoutStore; import org.openlca.app.editors.graphical.model.Link; import org.openlca.app.editors.graphical.model.ProcessNode; import org.openlca.app.editors.graphical.model.ProductSystemNode; import org.openlca.app.editors.graphical.model.TreeConnectionRouter; import org.openlca.app.editors.graphical.outline.OutlinePage; import org.openlca.app.editors.graphical.search.MutableProcessLinkSearchMap; import org.openlca.app.editors.systems.ProductSystemEditor; import org.openlca.app.util.Labels; import org.openlca.app.util.Question; import org.openlca.app.util.UI; import org.openlca.core.model.ProcessLink; import org.openlca.core.model.descriptors.ProcessDescriptor; public class ProductSystemGraphEditor extends GraphicalEditor { public static final String ID = "editors.productsystem.graphical"; private ProductSystemEditor systemEditor; private ProductSystemNode model; private LayoutType layoutType = LayoutType.TREE_LAYOUT; private OutlinePage outline; private boolean routed; private GraphicalViewerConfigurator configurator; private ISelection selection; private List<String> actionIds; private boolean initialized = false; public ProductSystemGraphEditor(ProductSystemEditor editor) { this.systemEditor = editor; editor.onSaved(() -> NodeLayoutStore.saveLayout(getModel())); } public ProductSystemEditor getSystemEditor() { return systemEditor; } public void setDirty(boolean value) { systemEditor.setDirty(value); } @Override public boolean isDirty() { return systemEditor.isDirty(); } public ISelection getSelection() { return selection; } public void setInitialized(boolean initialized) { this.initialized = initialized; } public boolean isInitialized() { return initialized; } @Override public void init(IEditorSite site, IEditorInput input) throws PartInitException { setEditDomain(new DefaultEditDomain(this)); if (input instanceof GraphicalEditorInput) { GraphicalEditorInput modelInput = (GraphicalEditorInput) input; if (modelInput.getDescriptor() != null) { setPartName(Labels.getDisplayName(modelInput.getDescriptor())); } } super.init(site, input); } public boolean promptSaveIfNecessary() throws Exception { if (!isDirty()) return true; String question = M.SystemSaveProceedQuestion; if (Question.ask(M.Save + "?", question)) { new ProgressMonitorDialog(UI.shell()).run(false, false, (monitor) -> systemEditor.doSave(monitor)); return true; } return false; } private ProductSystemNode createModel() { if (getSystemEditor().getModel().getReferenceProcess() == null) return new ProductSystemNode(this); long referenceId = getSystemEditor().getModel().getReferenceProcess().getId(); ProductSystemNode productSystemNode = new ProductSystemNode(this); productSystemNode.add(createProcessNode(referenceId)); return productSystemNode; } private ProductSystemNode expandModel() { ProductSystemNode productSystemNode = new ProductSystemNode(this); for (Long id : getSystemEditor().getModel().getProcesses()) productSystemNode.add(createProcessNode(id)); return productSystemNode; } private ProcessNode createProcessNode(long id) { ProcessDescriptor descriptor = Cache.getEntityCache().get(ProcessDescriptor.class, id); ProcessNode processNode = new ProcessNode(descriptor); return processNode; } public void createNecessaryLinks(ProcessNode node) { MutableProcessLinkSearchMap linkSearch = node.parent().linkSearch; long id = node.process.getId(); for (ProcessLink link : linkSearch.getLinks(id)) { long processId = link.processId == id ? link.providerId : link.processId; ProcessNode otherNode = model.getProcessNode(processId); if (otherNode == null) continue; ProcessNode sourceNode = link.processId == id ? otherNode : node; ProcessNode targetNode = link.processId == id ? node : otherNode; if (!sourceNode.isExpandedRight() && !targetNode.isExpandedLeft()) continue; Link connectionLink = new Link(); connectionLink.sourceNode = sourceNode; connectionLink.targetNode = targetNode; connectionLink.processLink = link; connectionLink.link(); } } private GraphicalViewerConfigurator createGraphicalViewerConfigurator() { GraphicalViewerConfigurator configurator = new GraphicalViewerConfigurator(getGraphicalViewer()); configurator.setActionRegistry(getActionRegistry()); configurator.setCommandStack(getCommandStack()); configurator.setModel(model); return configurator; } @Override protected void configureGraphicalViewer() { model = createModel(); super.configureGraphicalViewer(); configurator = createGraphicalViewerConfigurator(); configurator.configureGraphicalViewer(); actionIds = configurator.configureActions(); configurator.configureKeyHandler(); configurator.configureContextMenu(); } @Override protected void initializeGraphicalViewer() { configurator.initializeGraphicalViewer(); configurator.configureZoomManager(); } @Override public GraphicalViewer getGraphicalViewer() { return super.getGraphicalViewer(); } @Override public void doSave(final IProgressMonitor monitor) { systemEditor.doSave(monitor); } public void updateModel(final IProgressMonitor monitor) { monitor.beginTask(M.UpdatingProductSystem, IProgressMonitor.UNKNOWN); systemEditor.updateModel(); monitor.done(); } @Override @SuppressWarnings("rawtypes") public Object getAdapter(final Class type) { if (type == ZoomManager.class) return ((ScalableRootEditPart) getGraphicalViewer().getRootEditPart()).getZoomManager(); if (type == IContentOutlinePage.class) { outline = new OutlinePage(model); outline.setEditDomain(getEditDomain()); outline.setSelectionSynchronizer(getSelectionSynchronizer()); return outline; } return super.getAdapter(type); } @Override public CommandStack getCommandStack() { CommandStack stack = super.getCommandStack(); if (stack == null) stack = new CommandStack(); return stack; } public LayoutType getLayoutType() { return layoutType; } public ProductSystemNode getModel() { return model; } public OutlinePage getOutline() { return outline; } public ZoomManager getZoomManager() { return getRootEditPart().getZoomManager(); } private ScalableRootEditPart getRootEditPart() { return (ScalableRootEditPart) getGraphicalViewer().getRootEditPart(); } @Override public boolean isSaveAsAllowed() { return false; } public void expand() { model = expandModel(); if (getGraphicalViewer() != null) { getGraphicalViewer().deselectAll(); getGraphicalViewer().setContents(model); for (ProcessNode node : model.getChildren()) { node.expandLeft(); node.expandRight(); } } } public void collapse() { model = createModel(); if (getGraphicalViewer() != null) { getGraphicalViewer().deselectAll(); getGraphicalViewer().setContents(model); } } @Override public void selectionChanged(IWorkbenchPart part, ISelection selection) { this.selection = selection; updateActions(actionIds); } @Override public void setFocus() { if (getGraphicalViewer() == null) return; if (getGraphicalViewer().getControl() == null) return; super.setFocus(); } public boolean isRouted() { return routed; } public void setRouted(boolean routed) { this.routed = routed; ConnectionRouter router = ConnectionRouter.NULL; if (routed) router = TreeConnectionRouter.instance; for (ProcessNode node : model.getChildren()) for (Link link : node.links) link.figure.setConnectionRouter(router); } }