]> gerrit.simantics Code Review - simantics/district.git/blob - org.simantics.district.region.ui/src/org/simantics/district/region/ui/handlers/ZoomToRegionHandler.java
7a1e105bee7599f6f8483e0c99de45600ced8b6f
[simantics/district.git] / org.simantics.district.region.ui / src / org / simantics / district / region / ui / handlers / ZoomToRegionHandler.java
1 package org.simantics.district.region.ui.handlers;
2
3 import java.awt.Shape;
4 import java.util.HashSet;
5 import java.util.List;
6 import java.util.Objects;
7 import java.util.Set;
8 import java.util.stream.Collectors;
9
10 import javax.inject.Named;
11
12 import org.eclipse.e4.core.di.annotations.CanExecute;
13 import org.eclipse.e4.core.di.annotations.Execute;
14 import org.eclipse.e4.ui.model.application.ui.basic.MPart;
15 import org.eclipse.e4.ui.services.IServiceConstants;
16 import org.eclipse.jface.viewers.ISelection;
17 import org.eclipse.swt.widgets.Control;
18 import org.eclipse.swt.widgets.Display;
19 import org.eclipse.swt.widgets.Shell;
20 import org.eclipse.ui.IEditorPart;
21 import org.eclipse.ui.IWorkbenchPart;
22 import org.simantics.Simantics;
23 import org.simantics.db.ReadGraph;
24 import org.simantics.db.Resource;
25 import org.simantics.db.common.request.ReadRequest;
26 import org.simantics.db.common.request.UniqueRead;
27 import org.simantics.db.exception.DatabaseException;
28 import org.simantics.district.region.DiagramRegions;
29 import org.simantics.district.region.DiagramRegions.DiagramRegion;
30 import org.simantics.g2d.canvas.ICanvasContext;
31 import org.simantics.g2d.diagram.IDiagram;
32 import org.simantics.g2d.diagram.handler.PickRequest;
33 import org.simantics.g2d.diagram.handler.impl.PickContextImpl;
34 import org.simantics.g2d.element.ElementHints;
35 import org.simantics.g2d.element.IElement;
36 import org.simantics.modeling.actions.NavigateToTarget;
37 import org.simantics.ui.workbench.action.DefaultActions;
38 import org.simantics.utils.threads.ThreadUtils;
39 import org.simantics.utils.ui.ISelectionUtils;
40 import org.simantics.utils.ui.workbench.WorkbenchUtils;
41 import org.slf4j.Logger;
42 import org.slf4j.LoggerFactory;
43
44 public class ZoomToRegionHandler {
45
46     private static final Logger LOGGER = LoggerFactory.getLogger(ZoomToRegionHandler.class);
47     public static final String COMMAND_ID = "org.simantics.district.region.ui.commands.zoomToRegion";
48     public static final String LABEL = "Zoom To Region";
49     
50     @CanExecute
51     public boolean canExecute() {
52         return true;
53     }
54     
55     @Execute
56     public void execute(@Named(IServiceConstants.ACTIVE_SHELL) Shell activeShell,
57             @Named(IServiceConstants.ACTIVE_PART) MPart part,
58             @Named(IServiceConstants.ACTIVE_SELECTION) ISelection selection) {
59         DiagramRegion region = ISelectionUtils.filterSingleSelection(selection, DiagramRegion.class);
60         zoomTo((Control) part.getWidget(), activeShell.getDisplay(), region.getResource());
61     }
62
63     public static void zoomTo(Control control, Display display, Resource region) {
64         Resource dia;
65         try {
66             dia = Simantics.getSession().syncRequest(new UniqueRead<Resource>() {
67                 
68                 @Override
69                 public Resource perform(ReadGraph graph) throws DatabaseException {
70                     return DiagramRegions.getDiagramForRegion(graph, region);
71                 }
72             });
73             
74             // get currentyl active workbench part
75             IWorkbenchPart beforePerformingDefaultAction = WorkbenchUtils.getActiveWorkbenchPart();
76             IEditorPart activeEditor = WorkbenchUtils.getActiveEditor();
77             LOGGER.info("activeWorkbenchPart {}", beforePerformingDefaultAction);
78             LOGGER.info("activeEditor {}", activeEditor);
79             DefaultActions.performDefaultAction(control, dia);
80             Simantics.getSession().asyncRequest(new ReadRequest() {
81                 
82                 @Override
83                 public void run(ReadGraph graph) throws DatabaseException {
84                     Shape shp = DiagramRegions.coordinatesToShape(graph, region);
85                     display.asyncExec(() -> {
86                         IWorkbenchPart afterPerformingDefaultAction = WorkbenchUtils.getActiveWorkbenchPart();
87                         LOGGER.info("afterActiveWorkbenchPart {}", afterPerformingDefaultAction);
88                         int tries = 0;
89                         while (Objects.equals(beforePerformingDefaultAction, afterPerformingDefaultAction) && tries <= 10) {
90                             try {
91                                 Thread.sleep(150);
92                             } catch (InterruptedException e) {
93                                 LOGGER.error("Could not sleep", e);
94                             }
95                             afterPerformingDefaultAction = WorkbenchUtils.getActiveEditor();
96                             LOGGER.info("afterActiveWorkbenchPart {}", afterPerformingDefaultAction);
97                             tries++;
98                         }
99                         LOGGER.info("afterActiveWorkbenchPart {}", afterPerformingDefaultAction);
100                         if (beforePerformingDefaultAction.equals(afterPerformingDefaultAction)) {
101                             LOGGER.warn("No can do");
102                         } else if (afterPerformingDefaultAction != null) {
103                             // Okay, get the IDiagram now
104                             IDiagram diagram = afterPerformingDefaultAction.getAdapter(IDiagram.class);
105                             if (diagram == null)
106                                 LOGGER.warn("No can do - no IDiagram available");
107                             else {
108                                 Set<IElement> elems = new HashSet<>();
109                                 PickContextImpl.INSTANCE.pick(diagram, new PickRequest(shp), elems);
110                                 ICanvasContext context = afterPerformingDefaultAction.getAdapter(ICanvasContext.class);
111                                 List<Object> collect = elems.stream().map(el -> el.getHint(ElementHints.KEY_OBJECT)).collect(Collectors.toList());
112                                 ThreadUtils.asyncExec(context.getThreadAccess(), NavigateToTarget.elementSelectorZoomer(context, collect, false));
113                             }
114                         } else {
115                             LOGGER.info("afterPerforming is null");
116                         }
117                     });
118                 }
119             });
120         } catch (DatabaseException e) {
121             LOGGER.error("Could not zoom to region", e);
122         }
123     }
124 }