package org.simantics.district.region.ui.handlers; import java.awt.Shape; import java.util.HashSet; import java.util.List; import java.util.Objects; import java.util.Set; import java.util.stream.Collectors; import javax.inject.Named; import org.eclipse.e4.core.di.annotations.CanExecute; import org.eclipse.e4.core.di.annotations.Execute; import org.eclipse.e4.ui.model.application.ui.basic.MPart; import org.eclipse.e4.ui.services.IServiceConstants; import org.eclipse.jface.viewers.ISelection; import org.eclipse.swt.widgets.Control; import org.eclipse.swt.widgets.Display; import org.eclipse.swt.widgets.Shell; import org.eclipse.ui.IEditorPart; import org.eclipse.ui.IWorkbenchPart; import org.simantics.Simantics; import org.simantics.db.ReadGraph; import org.simantics.db.Resource; import org.simantics.db.common.request.ReadRequest; import org.simantics.db.common.request.UniqueRead; import org.simantics.db.exception.DatabaseException; import org.simantics.district.region.DiagramRegions; import org.simantics.district.region.DiagramRegions.DiagramRegion; import org.simantics.g2d.canvas.ICanvasContext; import org.simantics.g2d.diagram.IDiagram; import org.simantics.g2d.diagram.handler.PickRequest; import org.simantics.g2d.diagram.handler.impl.PickContextImpl; import org.simantics.g2d.element.ElementHints; import org.simantics.g2d.element.IElement; import org.simantics.modeling.actions.NavigateToTarget; import org.simantics.ui.workbench.action.DefaultActions; import org.simantics.utils.threads.ThreadUtils; import org.simantics.utils.ui.ISelectionUtils; import org.simantics.utils.ui.workbench.WorkbenchUtils; import org.slf4j.Logger; import org.slf4j.LoggerFactory; public class ZoomToRegionHandler { private static final Logger LOGGER = LoggerFactory.getLogger(ZoomToRegionHandler.class); public static final String COMMAND_ID = "org.simantics.district.region.ui.commands.zoomToRegion"; public static final String LABEL = "Zoom To Region"; @CanExecute public boolean canExecute() { return true; } @Execute public void execute(@Named(IServiceConstants.ACTIVE_SHELL) Shell activeShell, @Named(IServiceConstants.ACTIVE_PART) MPart part, @Named(IServiceConstants.ACTIVE_SELECTION) ISelection selection) { DiagramRegion region = ISelectionUtils.filterSingleSelection(selection, DiagramRegion.class); zoomTo((Control) part.getWidget(), activeShell.getDisplay(), region.getResource()); } public static void zoomTo(Control control, Display display, Resource region) { Resource dia; try { dia = Simantics.getSession().syncRequest(new UniqueRead() { @Override public Resource perform(ReadGraph graph) throws DatabaseException { return DiagramRegions.getDiagramForRegion(graph, region); } }); // get currently active workbench part IWorkbenchPart beforePerformingDefaultAction = WorkbenchUtils.getActiveWorkbenchPart(); IEditorPart activeEditor = WorkbenchUtils.getActiveEditor(); LOGGER.info("activeWorkbenchPart {}", beforePerformingDefaultAction); LOGGER.info("activeEditor {}", activeEditor); DefaultActions.performDefaultAction(control, dia); Simantics.getSession().asyncRequest(new ReadRequest() { @Override public void run(ReadGraph graph) throws DatabaseException { Shape shp = DiagramRegions.coordinatesToShape(graph, region); display.asyncExec(() -> { IWorkbenchPart afterPerformingDefaultAction = WorkbenchUtils.getActiveWorkbenchPart(); LOGGER.info("afterActiveWorkbenchPart {}", afterPerformingDefaultAction); int tries = 0; while (Objects.equals(beforePerformingDefaultAction, afterPerformingDefaultAction) && tries <= 10) { try { Thread.sleep(150); } catch (InterruptedException e) { LOGGER.error("Could not sleep", e); } afterPerformingDefaultAction = WorkbenchUtils.getActiveEditor(); LOGGER.info("afterActiveWorkbenchPart {}", afterPerformingDefaultAction); tries++; } LOGGER.info("afterActiveWorkbenchPart {}", afterPerformingDefaultAction); if (beforePerformingDefaultAction.equals(afterPerformingDefaultAction)) { LOGGER.warn("No can do"); } else if (afterPerformingDefaultAction != null) { // Okay, get the IDiagram now IDiagram diagram = afterPerformingDefaultAction.getAdapter(IDiagram.class); if (diagram == null) LOGGER.warn("No can do - no IDiagram available"); else { Set elems = new HashSet<>(); PickContextImpl.INSTANCE.pick(diagram, new PickRequest(shp), elems); ICanvasContext context = afterPerformingDefaultAction.getAdapter(ICanvasContext.class); List collect = elems.stream().map(el -> el.getHint(ElementHints.KEY_OBJECT)).collect(Collectors.toList()); ThreadUtils.asyncExec(context.getThreadAccess(), NavigateToTarget.elementSelectorZoomer(context, collect, false)); } } else { LOGGER.info("afterPerforming is null"); } }); } }); } catch (DatabaseException e) { LOGGER.error("Could not zoom to region", e); } } }