import java.util.List;
import org.eclipse.e4.ui.workbench.modeling.ESelectionService;
+import org.eclipse.jface.dialogs.MessageDialog;
import org.eclipse.jface.viewers.ColumnLabelProvider;
import org.eclipse.jface.viewers.ColumnViewerToolTipSupport;
import org.eclipse.jface.viewers.DoubleClickEvent;
import org.eclipse.swt.graphics.Image;
import org.eclipse.swt.layout.FillLayout;
import org.eclipse.swt.widgets.Composite;
+import org.eclipse.swt.widgets.Display;
import org.eclipse.swt.widgets.Tree;
import org.simantics.Simantics;
import org.simantics.browsing.ui.common.AdaptableHintContext;
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.layer0.Layer0;
-import org.simantics.scl.runtime.Lists;
-import org.simantics.scl.runtime.function.FunctionImpl1;
import org.simantics.ui.selection.AnyResource;
import org.simantics.ui.selection.AnyVariable;
import org.simantics.ui.selection.WorkbenchSelectionContentType;
TreeSelection selection = (TreeSelection) event.getViewer().getSelection();
ElementSelector query = (ElementSelector) selection.getFirstElement();
try {
- List<Resource> result = Simantics.getSession().syncRequest(new Read<List<Resource>>() {
+ SelectionResult result = Simantics.getSession().syncRequest(new Read<SelectionResult>() {
@Override
- public List<Resource> perform(ReadGraph graph) throws DatabaseException {
+ public SelectionResult perform(ReadGraph graph) throws DatabaseException {
model = ActiveModels.getPossibleActiveModel(graph, Simantics.getProjectResource());
if (model == null) {
LOGGER.warn("No active model");
- return Collections.emptyList();
+ return new SelectionResult(Collections.emptyList(), 0, 0);
}
return query.selectElementsFrom(graph, model);
});
if (query.getGenerator() instanceof DiagramGenerator || query.getGenerator() instanceof ExplicitGenerator) {
- DistrictNetworkUIUtil.openDNDiagramWithSelection(event.getViewer().getControl().getDisplay(), result);
+ DistrictNetworkUIUtil.openDNDiagramWithSelection(event.getViewer().getControl().getDisplay(), new ArrayList<>(result.elements));
}
else {
- selectionService.setPostSelection(new StructuredSelection(Lists.map(new FunctionImpl1<Resource, AdaptableHintContext>() {
- public AdaptableHintContext apply(Resource p0) {
- AdaptableHintContext selectionElement = new SelectionElement(SelectionHints.STD_KEYS);
- selectionElement.setHint(SelectionHints.KEY_MAIN, p0);
- selectionElement.setHint(SelectionHints.KEY_MODEL, model);
- return selectionElement;
- }
- }, result)));
+ selectionService.setPostSelection(new StructuredSelection(result.elements.stream()
+ .map(p0 -> {
+ AdaptableHintContext selectionElement = new SelectionElement(SelectionHints.STD_KEYS);
+ selectionElement.setHint(SelectionHints.KEY_MAIN, p0);
+ selectionElement.setHint(SelectionHints.KEY_MODEL, model);
+ return selectionElement;
+ })
+ .toArray()));
+ }
+
+ if (result.tailCount != result.tailSize) {
+ 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);
}
} catch (DatabaseException e) {
LOGGER.error("Element selection query failed", e);
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
+import java.util.Comparator;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
+import java.util.stream.Collectors;
import org.simantics.Simantics;
import org.simantics.db.ReadGraph;
import org.simantics.district.selection.ElementSelector.AggregateCondition.Type;
import org.simantics.layer0.Layer0;
import org.simantics.modeling.ModelingResources;
-import org.simantics.scl.runtime.Lists;
-import org.simantics.scl.runtime.function.FunctionImpl1;
-import org.simantics.scl.runtime.tuple.Tuple2;
import org.simantics.structural.stubs.StructuralResource2;
+import org.simantics.utils.datastructures.Pair;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
return null;
}
- public List<Resource> selectElementsFrom(ReadGraph graph, Resource model) throws DatabaseException {
+ public SelectionResult selectElementsFrom(ReadGraph graph, Resource model) throws DatabaseException {
if (selector == null) {
buildSelection(graph);
}
- Collection<Resource> result = gather(graph, model);
- return result instanceof List ? (List<Resource>) result : new ArrayList<>(result);
+ return gather(graph, model);
}
private static Generator buildGenerator(ReadGraph graph, Resource resource) throws DatabaseException {
return result;
}
- private Collection<Resource> gather(ReadGraph graph, Resource model) throws DatabaseException {
+ private SelectionResult gather(ReadGraph graph, Resource model) throws DatabaseException {
return selector.select(graph, filterElementsFrom(graph, generator.generate(graph, model)));
}
Collection<Resource> generate(ReadGraph graph, Resource model) throws DatabaseException {
Resource conf = graph.syncRequest(new Configuration(model));
- ArrayList<Resource> result = new ArrayList<>();
+ HashMap<Resource, Resource> fromMapped = new HashMap<Resource, Resource>();
// Iterate over diagrams
+ // Each model element is represented by the corresponding mapping element, if present
for (Resource comp : graph.getObjects(conf, L0.ConsistsOf)) {
if (!graph.isInstanceOf(comp, STR.Composite)) continue;
Resource diagram = graph.getPossibleObject(comp, MOD.CompositeToDiagram);
- if (diagram != null) result.addAll(elementsOfDiagram(graph, diagram));
+ if (diagram != null) {
+ for (Resource elem : elementsOfDiagram(graph, diagram)) {
+ Resource mapped = graph.getPossibleObject(elem, DN.MappedComponent);
+ if (mapped != null) {
+ fromMapped.put(mapped, elem);
+ }
+ else if (!fromMapped.containsKey(elem)) {
+ fromMapped.put(elem, elem);
+ }
+ }
+ }
}
- return result;
+ return new ArrayList<>(fromMapped.values());
}
}
// Selectors
+ public static class SelectionResult {
+ public final Collection<Resource> elements;
+ public final int tailCount;
+ public final int tailSize;
+
+ public SelectionResult(Collection<Resource> elements, int tailCount, int tailSize) {
+ this.elements = elements;
+ this.tailCount = tailCount;
+ this.tailSize = tailSize;
+ }
+ }
+
public static abstract class Selector {
- abstract Collection<Resource> select(ReadGraph graph, Collection<Resource> elements);
+ abstract SelectionResult select(ReadGraph graph, Collection<Resource> elements);
}
public static class All extends Selector {
}
@Override
- Collection<Resource> select(ReadGraph graph, Collection<Resource> elements) {
- return elements;
+ SelectionResult select(ReadGraph graph, Collection<Resource> elements) {
+ return new SelectionResult(elements, 0, 0);
}
}
public String propertyName;
public int resultCount;
- @SuppressWarnings("unchecked")
@Override
- Collection<Resource> select(ReadGraph graph, Collection<Resource> elements) {
- List<Tuple2> result2 = Lists.map(new FunctionImpl1<Resource, Tuple2>() {
- @Override
- public Tuple2 apply(Resource r) {
- return new Tuple2(r, getPropertyValue(graph, r, propertyName));
- }
- }, new ArrayList<>(elements));
+ SelectionResult select(ReadGraph graph, Collection<Resource> elements) {
+ // Select sorting direction
+ Comparator<Pair<Resource, Double>> comparator = smallest ?
+ (p1, p2) -> Double.compare(p1.second, p2.second) :
+ (p1, p2) -> Double.compare(p1.second, p2.second);
- result2 = Lists.filter(new FunctionImpl1<Tuple2, Boolean>() {
- @Override
- public Boolean apply(Tuple2 t) {
- return t.c1 != null;
- }
- }, result2);
+ // Get association list to property values
+ List<Pair<Resource, Double>> result2 = elements.stream()
+ .map(r -> Pair.make(r, getPropertyValue(graph, r, propertyName)))
+ .filter(t -> t.second != null)
+ .sorted(comparator)
+ .collect(Collectors.toList());
+ int count = Math.min(resultCount, result2.size());
- result2.sort((t1, t2) -> smallest ? Double.compare((Double) t1.c1, (Double) t2.c1) : Double.compare((Double) t2.c1, (Double) t1.c1));
+ // Count number of equal values at the end of the list
+ int tailCount = 0;
+ double tailValue = count > 0 ? result2.get(count-1).second : 0.0;
+ for (int i = count-1; i >= 0; i--) {
+ if (result2.get(i).second == tailValue)
+ tailCount++;
+ else
+ break;
+ }
- if (resultCount < result2.size()) {
- double limitValue = (double) result2.get(resultCount-1).c1;
-
- // Expand selection to contain all items with the same value as the nth one
- int count = resultCount;
- while (count < result2.size() && (double)result2.get(count).c1 == limitValue) count++;
- result2 = result2.subList(0, count);
+ // Count number of elements with value equal to the end of the list
+ int tailSize = tailCount;
+ for (int i = count; i < result2.size(); i++) {
+ if (result2.get(i).second == tailValue)
+ tailSize++;
+ else
+ break;
}
- return (List<Resource>) Lists.map(new FunctionImpl1<Tuple2, Resource>() {
- @Override
- public Resource apply(Tuple2 p0) {
- return (Resource) p0.c0;
- }
- }, result2);
+ // Take first n items
+ if (count < result2.size()) {
+ result2 = result2.subList(0, resultCount);
+ }
+
+ // Map to list or resources
+ List<Resource> selection = result2.stream().map(p -> p.first).collect(Collectors.toList());
+ return new SelectionResult(selection, tailCount, tailSize);
}
}