X-Git-Url: https://gerrit.simantics.org/r/gitweb?a=blobdiff_plain;f=org.simantics.district.selection.ui%2Fsrc%2Forg%2Fsimantics%2Fdistrict%2Fselection%2Fui%2Fparts%2FElementSelectionView.java;h=31d1c6e3b7a64ad915551dec6a46e95714989d47;hb=5618901b005fe275d5218e6c5e8243941f9a1e2f;hp=1cddde9f7034c62c2c37c4ce186a375707f4f78b;hpb=09b78f5c26bb8b521beb6eeeb5c3f44ac1aa4d07;p=simantics%2Fdistrict.git diff --git a/org.simantics.district.selection.ui/src/org/simantics/district/selection/ui/parts/ElementSelectionView.java b/org.simantics.district.selection.ui/src/org/simantics/district/selection/ui/parts/ElementSelectionView.java index 1cddde9f..31d1c6e3 100644 --- a/org.simantics.district.selection.ui/src/org/simantics/district/selection/ui/parts/ElementSelectionView.java +++ b/org.simantics.district.selection.ui/src/org/simantics/district/selection/ui/parts/ElementSelectionView.java @@ -1,10 +1,18 @@ package org.simantics.district.selection.ui.parts; +import java.awt.Color; +import java.util.ArrayList; +import java.util.Collection; +import java.util.Collections; +import java.util.HashMap; import java.util.List; +import java.util.Map; +import java.util.Map.Entry; import javax.annotation.PostConstruct; import javax.inject.Inject; +import org.eclipse.e4.core.services.events.IEventBroker; import org.eclipse.e4.ui.di.Focus; import org.eclipse.e4.ui.model.application.MApplication; import org.eclipse.e4.ui.model.application.ui.basic.MPart; @@ -16,10 +24,29 @@ import org.eclipse.e4.ui.model.application.ui.menu.MToolBar; import org.eclipse.e4.ui.model.application.ui.menu.MToolBarElement; import org.eclipse.e4.ui.services.EMenuService; import org.eclipse.e4.ui.workbench.modeling.ESelectionService; +import org.eclipse.jface.dialogs.MessageDialog; +import org.eclipse.jface.viewers.StructuredSelection; import org.eclipse.swt.SWT; import org.eclipse.swt.widgets.Composite; +import org.eclipse.swt.widgets.Display; +import org.simantics.Simantics; +import org.simantics.browsing.ui.common.AdaptableHintContext; +import org.simantics.db.ReadGraph; +import org.simantics.db.Resource; +import org.simantics.db.exception.DatabaseException; +import org.simantics.db.layer0.SelectionHints; +import org.simantics.db.layer0.request.ActiveModels; +import org.simantics.db.request.Read; +import org.simantics.district.network.ui.DistrictNetworkUIUtil; +import org.simantics.district.network.ui.participants.DistrictFinderVisualisationParticipant; import org.simantics.district.selection.ElementSelector; +import org.simantics.district.selection.ElementSelector.DiagramGenerator; +import org.simantics.district.selection.ElementSelector.ExplicitGenerator; +import org.simantics.district.selection.ElementSelector.PropertySelector; +import org.simantics.district.selection.ElementSelector.SelectionResult; +import org.simantics.district.selection.ui.ElementSelectionTools; import org.simantics.district.selection.ui.ElementSelectorTableUI; +import org.simantics.scl.runtime.tuple.Tuple2; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -35,6 +62,12 @@ public class ElementSelectionView { private static final String DELETE_ID = "org.simantics.district.selection.ui.command.deleteElementSelector"; private static final String DELETE_LABEL = "Delete Element Selection Query"; private static final String DELETE_ICON = "platform:/plugin/com.famfamfam.silk/icons/cross.png"; + + /** + * Name of an event that is posted to IEventBroker when a selection is made. The data value is + * an instance of Collection<Resource>. + */ + public static final String SELECTION_EVENT_ID = "org/simantics/district/selection/elementQuerySelection"; private static final Logger LOGGER = LoggerFactory.getLogger(ElementSelectionView.class); @@ -42,7 +75,10 @@ public class ElementSelectionView { @Inject private ESelectionService selectionService; - + + @Inject + private IEventBroker eventBroker; + @Inject public void init(MPart part, MApplication app) { // Command is contributed via fragment @@ -84,8 +120,8 @@ public class ElementSelectionView { @PostConstruct public void createPartControl(Composite parent, EMenuService menuService) { - table = new ElementSelectorTableUI(selectionService, parent, SWT.BORDER); - if (!(menuService.registerContextMenu(this.table.getTree(), POPUP_ID))) + table = new ElementSelectorTableUI(parent, SWT.BORDER, this); + if (!(menuService.registerContextMenu(this.table.getTable(), POPUP_ID))) LOGGER.warn("Could not register context menu {}", POPUP_ID); } @@ -93,8 +129,101 @@ public class ElementSelectionView { public void setFocus() { table.setFocus(); } - + public ElementSelector getSelectedItem() { return table.getSelectedItem(); } + + private Map resultCache = new HashMap<>(); + + public void performSelection(Display display, ElementSelector query) { + try { + Collection models = Simantics.getSession().syncRequest(new ActiveModels(Simantics.getProjectResource())); + final Resource model = models.isEmpty() ? null : models.iterator().next(); + + Tuple2 selectionResult = resultCache.get(query); + if (selectionResult != null) { + // clear existing result and visualisation + clearResultVisualisation(query); + } + + SelectionResult result = performQuery(query, model); + + resultCache.put(query, new Tuple2(result, model)); + + if (result.tailCount != result.tailSize) { + showArbitraryResultWarning(query, result); + } + + if (query.getGenerator() instanceof DiagramGenerator || query.getGenerator() instanceof ExplicitGenerator) { + openDiagramWithSelection(display, result); + } + + StructuredSelection selection = makeSelection(model, result, query.getColor()); + selectionService.setPostSelection(selection); + sendSelectionEvent(selection); + } catch (DatabaseException e) { + LOGGER.error("Element selection query failed", e); + } + } + + public void clearResultVisualisation(ElementSelector query) { + Tuple2 selectionResult = resultCache.get(query); + if (selectionResult != null) { + SelectionResult result = (SelectionResult) selectionResult.c0; + Resource model = (Resource) selectionResult.c1; + eventBroker.send(SELECTION_EVENT_ID, makeSelection(model, result, null)); + } + } + + private StructuredSelection makeSelection(final Resource model, SelectionResult result, float[] fs) { + return new StructuredSelection(result.elements.stream() + .map(p0 -> { + AdaptableHintContext selectionElement = new ElementSelectionTools.SelectionElement(SelectionHints.STD_KEYS); + selectionElement.setHint(SelectionHints.KEY_MAIN, p0); + selectionElement.setHint(SelectionHints.KEY_MODEL, model); + if (fs != null) { + selectionElement.setHint(DistrictFinderVisualisationParticipant.COLOR_KEY, new Color(fs[2], fs[1], fs[0], fs[3])); + } + return selectionElement; + }) + .toArray()); + } + + private void openDiagramWithSelection(Display display, SelectionResult result) throws DatabaseException { + DistrictNetworkUIUtil.openDNDiagramWithSelection(display, new ArrayList<>(result.elements)); + } + + private void sendSelectionEvent(Object selection) { + eventBroker.send(SELECTION_EVENT_ID, selection); + } + + private void showArbitraryResultWarning(ElementSelector query, SelectionResult result) { + String name = query.getSelector() != null && query.getSelector() instanceof PropertySelector ? ((PropertySelector)query.getSelector()).propertyName : null; + String msg = "Last " + result.tailCount + " of the " + result.elements.size() + " selected elements are an arbitraty subset of " + result.tailSize + " elements with equal values" + + (name != null ? " for " + name : ""); + MessageDialog.openInformation(Display.getDefault().getActiveShell(), "Note", msg); + } + + private SelectionResult performQuery(ElementSelector query, final Resource model) throws DatabaseException { + SelectionResult result = Simantics.getSession().syncRequest(new Read() { + @Override + public SelectionResult perform(ReadGraph graph) throws DatabaseException { + if (model == null) { + LOGGER.warn("No active model"); + return new SelectionResult(Collections.emptyList(), 0, 0); + } + + return query.selectElementsFrom(graph, model); + } + }); + return result; + } + + public void dispose() { + for (Entry entry : resultCache.entrySet()) { + ElementSelector query = entry.getKey(); + clearResultVisualisation(query); + } + } }