From b7f8a2b6c6018cc06b06eaf0dee1641e62b66643 Mon Sep 17 00:00:00 2001 From: lempinen Date: Tue, 2 Nov 2010 14:11:03 +0000 Subject: [PATCH] First take on Enumerations in System Dynamics. Enumerations can be created to Configurations and deleted from the model browser. Properties of the enumerations can be modified from the property view (add & remove indexes). Enumeration is added to the modelica code, but it cannot be used yet. git-svn-id: https://www.simantics.org/svn/simantics/sysdyn/trunk@18557 ac1ea38d-2e2b-0410-8846-a27921b304fc --- .../RelatedOrderedSetElements.java | 27 ++ .../RelatedOrderedSetElementsRuleFactory.java | 40 +++ .../RelatedOrderedSetElementsAccessor.java | 62 ++++ org.simantics.sysdyn.ontology/graph.tg | Bin 45602 -> 46084 bytes .../graph/Sysdyn.pgraph | 20 +- .../graph/WorkModel.pgraph | 11 +- .../org/simantics/sysdyn/SysdynResource.java | 33 +- org.simantics.sysdyn.ui/plugin.xml | 25 ++ .../sysdyn/ui/browser/BrowserSelection.java | 11 +- .../sysdyn/ui/browser/SysdynBrowser.java | 2 +- .../browser/contributions/Configuration.java | 6 + .../ui/browser/nodes/EnumerationNode.java | 35 +++ .../handlers/NewEnumerationNodeHandler.java | 50 ++++ .../sysdyn/ui/properties/EnumerationTab.java | 281 ++++++++++++++++++ .../ResourceSelectionProcessor.java | 7 + .../sysdyn/modelica/ModelicaWriter.java | 11 + .../sysdyn/representation/Enumeration.java | 31 ++ .../representation/EnumerationIndex.java | 16 + .../representation/EnumerationIndexes.java | 17 ++ .../sysdyn/representation/SysdynSchema.java | 3 + .../visitors/ElementVisitorVoidAdapter.java | 5 + .../visitors/IElementVisitorVoid.java | 2 + 22 files changed, 673 insertions(+), 22 deletions(-) create mode 100644 org.simantics.objmap/src/org/simantics/objmap/annotations/RelatedOrderedSetElements.java create mode 100644 org.simantics.objmap/src/org/simantics/objmap/annotations/factories/RelatedOrderedSetElementsRuleFactory.java create mode 100644 org.simantics.objmap/src/org/simantics/objmap/rules/domain/RelatedOrderedSetElementsAccessor.java create mode 100644 org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/browser/nodes/EnumerationNode.java create mode 100644 org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/handlers/NewEnumerationNodeHandler.java create mode 100644 org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/properties/EnumerationTab.java create mode 100644 org.simantics.sysdyn/src/org/simantics/sysdyn/representation/Enumeration.java create mode 100644 org.simantics.sysdyn/src/org/simantics/sysdyn/representation/EnumerationIndex.java create mode 100644 org.simantics.sysdyn/src/org/simantics/sysdyn/representation/EnumerationIndexes.java diff --git a/org.simantics.objmap/src/org/simantics/objmap/annotations/RelatedOrderedSetElements.java b/org.simantics.objmap/src/org/simantics/objmap/annotations/RelatedOrderedSetElements.java new file mode 100644 index 00000000..21b3e171 --- /dev/null +++ b/org.simantics.objmap/src/org/simantics/objmap/annotations/RelatedOrderedSetElements.java @@ -0,0 +1,27 @@ +/******************************************************************************* + * Copyright (c) 2007, 2010 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 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * VTT Technical Research Centre of Finland - initial API and implementation + *******************************************************************************/ +package org.simantics.objmap.annotations; + +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; + +import org.simantics.objmap.annotations.factories.RelatedOrderedSetElementsRuleFactory; +import org.simantics.objmap.annotations.meta.HasFieldRuleFactory; + +@Retention(RetentionPolicy.RUNTIME) +@Target(ElementType.FIELD) +@HasFieldRuleFactory(RelatedOrderedSetElementsRuleFactory.class) +public @interface RelatedOrderedSetElements { + boolean composition() default false; +} diff --git a/org.simantics.objmap/src/org/simantics/objmap/annotations/factories/RelatedOrderedSetElementsRuleFactory.java b/org.simantics.objmap/src/org/simantics/objmap/annotations/factories/RelatedOrderedSetElementsRuleFactory.java new file mode 100644 index 00000000..fb78847e --- /dev/null +++ b/org.simantics.objmap/src/org/simantics/objmap/annotations/factories/RelatedOrderedSetElementsRuleFactory.java @@ -0,0 +1,40 @@ +/******************************************************************************* + * Copyright (c) 2007, 2010 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 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * VTT Technical Research Centre of Finland - initial API and implementation + *******************************************************************************/ +package org.simantics.objmap.annotations.factories; + +import java.lang.annotation.Annotation; +import java.lang.reflect.Field; +import java.util.Collection; + +import org.simantics.db.ReadGraph; +import org.simantics.db.exception.ResourceNotFoundException; +import org.simantics.db.exception.ServiceException; +import org.simantics.db.exception.ValidationException; +import org.simantics.objmap.IMappingRule; +import org.simantics.objmap.annotations.RelatedOrderedSetElements; +import org.simantics.objmap.rules.MappedElementsRule; +import org.simantics.objmap.rules.domain.RelatedOrderedSetElementsAccessor; +import org.simantics.objmap.rules.factory.IFieldRuleFactory; +import org.simantics.objmap.rules.range.FieldAccessor; + +public class RelatedOrderedSetElementsRuleFactory implements IFieldRuleFactory { + + @Override + public IMappingRule create(ReadGraph g, Annotation _annotation, Field field) throws ResourceNotFoundException, ValidationException, ServiceException { + RelatedOrderedSetElements annotation = (RelatedOrderedSetElements)_annotation; + return new MappedElementsRule( + new RelatedOrderedSetElementsAccessor(annotation.composition()), + new FieldAccessor>(field) + ); + } + +} diff --git a/org.simantics.objmap/src/org/simantics/objmap/rules/domain/RelatedOrderedSetElementsAccessor.java b/org.simantics.objmap/src/org/simantics/objmap/rules/domain/RelatedOrderedSetElementsAccessor.java new file mode 100644 index 00000000..a92d2d27 --- /dev/null +++ b/org.simantics.objmap/src/org/simantics/objmap/rules/domain/RelatedOrderedSetElementsAccessor.java @@ -0,0 +1,62 @@ +/******************************************************************************* + * Copyright (c) 2007, 2010 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 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * VTT Technical Research Centre of Finland - initial API and implementation + *******************************************************************************/ +package org.simantics.objmap.rules.domain; + +import java.util.Collection; + +import org.apache.log4j.Logger; +import org.simantics.db.ReadGraph; +import org.simantics.db.Resource; +import org.simantics.db.WriteGraph; +import org.simantics.db.common.utils.OrderedSetUtils; +import org.simantics.db.exception.DatabaseException; +import org.simantics.objmap.MappingException; + +/** + * Accesses the set of objects attached to the element by the given relation. + * @author Hannu Niemistö + */ +public class RelatedOrderedSetElementsAccessor implements IDomainAccessor> { + + static Logger LOGGER = Logger.getLogger("org.simantics.objmap"); + + boolean deleteExtraObjects; + + public RelatedOrderedSetElementsAccessor(boolean deleteExtraObjects) { + super(); + this.deleteExtraObjects = deleteExtraObjects; + } + + @Override + public Collection get(ReadGraph g, Resource element) throws MappingException { + try { + LOGGER.info(" RelatedOrderedSetElementsAccessor.get"); + return OrderedSetUtils.toList(g, element); + } catch (DatabaseException e) { + throw new MappingException(e); + } + } + + @Override + public boolean set(WriteGraph g, Resource element, Collection value) + throws MappingException { + try { + LOGGER.info(" RelatedOrderedSetElementsAccessor.set"); + return OrderedSetUtils.set(g, element, value); + // FIXME Implement deleteExtraObjects + } catch (DatabaseException e) { + throw new MappingException(e); + } + + } + +} diff --git a/org.simantics.sysdyn.ontology/graph.tg b/org.simantics.sysdyn.ontology/graph.tg index 05c8dcb9682d71024a1e3bd8e3b04632f2c7b26e..ee9c3913f501dd71c9016fdd35654c78a50ef5ec 100644 GIT binary patch literal 46084 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 bjNszkT3XJM&EzK9yx_R+svbwd>N@^^Un3}K literal 45602 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ĐS$UX``*Wp_udwI2P;vpoS77U3srspDwi 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 + + + + + + + + + + @@ -456,6 +477,10 @@ args="org.simantics.image.ui.modelBrowser.ImageNode" property="org.simantics.sysdyn.ui.nodeClass"> + + diff --git a/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/browser/BrowserSelection.java b/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/browser/BrowserSelection.java index 619de4f0..4106a455 100644 --- a/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/browser/BrowserSelection.java +++ b/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/browser/BrowserSelection.java @@ -12,14 +12,17 @@ package org.simantics.sysdyn.ui.browser; import org.eclipse.core.runtime.IAdaptable; +import org.simantics.browsing.ui.NodeContext; import org.simantics.db.Resource; public class BrowserSelection implements IAdaptable { private Resource resource; private Resource model; private String URI; + private Object originalInput; - public BrowserSelection(Resource resource, String URI, Resource model) { + public BrowserSelection(Object originalInput, Resource resource, String URI, Resource model) { + this.originalInput = originalInput; this.resource = resource; this.URI = URI; this.model = model; @@ -30,6 +33,12 @@ public class BrowserSelection implements IAdaptable { public Object getAdapter(Class adapter) { if (adapter == Resource.class) return resource; + if (NodeContext.class.equals(adapter)) + return originalInput; + if (originalInput instanceof IAdaptable) { + IAdaptable input = (IAdaptable)originalInput; + return input.getAdapter(adapter); + } return null; } diff --git a/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/browser/SysdynBrowser.java b/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/browser/SysdynBrowser.java index 6905e7e6..dac17e5e 100644 --- a/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/browser/SysdynBrowser.java +++ b/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/browser/SysdynBrowser.java @@ -54,7 +54,7 @@ public class SysdynBrowser extends GraphExplorerView { if(vn != null) { Resource resource = vn.getResource() == null ? vn.data : vn.getResource(); context = new AdaptableHintContext(SelectionHints.KEY_MAIN, SelectionHints.KEY_SELECTION_PROPERTY); - context.setHint(SelectionHints.KEY_MAIN, new BrowserSelection(resource, vn.getURI(), vn.getModel())); + context.setHint(SelectionHints.KEY_MAIN, new BrowserSelection(objects[i], resource, vn.getURI(), vn.getModel())); context.setHint(SelectionHints.KEY_SELECTION_PROPERTY, vn.getVariable()); } else { context = new AdaptableHintContext(SelectionHints.KEY_MAIN); diff --git a/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/browser/contributions/Configuration.java b/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/browser/contributions/Configuration.java index 89edaaa4..7baf1048 100644 --- a/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/browser/contributions/Configuration.java +++ b/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/browser/contributions/Configuration.java @@ -22,6 +22,7 @@ import org.simantics.db.exception.DatabaseException; import org.simantics.layer0.Layer0; import org.simantics.sysdyn.SysdynResource; import org.simantics.sysdyn.ui.browser.nodes.ConfigurationNode; +import org.simantics.sysdyn.ui.browser.nodes.EnumerationNode; import org.simantics.sysdyn.ui.browser.nodes.InputNode; import org.simantics.sysdyn.ui.browser.nodes.ModuleNode; import org.simantics.sysdyn.ui.browser.nodes.VariableNode; @@ -39,6 +40,7 @@ public class Configuration extends ViewpointContributor variables = new ArrayList(); ArrayList inputs = new ArrayList(); ArrayList modules = new ArrayList(); + ArrayList enumerations = new ArrayList(); for(Resource r : graph.getObjects(configuration.data, l0.ConsistsOf)) { Resource represents = graph.getSingleObject(r, l0.Represents); @@ -48,6 +50,8 @@ public class Configuration extends ViewpointContributor implements IDeletableNode { + + public EnumerationNode(Resource resource) { + super(resource); + } + + @Override + public void delete() throws DeleteException { + try { + SimanticsUI.getSession().syncRequest(new WriteRequest() { + @Override + public void perform(WriteGraph graph) throws DatabaseException, CancelTransactionException { + Layer0 l0 = Layer0.getInstance(graph); + graph.deny(resource, l0.PartOf); + } + }); + } catch (DatabaseException e) { + ExceptionUtils.logAndShowError(e); + } + } + +} diff --git a/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/handlers/NewEnumerationNodeHandler.java b/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/handlers/NewEnumerationNodeHandler.java new file mode 100644 index 00000000..bbccf0b7 --- /dev/null +++ b/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/handlers/NewEnumerationNodeHandler.java @@ -0,0 +1,50 @@ +package org.simantics.sysdyn.ui.handlers; + +import org.eclipse.core.commands.AbstractHandler; +import org.eclipse.core.commands.ExecutionEvent; +import org.eclipse.core.commands.ExecutionException; +import org.eclipse.jface.viewers.ISelection; +import org.eclipse.ui.handlers.HandlerUtil; +import org.simantics.db.Resource; +import org.simantics.db.WriteGraph; +import org.simantics.db.common.request.WriteRequest; +import org.simantics.db.common.utils.OrderedSetUtils; +import org.simantics.db.exception.DatabaseException; +import org.simantics.layer0.Layer0; +import org.simantics.layer0.utils.direct.GraphUtils; +import org.simantics.sysdyn.SysdynResource; +import org.simantics.ui.SimanticsUI; +import org.simantics.ui.utils.AdaptionUtils; + +public class NewEnumerationNodeHandler extends AbstractHandler { + + @Override + public Object execute(ExecutionEvent event) throws ExecutionException { + + ISelection sel = HandlerUtil.getCurrentSelection(event); + + final Resource configuration = AdaptionUtils.adaptToSingle(sel, Resource.class); + + SimanticsUI.getSession().asyncRequest(new WriteRequest() { + + @Override + public void perform(WriteGraph g) throws DatabaseException { + SysdynResource sr = SysdynResource.getInstance(g); + Layer0 l0 = Layer0.getInstance(g); + + + Resource enumerationIndexes = OrderedSetUtils.create(g, sr.EnumerationIndexes); + + Resource enumeration = GraphUtils.create2(g, + sr.Enumeration, + l0.HasName, "Enumeration", + sr.HasEnumerationIndexes, enumerationIndexes); + + g.claim(configuration, l0.ConsistsOf, enumeration); + + } + }); + return null; + } + +} diff --git a/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/properties/EnumerationTab.java b/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/properties/EnumerationTab.java new file mode 100644 index 00000000..ffabdef0 --- /dev/null +++ b/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/properties/EnumerationTab.java @@ -0,0 +1,281 @@ +package org.simantics.sysdyn.ui.properties; + +import java.util.ArrayList; +import java.util.List; + +import org.eclipse.jface.layout.GridDataFactory; +import org.eclipse.jface.layout.GridLayoutFactory; +import org.eclipse.jface.viewers.ISelection; +import org.eclipse.swt.SWT; +import org.eclipse.swt.custom.TableEditor; +import org.eclipse.swt.events.FocusAdapter; +import org.eclipse.swt.events.FocusEvent; +import org.eclipse.swt.events.ModifyEvent; +import org.eclipse.swt.events.ModifyListener; +import org.eclipse.swt.events.SelectionAdapter; +import org.eclipse.swt.events.SelectionEvent; +import org.eclipse.swt.events.SelectionListener; +import org.eclipse.swt.widgets.Composite; +import org.eclipse.swt.widgets.Control; +import org.eclipse.swt.widgets.TableItem; +import org.eclipse.swt.widgets.Text; +import org.eclipse.ui.IWorkbenchSite; +import org.simantics.browsing.ui.swt.PropertyTabContributorImpl; +import org.simantics.browsing.ui.swt.widgets.Button; +import org.simantics.browsing.ui.swt.widgets.StringPropertyFactory; +import org.simantics.browsing.ui.swt.widgets.Table; +import org.simantics.browsing.ui.swt.widgets.TrackedText; +import org.simantics.browsing.ui.swt.widgets.impl.ReadFactoryImpl; +import org.simantics.browsing.ui.swt.widgets.impl.Widget; +import org.simantics.browsing.ui.swt.widgets.impl.WidgetSupport; +import org.simantics.databoard.binding.java.StringBindingDefault; +import org.simantics.db.Builtins; +import org.simantics.db.ReadGraph; +import org.simantics.db.Resource; +import org.simantics.db.WriteGraph; +import org.simantics.db.common.request.ReadRequest; +import org.simantics.db.common.request.WriteRequest; +import org.simantics.db.common.utils.OrderedSetUtils; +import org.simantics.db.exception.DatabaseException; +import org.simantics.db.management.ISessionContext; +import org.simantics.layer0.Layer0; +import org.simantics.layer0.utils.direct.GraphUtils; +import org.simantics.sysdyn.SysdynResource; +import org.simantics.sysdyn.ui.properties.widgets.factories.VariableNamePropertyModifier; +import org.simantics.sysdyn.ui.properties.widgets.factories.VariableNameValidator; +import org.simantics.ui.SimanticsUI; +import org.simantics.utils.datastructures.Pair; +import org.simantics.utils.ui.ISelectionUtils; + +public class EnumerationTab extends PropertyTabContributorImpl { + + Table table; + @Override + public void createControls(Composite body, IWorkbenchSite site, + final ISessionContext context, WidgetSupport support) { + + Composite container = new Composite(body, SWT.None); + GridDataFactory.fillDefaults().grab(true, true).applyTo(container); + GridLayoutFactory.fillDefaults().margins(3, 3).numColumns(2).applyTo(container); + + TrackedText nameText = new TrackedText(container, support, SWT.BORDER); + nameText.setTextFactory(new StringPropertyFactory(Builtins.URIs.HasName)); + nameText.addModifyListener(new VariableNamePropertyModifier(context, Builtins.URIs.HasName)); + nameText.setInputValidator(new VariableNameValidator(support)); + GridDataFactory.fillDefaults().grab(true, false).span(2,1).applyTo(nameText.getWidget()); + + + table = new Table(container, support, SWT.BORDER); + table.setItemFactory(new ReadFactoryImpl>>() { + + @Override + public List> perform(ReadGraph graph, + Object input) throws DatabaseException { + Resource enumeration = (Resource)input; + SysdynResource sr = SysdynResource.getInstance(graph); + Resource list = graph.getSingleObject(enumeration, sr.HasEnumerationIndexes); + List resourceList = OrderedSetUtils.toList(graph, list); + + List> result = new ArrayList>(); + for(Resource r : resourceList) { + result.add(new Pair( + (String)graph.getRelatedValue(r, Layer0.getInstance(graph).HasName, StringBindingDefault.INSTANCE) + , r)); + } + return result; + } + }); + table.setSelectionFactory(new ReadFactoryImpl() { + + @Override + public String perform(ReadGraph graph, final Resource input) throws DatabaseException { + return graph.getRelatedValue(input, Layer0.getInstance(graph).HasName); + } + }); + GridDataFactory.fillDefaults().grab(true, true).span(2, 1).applyTo(table.getWidget()); + + + final TableEditor editor = new TableEditor(table.getWidget()); + // The editor must have the same size as the cell and must + // not be any smaller than 50 pixels. + editor.horizontalAlignment = SWT.LEFT; + editor.grabHorizontal = true; + editor.minimumWidth = 50; + // editing the second column + final int EDITABLECOLUMN = 0; + + table.addSelectionListener(new SelectionAdapter() { + public void widgetSelected(SelectionEvent e) { + // Clean up any previous editor control + Control oldEditor = editor.getEditor(); + if (oldEditor != null) + oldEditor.dispose(); + + // Identify the selected row + final TableItem item = (TableItem) e.item; + if (item == null) + return; + + // The control that will be the editor must be a child of the + // Table + Text newEditor = new Text(item.getParent(), SWT.NONE); + final String originalText = item.getText(EDITABLECOLUMN); + final Resource resource = (Resource) item.getData(); + newEditor.setText(originalText); + newEditor.addModifyListener(new ModifyListener() { + public void modifyText(ModifyEvent me) { + Text text = (Text) editor.getEditor(); + if(!text.isDisposed()) { + TableItem item = editor.getItem(); + if(!item.isDisposed()) + item.setText(EDITABLECOLUMN, text.getText()); + } + } + }); + newEditor.addFocusListener(new FocusAdapter() { + @Override + public void focusLost(FocusEvent e) { + final Text text = (Text) editor.getEditor(); + if(!text.getText().equals(originalText)) { + final String newText = text.getText(); + try { + context.getSession().syncRequest(new WriteRequest() { + + @Override + public void perform(WriteGraph graph) throws DatabaseException { + graph.claimLiteral( + resource, + Layer0.getInstance(graph).HasName, + newText); + } + }); + } catch (DatabaseException e1) { + e1.printStackTrace(); + } + } + } + }); + newEditor.selectAll(); + newEditor.setFocus(); + editor.setEditor(newEditor, item, EDITABLECOLUMN); + } + }); + + + Button add = new Button(container, support, SWT.None); + add.setText("Add index"); + add.addSelectionListener(new addEnumerationIndexListener(support)); + + Button remove = new Button(container, support, SWT.None); + remove.setText("Remove"); + remove.addSelectionListener(new removeEnumerationIndexListener(support)); + } + + private class addEnumerationIndexListener implements SelectionListener, Widget { + + Resource enumerationIndexes; + + public addEnumerationIndexListener(WidgetSupport support) { + support.register(this); + } + + @Override + public void setInput(ISessionContext context, Object input) { + final Resource enumeration = ISelectionUtils.filterSingleSelection((ISelection)input, Resource.class); + try { + context.getSession().syncRequest(new ReadRequest() { + + @Override + public void run(ReadGraph graph) throws DatabaseException { + enumerationIndexes = graph.getSingleObject(enumeration, SysdynResource.getInstance(graph).HasEnumerationIndexes); + } + }); + } catch (DatabaseException e) { + e.printStackTrace(); + } + } + + @Override + public void widgetSelected(SelectionEvent e) { + try { + SimanticsUI.getSession().syncRequest(new WriteRequest() { + + @Override + public void perform(WriteGraph graph) throws DatabaseException { + SysdynResource sr = SysdynResource.getInstance(graph); + Layer0 l0 = Layer0.getInstance(graph); + + + Resource ei = GraphUtils.create2(graph, + sr.EnumerationIndex, + l0.HasName, "index"); + OrderedSetUtils.add(graph, enumerationIndexes, ei); + } + }); + } catch (DatabaseException e1) { + e1.printStackTrace(); + } + + } + + @Override + public void widgetDefaultSelected(SelectionEvent e) { + + } + + } + + private class removeEnumerationIndexListener implements SelectionListener, Widget { + + Resource enumerationIndexes; + + public removeEnumerationIndexListener(WidgetSupport support) { + support.register(this); + } + + @Override + public void setInput(ISessionContext context, Object input) { + final Resource enumeration = ISelectionUtils.filterSingleSelection((ISelection)input, Resource.class); + try { + context.getSession().syncRequest(new ReadRequest() { + + @Override + public void run(ReadGraph graph) throws DatabaseException { + enumerationIndexes = graph.getSingleObject(enumeration, SysdynResource.getInstance(graph).HasEnumerationIndexes); + } + }); + } catch (DatabaseException e) { + e.printStackTrace(); + } + } + + @Override + public void widgetSelected(SelectionEvent e) { + TableItem[] items = table.getWidget().getSelection(); + final ArrayList resources = new ArrayList(); + for(int i = 0; i < items.length; i++) { + if(items[i].getData() instanceof Resource) + resources.add((Resource)items[i].getData()); + } + try { + SimanticsUI.getSession().syncRequest(new WriteRequest() { + + @Override + public void perform(WriteGraph graph) throws DatabaseException { + for(Resource r : resources) + OrderedSetUtils.remove(graph, enumerationIndexes, r); + } + }); + } catch (DatabaseException e1) { + e1.printStackTrace(); + } + + } + + @Override + public void widgetDefaultSelected(SelectionEvent e) { + + } + + } +} diff --git a/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/properties/ResourceSelectionProcessor.java b/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/properties/ResourceSelectionProcessor.java index cf603073..1bb77cb0 100644 --- a/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/properties/ResourceSelectionProcessor.java +++ b/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/properties/ResourceSelectionProcessor.java @@ -78,6 +78,13 @@ public class ResourceSelectionProcessor implements SelectionProcessor inputs = new ArrayList(); ArrayList modules = new ArrayList(); ArrayList stocks = new ArrayList(); + ArrayList enumerations = new ArrayList(); ArrayList inputDependencies = new ArrayList(); ArrayList outputDependencies = new ArrayList(); HashMap> moduleInputs = new HashMap>(); @@ -136,6 +138,8 @@ public class ModelicaWriter { } } else if (element instanceof Input) { inputs.add((Input)element); + } else if (element instanceof Enumeration) { + enumerations.add((Enumeration)element); } else if (element instanceof Dependency && ((Dependency)element).refersTo() != null) { Dependency dependency = (Dependency)element; if(dependency.getHead() instanceof Module) { @@ -172,6 +176,13 @@ public class ModelicaWriter { b.append(" " + i.getType() + " " + i.getName() + ";\n"); } } + + if(!enumerations.isEmpty()) { + b.append("// Enumeration definitions\n"); + for(Enumeration e : enumerations) { + b.append(e.getDeclaration()); + } + } for(Stock stock : stocks) { IExpression expr = stock.getExpression(); diff --git a/org.simantics.sysdyn/src/org/simantics/sysdyn/representation/Enumeration.java b/org.simantics.sysdyn/src/org/simantics/sysdyn/representation/Enumeration.java new file mode 100644 index 00000000..4176277f --- /dev/null +++ b/org.simantics.sysdyn/src/org/simantics/sysdyn/representation/Enumeration.java @@ -0,0 +1,31 @@ +package org.simantics.sysdyn.representation; + +import org.simantics.objmap.annotations.GraphType; +import org.simantics.objmap.annotations.RelatedElement; +import org.simantics.sysdyn.representation.visitors.IElementVisitorVoid; + +@GraphType("http://www.simantics.org/Sysdyn-1.0/Enumeration") +public class Enumeration extends Variable { + + @RelatedElement("http://www.simantics.org/Sysdyn-1.0/HasEnumerationIndexes") + private EnumerationIndexes enumerationIndexes; + + @Override + public void accept(IElementVisitorVoid v) { + v.visit(this); + } + + public String getDeclaration() { + StringBuilder sb = new StringBuilder(); + sb.append(" " + this.getType()); + sb.append(" " + this.name); + sb.append(" = enumeration("); + for(int i = 0; i < enumerationIndexes.getEnumerationIndexes().size(); i++) { + sb.append(enumerationIndexes.getEnumerationIndexes().get(i).getName()); + if(i < enumerationIndexes.getEnumerationIndexes().size() - 1) + sb.append(", "); + } + sb.append(");\n"); + return sb.toString(); + } +} diff --git a/org.simantics.sysdyn/src/org/simantics/sysdyn/representation/EnumerationIndex.java b/org.simantics.sysdyn/src/org/simantics/sysdyn/representation/EnumerationIndex.java new file mode 100644 index 00000000..9cbff869 --- /dev/null +++ b/org.simantics.sysdyn/src/org/simantics/sysdyn/representation/EnumerationIndex.java @@ -0,0 +1,16 @@ +package org.simantics.sysdyn.representation; + +import org.simantics.objmap.annotations.GraphType; +import org.simantics.objmap.annotations.RelatedValue; + +@GraphType("http://www.simantics.org/Sysdyn-1.0/EnumerationIndex") +public class EnumerationIndex { + + @RelatedValue("http://www.simantics.org/Layer0-1.0/HasName") + protected String name; + + public String getName() { + return this.name; + } + +} diff --git a/org.simantics.sysdyn/src/org/simantics/sysdyn/representation/EnumerationIndexes.java b/org.simantics.sysdyn/src/org/simantics/sysdyn/representation/EnumerationIndexes.java new file mode 100644 index 00000000..024a7b3e --- /dev/null +++ b/org.simantics.sysdyn/src/org/simantics/sysdyn/representation/EnumerationIndexes.java @@ -0,0 +1,17 @@ +package org.simantics.sysdyn.representation; + +import java.util.ArrayList; + +import org.simantics.objmap.annotations.GraphType; +import org.simantics.objmap.annotations.RelatedOrderedSetElements; + +@GraphType("http://www.simantics.org/Sysdyn-1.0/EnumerationIndexes") +public class EnumerationIndexes { + + @RelatedOrderedSetElements + private ArrayList enumerationIndexes = new ArrayList(); + + public ArrayList getEnumerationIndexes() { + return enumerationIndexes; + } +} diff --git a/org.simantics.sysdyn/src/org/simantics/sysdyn/representation/SysdynSchema.java b/org.simantics.sysdyn/src/org/simantics/sysdyn/representation/SysdynSchema.java index 745fd6ad..3c0888e0 100644 --- a/org.simantics.sysdyn/src/org/simantics/sysdyn/representation/SysdynSchema.java +++ b/org.simantics.sysdyn/src/org/simantics/sysdyn/representation/SysdynSchema.java @@ -37,6 +37,9 @@ public class SysdynSchema extends SimpleSchema { addLinkType(MappingSchemas.fromAnnotations(g, Input.class)); addLinkType(MappingSchemas.fromAnnotations(g, ModuleType.class)); addLinkType(MappingSchemas.fromAnnotations(g, Model.class)); + addLinkType(MappingSchemas.fromAnnotations(g, Enumeration.class)); + addLinkType(MappingSchemas.fromAnnotations(g, EnumerationIndex.class)); + addLinkType(MappingSchemas.fromAnnotations(g, EnumerationIndexes.class)); addLinkType(MappingSchemas.fromAnnotations(g, NormalExpression.class)); addLinkType(MappingSchemas.fromAnnotations(g, ParameterExpression.class)); addLinkType(MappingSchemas.fromAnnotations(g, StockExpression.class)); diff --git a/org.simantics.sysdyn/src/org/simantics/sysdyn/representation/visitors/ElementVisitorVoidAdapter.java b/org.simantics.sysdyn/src/org/simantics/sysdyn/representation/visitors/ElementVisitorVoidAdapter.java index fe3afd76..7a224f95 100644 --- a/org.simantics.sysdyn/src/org/simantics/sysdyn/representation/visitors/ElementVisitorVoidAdapter.java +++ b/org.simantics.sysdyn/src/org/simantics/sysdyn/representation/visitors/ElementVisitorVoidAdapter.java @@ -15,6 +15,7 @@ import org.simantics.sysdyn.representation.Auxiliary; import org.simantics.sysdyn.representation.Cloud; import org.simantics.sysdyn.representation.Configuration; import org.simantics.sysdyn.representation.Dependency; +import org.simantics.sysdyn.representation.Enumeration; import org.simantics.sysdyn.representation.Flow; import org.simantics.sysdyn.representation.Input; import org.simantics.sysdyn.representation.Module; @@ -58,4 +59,8 @@ public class ElementVisitorVoidAdapter implements IElementVisitorVoid { @Override public void visit(Configuration configuration) { } + + @Override + public void visit(Enumeration enumeration) { + } } diff --git a/org.simantics.sysdyn/src/org/simantics/sysdyn/representation/visitors/IElementVisitorVoid.java b/org.simantics.sysdyn/src/org/simantics/sysdyn/representation/visitors/IElementVisitorVoid.java index d7320342..0d560b2b 100644 --- a/org.simantics.sysdyn/src/org/simantics/sysdyn/representation/visitors/IElementVisitorVoid.java +++ b/org.simantics.sysdyn/src/org/simantics/sysdyn/representation/visitors/IElementVisitorVoid.java @@ -15,6 +15,7 @@ import org.simantics.sysdyn.representation.Auxiliary; import org.simantics.sysdyn.representation.Cloud; import org.simantics.sysdyn.representation.Configuration; import org.simantics.sysdyn.representation.Dependency; +import org.simantics.sysdyn.representation.Enumeration; import org.simantics.sysdyn.representation.Flow; import org.simantics.sysdyn.representation.Input; import org.simantics.sysdyn.representation.Module; @@ -32,4 +33,5 @@ public interface IElementVisitorVoid { void visit(Flow flow); void visit(Module module); void visit(Configuration configuration); + void visit(Enumeration enumeration); } -- 2.47.1