From db27ce6407d4a3ec7b6e3ba97847275b41432fc7 Mon Sep 17 00:00:00 2001 From: miettinen Date: Tue, 21 Jan 2014 06:35:57 +0000 Subject: [PATCH] Loops tab in Sysdyn: Combo for selecting the loop items (refs #3012). LoopTab to extend AdjustableTab git-svn-id: https://www.simantics.org/svn/simantics/sysdyn/trunk@28678 ac1ea38d-2e2b-0410-8846-a27921b304fc --- .../sysdyn/ui/properties/LoopTab.java | 202 ++++++++++++++++-- .../sysdyn/utils/ConfigurationUtils.java | 86 +++++--- 2 files changed, 246 insertions(+), 42 deletions(-) diff --git a/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/properties/LoopTab.java b/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/properties/LoopTab.java index 60720d62..0b770e37 100644 --- a/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/properties/LoopTab.java +++ b/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/properties/LoopTab.java @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2010, 2012 Association for Decentralized Information Management in + * Copyright (c) 2013-2014 Association for Decentralized Information Management in * Industry THTH ry. * All rights reserved. This program and the accompanying materials * are made available under the terms of the Eclipse Public License v1.0 @@ -11,15 +11,24 @@ *******************************************************************************/ package org.simantics.sysdyn.ui.properties; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + import org.eclipse.jface.layout.GridDataFactory; import org.eclipse.jface.layout.GridLayoutFactory; import org.eclipse.swt.SWT; +import org.eclipse.swt.widgets.Combo; import org.eclipse.swt.widgets.Composite; +import org.eclipse.swt.widgets.Display; import org.eclipse.swt.widgets.Group; +import org.eclipse.swt.widgets.Label; import org.eclipse.ui.IWorkbenchSite; import org.simantics.browsing.ui.swt.widgets.Button; import org.simantics.browsing.ui.swt.widgets.StringPropertyModifier; +import org.simantics.browsing.ui.swt.widgets.TrackedCombo; import org.simantics.browsing.ui.swt.widgets.TrackedText; +import org.simantics.browsing.ui.swt.widgets.impl.ComboModifyListenerImpl; import org.simantics.browsing.ui.swt.widgets.impl.ReadFactoryImpl; import org.simantics.browsing.ui.swt.widgets.impl.SelectionListenerImpl; import org.simantics.browsing.ui.swt.widgets.impl.WidgetSupport; @@ -28,10 +37,14 @@ import org.simantics.databoard.util.ObjectUtils; import org.simantics.db.ReadGraph; import org.simantics.db.Resource; import org.simantics.db.WriteGraph; +import org.simantics.db.common.request.WriteRequest; +import org.simantics.db.common.utils.ListUtils; import org.simantics.db.exception.DatabaseException; import org.simantics.db.management.ISessionContext; import org.simantics.modeling.ModelingResources; import org.simantics.sysdyn.SysdynResource; +import org.simantics.sysdyn.utils.ConfigurationUtils; +import org.simantics.ui.SimanticsUI; import org.simantics.utils.datastructures.Pair; import org.simantics.utils.datastructures.Triple; @@ -40,22 +53,29 @@ import org.simantics.utils.datastructures.Triple; * @author Tuomas Miettinen * */ -public class LoopTab extends LabelPropertyTabContributor { +public class LoopTab extends AdjustableTab { - Button auto, balancing, reinforcing, other, inside, outside; + private Label loopItemsLabel; + private TrackedCombo loopItemsDropdown; + Button auto, balancing, reinforcing, other, inside, outside; TrackedText loopComment, polarityLocationText; + Composite composite, loopItems; + Group commentGroup, rotationGroup; + protected Resource resource; public static final String AUTO = "$$AUTO$$"; @Override - public void createControls(Composite body, IWorkbenchSite site, ISessionContext context, WidgetSupport support) { - Composite composite = new Composite(body, SWT.NONE); - GridDataFactory.fillDefaults().grab(true, true).applyTo(composite); - GridLayoutFactory.fillDefaults().margins(3, 3).numColumns(2).applyTo(composite); - - Group commentGroup = new Group(composite, SWT.NONE); + protected void createAndAddControls(Composite body, IWorkbenchSite site, + ISessionContext context, WidgetSupport support) { + composite = new Composite(body, SWT.NONE); + + loopItems = new Composite(composite, SWT.NONE); + loopItemsLabel = new Label(loopItems, SWT.SINGLE); + loopItemsLabel.setText("Loop Items:"); + loopItemsDropdown = new TrackedCombo(loopItems, support, SWT.DROP_DOWN | SWT.BORDER | SWT.READ_ONLY); + + commentGroup = new Group(composite, SWT.NONE); commentGroup.setText("Comment"); - GridDataFactory.fillDefaults().grab(true, false).applyTo(commentGroup); - GridLayoutFactory.fillDefaults().numColumns(5).applyTo(commentGroup); auto = new Button(commentGroup, support, SWT.RADIO); auto.setText("Auto"); @@ -79,11 +99,8 @@ public class LoopTab extends LabelPropertyTabContributor { loopComment = new TrackedText(commentGroup, support, SWT.BORDER); loopComment.setTextFactory(new OtherCommentStringPropertyFactory()); loopComment.addModifyListener(new StringPropertyModifier(context, SysdynResource.URIs.Loop_Comment)); - GridDataFactory.fillDefaults().grab(true, false).applyTo(loopComment.getWidget()); - Group rotationGroup = new Group(composite, SWT.NONE); - GridDataFactory.fillDefaults().applyTo(rotationGroup); - GridLayoutFactory.fillDefaults().applyTo(rotationGroup); + rotationGroup = new Group(composite, SWT.NONE); rotationGroup.setText("Direction of Rotation"); inside = new Button(rotationGroup, support, SWT.RADIO); @@ -95,6 +112,161 @@ public class LoopTab extends LabelPropertyTabContributor { outside.setText("Counterclockwise"); outside.setSelectionFactory(new ClockwiseRotationRadioSelectionFactory(false)); outside.addSelectionListener(new ClockwiseRotationSelectionListener(context, false)); + + addListeners(context); + } + + private void addListeners(ISessionContext context) { + // Item factory for loopItemsDropdown combo + loopItemsDropdown.setItemFactory(new ReadFactoryImpl>() { + + @Override + public Map perform(ReadGraph graph, final Resource input) throws DatabaseException { + + LoopTab.this.resource = input; + Map map = new HashMap(); + List> loops = ConfigurationUtils.getAllLoopsInDiagram(graph, input); + map.put("", null); + for (List loop : loops) { + map.put(ConfigurationUtils.cycleToString(graph, loop), loop); + } + return map; + } + }); + + // Initial selection to the combo + loopItemsDropdown.setSelectionFactory(new ReadFactoryImpl() { + + @Override + public String perform(ReadGraph graph, final Resource input) throws DatabaseException { + SysdynResource sr = SysdynResource.getInstance(graph); + Resource itemListResource = graph.getPossibleObject(input, sr.Loop_Items); + + // If the loop hasn't been defined, return empty. + if (itemListResource == null) { + return ""; + } + List itemList = ListUtils.toPossibleList(graph, itemListResource); + if (itemList == null) { + return ""; + } + + // See if the defined loop still exists. + List> loops = ConfigurationUtils.getAllLoopsInDiagram(graph, input); + Resource first = itemList.get(0); + for (List loop : loops) { + // If the loops are of different size, continue. + if (loop.size() != itemList.size()) + continue; + + // If the first element of the sought loop is not found, continue. + int indexOfFirst = loop.indexOf(first); + if (indexOfFirst < 0) { + continue; + } + + // Check if the loops are the same, + // even if they start at different Resources + boolean match = true; + int i = 1;// = indexOfFirst + 1; + do { + // Get the next Resource in the loop + Resource next = loop.get((i + indexOfFirst) % loop.size()); + // If it is other than what should be, continue to the next loop. + if (!next.equalsResource(itemList.get(i))) { + match = false; + break; + } + } while (++i != itemList.size()); + if (!match) + continue; + + return ConfigurationUtils.cycleToString(graph, loop); + } + + // No match found, hence empty + return ""; + } + }); + + // Modify listener for selecting loop items + loopItemsDropdown.addModifyListener(new ComboModifyListenerImpl() { + + @SuppressWarnings("unchecked") + @Override + public void applyText(WriteGraph graph, final Resource input, String text) throws DatabaseException { + final Combo c = loopItemsDropdown.getWidget(); + Display.getDefault().asyncExec(new Runnable() { + public void run() { + Object o = c.getData(); + if (o != null && !(o instanceof HashMap)) + return; + + Object loopObject = ((HashMap)o).get(c.getText()); + if (loopObject == null || !(loopObject instanceof List)) + return; + + final List loop = (List)loopObject; + SimanticsUI.getSession().asyncRequest(new WriteRequest() { + + @Override + public void perform(WriteGraph graph) + throws DatabaseException { + SysdynResource sr = SysdynResource.getInstance(graph); + Resource loopResource = graph.getPossibleObject(input, sr.Loop_Items); + // Delete the current list if it exists. + if (loopResource != null) { + List removedList = ListUtils.toPossibleList(graph, loopResource); + for (Resource r : removedList) + ListUtils.removeElement(graph, loopResource, r); + graph.deny(loopResource); + } + // Create new list. + Resource newList = ListUtils.create(graph, loop); + graph.claim(input, sr.Loop_Items, newList); + } + }); + } + }); + + } + }); + } + + @Override + protected void createControlLayoutVertical() { + GridDataFactory.fillDefaults().grab(true, false).span(1, 1).applyTo(loopItems); + GridLayoutFactory.fillDefaults().numColumns(1).applyTo(loopItems); + GridDataFactory.fillDefaults().grab(false, false).applyTo(loopItemsLabel); + GridDataFactory.fillDefaults().grab(true, false).applyTo(loopItemsDropdown.getWidget()); + + GridDataFactory.fillDefaults().grab(true, true).applyTo(composite); + GridLayoutFactory.fillDefaults().margins(3, 3).numColumns(1).applyTo(composite); + + GridDataFactory.fillDefaults().grab(true, false).applyTo(commentGroup); + GridLayoutFactory.fillDefaults().numColumns(5).applyTo(commentGroup); + + GridDataFactory.fillDefaults().grab(true, false).applyTo(loopComment.getWidget()); + GridDataFactory.fillDefaults().grab(false, false).applyTo(rotationGroup); + GridLayoutFactory.fillDefaults().applyTo(rotationGroup); + } + + @Override + protected void createControlLayoutHorizontal(boolean wideScreen) { + GridDataFactory.fillDefaults().grab(true, false).span(2, 1).applyTo(loopItems); + GridLayoutFactory.fillDefaults().numColumns(2).applyTo(loopItems); + GridDataFactory.fillDefaults().grab(false, false).applyTo(loopItemsLabel); + GridDataFactory.fillDefaults().grab(true, false).applyTo(loopItemsDropdown.getWidget()); + + GridDataFactory.fillDefaults().grab(true, true).applyTo(composite); + GridLayoutFactory.fillDefaults().margins(3, 3).numColumns(2).applyTo(composite); + + GridDataFactory.fillDefaults().grab(true, false).applyTo(commentGroup); + GridLayoutFactory.fillDefaults().numColumns(5).applyTo(commentGroup); + + GridDataFactory.fillDefaults().grab(true, false).applyTo(loopComment.getWidget()); + GridDataFactory.fillDefaults().grab(false, false).applyTo(rotationGroup); + GridLayoutFactory.fillDefaults().applyTo(rotationGroup); } class OtherCommentStringPropertyFactory extends ReadFactoryImpl { diff --git a/org.simantics.sysdyn/src/org/simantics/sysdyn/utils/ConfigurationUtils.java b/org.simantics.sysdyn/src/org/simantics/sysdyn/utils/ConfigurationUtils.java index e10cbe9d..9f5895c4 100644 --- a/org.simantics.sysdyn/src/org/simantics/sysdyn/utils/ConfigurationUtils.java +++ b/org.simantics.sysdyn/src/org/simantics/sysdyn/utils/ConfigurationUtils.java @@ -72,14 +72,34 @@ public class ConfigurationUtils { @SuppressWarnings({ "rawtypes", "unchecked", "unused" }) public static List> getLoops(ReadGraph g, Resource r) throws DatabaseException, ServiceException { + // Get all loops in the diagram. + List> cycles = getAllLoopsInDiagram(g, r); + + // Collect all those loops in which the original resource exists. + List> loops = new ArrayList>(); + for (Object o : cycles) { + if (o instanceof List) { + List loop = (List)o; + if (loop.contains(r)) + loops.add(loop); + } + } + + // Debug print the result + if (false) { + System.out.println(cyclesToString(g, cycles)); + } + + return loops; + } + + @SuppressWarnings({ "rawtypes", "unchecked" }) + public static List> getAllLoopsInDiagram(ReadGraph g, Resource r) throws DatabaseException, ServiceException { Layer0 l0 = Layer0.getInstance(g); SysdynResource sr = SysdynResource.getInstance(g); - List> loops = Collections.emptyList(); Resource configuration = g.getPossibleObject(r, l0.PartOf); if (configuration == null) - return loops; - - loops = new ArrayList>(); + return Collections.emptyList(); Collection variables = g.getObjects(configuration, l0.ConsistsOf); ArrayList shadows = new ArrayList(); @@ -159,31 +179,43 @@ public class ConfigurationUtils { ElementaryCyclesSearch ecs = new ElementaryCyclesSearch(adjMatrix, nodes); List cycles = ecs.getElementaryCycles(); - // Collect all those loops in which the original resource exists. - for (Object o : cycles) { - if (o instanceof List) { - List loop = (List)o; - if (loop.contains(r)) - loops.add(loop); - } + return cycles; + } + + /** + * Get the String representation of cycles. + * @param g + * @param cycles List of Resource Lists of which names are returned. + * @return the String representation of cycles + * @throws DatabaseException + */ + public static String cyclesToString(ReadGraph g, List> cycles) throws DatabaseException { + StringBuilder sb = new StringBuilder(""); + for (int i = 0; i < cycles.size(); i++) { + sb.append(cycleToString(g, cycles.get(i))); + sb.append("\n"); } - - // Debug print the result - if (false) { - for (int i = 0; i < cycles.size(); i++) { - List cycle = (List) cycles.get(i); - for (int j = 0; j < cycle.size(); j++) { - Resource node = (Resource) cycle.get(j); - if (j < cycle.size() - 1) { - System.out.print(g.getPossibleRelatedValue(node, l0.HasName, Bindings.STRING) + " -> "); - } else { - System.out.print(g.getPossibleRelatedValue(node, l0.HasName, Bindings.STRING)); - } - } - System.out.print("\n"); + return sb.toString(); + } + + /** + * Get the String representation of a cycle. + * @param g + * @param cycle List of Resources of which names are returned. + * @return the String representation of a cycle + * @throws DatabaseException + */ + public static String cycleToString(ReadGraph g, List cycle) throws DatabaseException { + Layer0 l0 = Layer0.getInstance(g); + StringBuilder sb = new StringBuilder(""); + for (int j = 0; j < cycle.size(); j++) { + Resource node = (Resource) cycle.get(j); + if (j < cycle.size() - 1) { + sb.append(g.getPossibleRelatedValue(node, l0.HasName, Bindings.STRING) + " -> "); + } else { + sb.append(g.getPossibleRelatedValue(node, l0.HasName, Bindings.STRING)); } } - - return loops; + return sb.toString(); } } -- 2.47.1