package org.simantics.db.indexing;
-import java.io.IOException;
import java.util.ArrayList;
import java.util.Collection;
import java.util.HashSet;
import org.simantics.db.common.request.ObjectsWithType;
import org.simantics.db.exception.DatabaseException;
import org.simantics.db.indexing.exception.IndexCorruptedException;
+import org.simantics.db.layer0.genericrelation.Dependencies;
import org.simantics.db.layer0.genericrelation.IndexQueries;
import org.simantics.db.layer0.genericrelation.IndexedRelations;
import org.simantics.db.layer0.util.Layer0Utils;
Layer0 L0 = Layer0.getInstance(graph);
HashSet<Resource> results = new HashSet<Resource>();
- String search = "Name:" + name;
+ String search = IndexQueries.quoteTerm(Dependencies.FIELD_NAME, name);
- for(Map<String, Object> entry : find(graph, model, search)) {
- Resource resource = (Resource)entry.get("Resource");
+ for(Resource resource : findResources(graph, model, search)) {
if(name.equals(graph.getPossibleRelatedValue(resource, L0.HasName, Bindings.STRING))) results.add(resource);
}
return results;
HashSet<Resource> results = new HashSet<Resource>();
Layer0 L0 = Layer0.getInstance(graph);
String typeName = graph.getRelatedValue(type, L0.HasName, Bindings.STRING);
- String search = "Types:" + IndexQueries.quoteTerm(typeName);
+ String search = IndexQueries.quoteTerm(Dependencies.FIELD_TYPES, typeName);
- for(Map<String, Object> entry : find(graph, model, search)) {
- Resource resource = (Resource)entry.get("Resource");
+ for(Resource resource : findResources(graph, model, search)) {
if(graph.isInstanceOf(resource, type)) results.add(resource);
}
return results;
HashSet<Resource> results = new HashSet<Resource>();
String typeName = graph.getRelatedValue(type, L0.HasName, Bindings.STRING);
- String search = "Types:" + IndexQueries.quoteTerm(typeName) + " AND Name:" + IndexQueries.quoteTerm(name);
+
+ String search = IndexQueries.and(IndexQueries.quoteTerm(Dependencies.FIELD_TYPES, typeName), IndexQueries.quoteTerm(Dependencies.FIELD_NAME, name));
- for(Map<String, Object> entry : find(graph, model, search)) {
- Resource resource = (Resource)entry.get("Resource");
+ for(Resource resource : findResources(graph, model, search)) {
if(graph.isInstanceOf(resource, type)) results.add(resource);
}
return results;
*******************************************************************************/
package org.simantics.db.indexing;
+import java.io.IOException;
import java.io.Reader;
import java.util.HashMap;
import java.util.Map;
import org.apache.lucene.analysis.Analyzer;
import org.apache.lucene.analysis.TokenFilter;
+import org.apache.lucene.analysis.TokenStream;
import org.apache.lucene.analysis.Tokenizer;
import org.apache.lucene.analysis.core.KeywordAnalyzer;
import org.apache.lucene.analysis.core.WhitespaceAnalyzer;
import org.apache.lucene.analysis.miscellaneous.PerFieldAnalyzerWrapper;
import org.apache.lucene.analysis.pattern.PatternReplaceFilter;
import org.apache.lucene.analysis.pattern.PatternTokenizer;
+import org.apache.lucene.analysis.tokenattributes.CharTermAttribute;
import org.apache.lucene.analysis.util.CharTokenizer;
import org.apache.lucene.queryparser.classic.ParseException;
import org.apache.lucene.queryparser.classic.QueryParser;
import org.apache.lucene.util.AttributeFactory;
import org.apache.lucene.util.Version;
import org.simantics.databoard.util.ObjectUtils;
+import org.simantics.db.layer0.genericrelation.Dependencies;
import org.simantics.utils.datastructures.Pair;
public class Queries {
}
}
+ final static class LowercaseFilter extends TokenFilter {
+ private final CharTermAttribute termAtt = addAttribute(CharTermAttribute.class);
+
+ public LowercaseFilter(TokenStream in) {
+ super(in);
+ }
+
+ @Override
+ public boolean incrementToken() throws IOException {
+ if (!input.incrementToken()) return false;
+ String lowercase = termAtt.toString().toLowerCase();
+ termAtt.setEmpty().append(lowercase);
+ return true;
+ }
+ }
+
static final class TypeStringAnalyzer extends Analyzer {
+ private boolean lowercase;
- @Override
- protected TokenStreamComponents createComponents(String fieldName, Reader reader) {
+ public TypeStringAnalyzer(Boolean lowercase) {
+ this.lowercase = lowercase;
+ }
+
+ @Override
+ protected TokenStreamComponents createComponents(String fieldName, Reader reader) {
Tokenizer tokenizer = new PatternTokenizer(reader, Pattern.compile("(([^\\\\ ]|\\\\\\\\|\\\\ )+)( *)"), 1);
TokenFilter filter = new PatternReplaceFilter(tokenizer, Pattern.compile("(\\\\(\\\\| ))"), "$2", true);
- return new TokenStreamComponents(tokenizer, filter);
+ return new TokenStreamComponents(tokenizer, lowercase ? new LowercaseFilter(filter) : filter);
}
}
analyzerPerField.put("Resource", new KeywordAnalyzer());
analyzerPerField.put("GUID", new KeywordAnalyzer());
analyzerPerField.put("Name", new KeywordAnalyzer());
- analyzerPerField.put("Types", new TypeStringAnalyzer());
+ analyzerPerField.put("Types", new TypeStringAnalyzer(false));
+ analyzerPerField.put(Dependencies.FIELD_NAME_SEARCH, new LowerCaseWhitespaceAnalyzer(Version.LUCENE_4_9));
+ analyzerPerField.put(Dependencies.FIELD_TYPES_SEARCH, new TypeStringAnalyzer(true));
PerFieldAnalyzerWrapper analyzer = new PerFieldAnalyzerWrapper(new LowerCaseWhitespaceAnalyzer(Version.LUCENE_4_9), analyzerPerField);
return analyzer;
public static final String FIELD_NAME = "Name";
public static final String FIELD_TYPES = "Types";
public static final String FIELD_GUID = "GUID";
+ public static final String FIELD_NAME_SEARCH = "NameSearch";
+ public static final String FIELD_TYPES_SEARCH = "TypesSearch";
protected Resource getIndexRelation(ReadGraph graph) {
return Layer0X.getInstance(graph).DependenciesRelation;
}
protected static String getBindingPattern() {
- return "bfffff";
+ return "bfffffff";
}
@Override
Pair.make(Dependencies.FIELD_RESOURCE, "Long"),
Pair.make(Dependencies.FIELD_NAME, "String"),
Pair.make(Dependencies.FIELD_TYPES, "Text"),
- Pair.make(Dependencies.FIELD_GUID, "Text")
+ Pair.make(Dependencies.FIELD_GUID, "Text"),
+ Pair.make(Dependencies.FIELD_NAME_SEARCH, "Text"),
+ Pair.make(Dependencies.FIELD_TYPES_SEARCH, "Text")
};
final Resource resource;
ArrayList<Object[]> result = new ArrayList<Object[]>();
for (Entry entry : entries) {
if(entry.name == null) continue;
- result.add(new Object[] { ss.getRandomAccessId(entry.parent), ss.getRandomAccessId(entry.resource), entry.name, entry.types, entry.id });
+ result.add(new Object[] { ss.getRandomAccessId(entry.parent), ss.getRandomAccessId(entry.resource), entry.name, entry.types, entry.id, entry.name, entry.types });
}
return result;
@Override
public List<Map<String, Object>> query(RequestProcessor session, String search, String bindingPattern, Object[] constants, int maxResultCount) {
- if(!Dependencies.getBindingPattern().equals(bindingPattern)) throw new IllegalArgumentException("DependenciesRelation supports indexing only with 'bfffff'");
+ if(!Dependencies.getBindingPattern().equals(bindingPattern)) throw new IllegalArgumentException("DependenciesRelation supports indexing only with 'bfffffff'");
IndexedRelations indexer = session.getService(IndexedRelations.class);
return indexer.query(null, search, session, resource, (Resource)constants[0], maxResultCount);
}
@Override
public List<Resource> queryResources(RequestProcessor session, String search, String bindingPattern, Object[] constants, int maxResultCount) {
- if(!Dependencies.getBindingPattern().equals(bindingPattern)) throw new IllegalArgumentException("DependenciesRelation supports indexing only with 'bfffff'");
+ if(!Dependencies.getBindingPattern().equals(bindingPattern)) throw new IllegalArgumentException("DependenciesRelation supports indexing only with 'bfffffff'");
IndexedRelations indexer = session.getService(IndexedRelations.class);
return indexer.queryResources(null, search, session, resource, (Resource)constants[0], maxResultCount);
}
@Override
public List<Map<String, Object>> list(RequestProcessor session, String bindingPattern, Object[] constants, int maxResultCount) {
- if(!Dependencies.getBindingPattern().equals(bindingPattern)) throw new IllegalArgumentException("DependenciesRelation supports indexing only with 'bfffff'");
+ if(!Dependencies.getBindingPattern().equals(bindingPattern)) throw new IllegalArgumentException("DependenciesRelation supports indexing only with 'bfffffff'");
IndexedRelations indexer = session.getService(IndexedRelations.class);
return indexer.query(null, null, session, resource, (Resource)constants[0], maxResultCount);
}
if(!entry.isValid(graph)) continue;
Resource parent = graph.getPossibleObject(entry.component, L0.PartOf);
if (parent != null) {
- _additions.add(new Object[] { ss.getRandomAccessId(parent), ss.getRandomAccessId(entry.component), name, types, id != null ? id.indexString() : "" });
+ _additions.add(new Object[] { ss.getRandomAccessId(parent), ss.getRandomAccessId(entry.component), name, types, id != null ? id.indexString() : "", name, types});
} else {
//LOGGER.info("resource " + entry.component + ": no parent for entry " + name + " " + types);
}
if(part != null) {
_replacementKeys.add(ss.getRandomAccessId(entry.component));
_replacementObjects.add(new Object[] { ss.getRandomAccessId(part),
- ss.getRandomAccessId(entry.component), name, types, id != null ? id.indexString() : "" });
+ ss.getRandomAccessId(entry.component), name, types, id != null ? id.indexString() : "", name, types});
}
}
}
ArrayList<Object[]> result = new ArrayList<Object[]>(entries.size());
for (Entry entry : entries) {
- result.add(new Object[] { ss.getRandomAccessId(entry.parent), ss.getRandomAccessId(entry.resource), entry.name, entry.types, entry.id });
+ result.add(new Object[] { ss.getRandomAccessId(entry.parent), ss.getRandomAccessId(entry.resource), entry.name, entry.types, entry.id, entry.name, entry.types });
}
Layer0X L0X = Layer0X.getInstance(graph);
import org.simantics.scl.runtime.function.UnsaturatedFunction2;
/**
- * dependencies:
- * (ReadGraph, Resource model, String query) -> List<Map<String, Object>>
- * (ReadGraph, Resource model, String query, Integer maxResults) -> List<Map<String, Object>>
+ * dependencyResources:
+ * (ReadGraph, Resource model, String query) -> List<Resource>
+ * (ReadGraph, Resource model, String query, Integer maxResults) -> List<Resource>
*
* @author Antti Villberg
*/
public class DependencyResources extends FunctionImpl4<ReadGraph, Resource, String, Integer, Object> {
- public static final String FIELD_MODEL = "Model";
- public static final String FIELD_PARENT = "Parent";
- public static final String FIELD_RESOURCE = "Resource";
- public static final String FIELD_NAME = "Name";
- public static final String FIELD_TYPES = "Types";
-
protected Resource getIndexRelation(ReadGraph graph) {
return Layer0X.getInstance(graph).DependenciesRelation;
}
}
public static String escapeTerm(String field, String term, boolean escapeWildcards) {
- StringBuilder sb = new StringBuilder();
- return escapeTerm(field, term, escapeWildcards, sb).toString();
+ return escapeTerm(field, term, escapeWildcards, new StringBuilder()).toString();
}
-
+
+ public static StringBuilder quoteTerm(String field, String term, StringBuilder result) {
+ if (field != null)
+ result.append(field).append(':');
+ result.append("\"");
+ result.append(term.replaceAll("(\"|\\\\)", "\\\\$0"));
+ result.append("\"");
+ return result;
+ }
+
public static String quoteTerm(String term) {
- StringBuilder sb = new StringBuilder();
- sb.append("\"");
- sb.append(term.replaceAll("(\"|\\\\)", "\\\\$0"));
- sb.append("\"");
+ return quoteTerm(null, term, new StringBuilder(term.length()*2)).toString();
+ }
+
+ public static String quoteTerm(String field, String term) {
+ return quoteTerm(field, term,
+ new StringBuilder(
+ term.length()*2
+ + (field != null ? field.length() + 1 : 0))
+ ).toString();
+ }
+
+ private static String join(String withString, String... exps) {
+ if (exps.length == 0)
+ return "";
+ StringBuilder sb = new StringBuilder(128);
+ for (int i = 0; i < exps.length - 1; ++i) {
+ sb.append(exps[i]).append(withString);
+ }
+ sb.append(exps[exps.length - 1]);
return sb.toString();
}
+ public static String and(String exp1, String exp2) {
+ return exp1 + " AND " + exp2;
+ }
+
+ public static String and(String... exps) {
+ return join(" AND ", exps);
+ }
+
+ public static String or(String exp1, String exp2) {
+ return exp1 + " OR " + exp2;
+ }
+
+ public static String or(String... exps) {
+ return join(" OR ", exps);
+ }
+
// public static void main(String[] args) {
// System.out.println("esc: " + escape("AND01", true, true));
// System.out.println("esc: " + escape("AND 01", true, true));
package org.simantics.debug.ui;
import java.util.ArrayList;
+import java.util.Arrays;
import java.util.Collection;
import java.util.Collections;
import java.util.Comparator;
import java.util.TreeSet;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
+import java.util.stream.Collectors;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IProgressMonitor;
import org.simantics.db.common.uri.UnescapedChildMapOfResource;
import org.simantics.db.common.utils.NameUtils;
import org.simantics.db.exception.DatabaseException;
+import org.simantics.db.layer0.genericrelation.Dependencies;
+import org.simantics.db.layer0.genericrelation.IndexQueries;
import org.simantics.db.layer0.migration.OntologiesFromLibrary;
import org.simantics.db.layer0.variable.Variables.Role;
import org.simantics.db.request.Read;
}
}
} else {
+ String[] terms = pattern.trim().split("\\s+"); //$NON-NLS-1$
+ if (terms.length == 0) return;
+
Resource project = Simantics.peekProjectResource();
if (project != null) {
IResourceFilter rf = resourceFilter;
String filter = getFilterForResourceFilter(rf);
if (!filter.isEmpty())
filter += " AND "; //$NON-NLS-1$
- filter += "Name:" + pattern + "*"; //$NON-NLS-1$ //$NON-NLS-2$
+
+ filter += Dependencies.FIELD_NAME_SEARCH + ":("; //$NON-NLS-1$
+ filter += Arrays.stream(terms).map(term -> "+" + IndexQueries.escape(term.toLowerCase(), false) + "*").collect(Collectors.joining(" ")); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
+ filter +=")"; //$NON-NLS-1$
Layer0 L0 = Layer0.getInstance(graph);
id="tspan6235"
x="4.0821486"
y="291.79337"
- style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:5.64444447px;font-family:'The Real Font';-inkscape-font-specification:'The Real Font';fill:#ffffff;fill-opacity:1;stroke-width:0.26458335px">1.39.0</tspan></text>
+ style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:5.64444447px;font-family:'The Real Font';-inkscape-font-specification:'The Real Font';fill:#ffffff;fill-opacity:1;stroke-width:0.26458335px">1.40.0</tspan></text>
<circle
style="opacity:0.92900002;fill:#5d6b91;fill-opacity:1;stroke:none;stroke-width:1.27400005;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1;filter:url(#filter6809)"
id="path6231"
import org.simantics.db.Resource;
import org.simantics.db.exception.DatabaseException;
import org.simantics.db.layer0.adapter.ActionFactory;
+import org.simantics.db.layer0.genericrelation.Dependencies;
import org.simantics.db.request.Read;
import org.simantics.document.linking.ontology.DocumentLink;
import org.simantics.layer0.Layer0;
});
ISearchService searchService = (ISearchService) PlatformUI.getWorkbench().getService(ISearchService.class);
SearchQuery query = new SearchQuery(name);
- query.setSearchFlag("Name", "on"); //$NON-NLS-1$ //$NON-NLS-2$
+ query.setSearchFlag(Dependencies.FIELD_NAME_SEARCH, "on"); //$NON-NLS-1$
query.setSearchFlag(DocumentLink.URIs.SearchFunction, "on"); //$NON-NLS-1$
searchService.performQuery(query, ISearchService.ResultBrowser.VIEW, true);
} catch (DatabaseException e) {
import org.simantics.db.common.utils.NameUtils;
import org.simantics.db.exception.DatabaseException;
import org.simantics.db.layer0.adapter.Instances;
+import org.simantics.db.layer0.genericrelation.Dependencies;
import org.simantics.document.linking.ontology.DocumentLink;
import org.simantics.document.linking.utils.SourceLinkUtil;
import org.simantics.scl.runtime.function.FunctionImpl5;
SearchResult result = new SearchResult(columns);
Set<Resource> processed = new HashSet<Resource>();
- NameComparator c = new NameComparator(query.getQuery("Name")); //$NON-NLS-1$
-
+ NameComparator c = new NameComparator(query.getQuery(Dependencies.FIELD_NAME_SEARCH));
+
for (Resource source : results) {
// Prevent index corruption from producing duplicate results.
if (!processed.add(source))
public SearchResult apply(IProgressMonitor monitor, ReadGraph graph, Resource model, SearchQuery query, Integer maxResults) {
try {
Collection<Map<String, Object>> results = Searching.performSearch(graph, Layer0X.getInstance(graph).Dependencies, model,
- query.escaped(false).getQuery("Name","Types"), maxResults); //$NON-NLS-1$ //$NON-NLS-2$
+ query.escapedWithForcedCase(false, false).getQuery(Dependencies.FIELD_NAME_SEARCH, Dependencies.FIELD_TYPES_SEARCH), maxResults);
return generateSearchResults(graph, results);
} catch (DatabaseException e) {
Logger.defaultLogError(e);
import java.util.Arrays;
import java.util.Collection;
import java.util.List;
-import java.util.Map;
import java.util.concurrent.atomic.AtomicBoolean;
import org.eclipse.core.runtime.IProgressMonitor;
import org.simantics.db.exception.CancelTransactionException;
import org.simantics.db.exception.DatabaseException;
import org.simantics.db.layer0.genericrelation.Dependencies;
+import org.simantics.db.layer0.genericrelation.IndexQueries;
import org.simantics.db.layer0.request.PossibleModel;
import org.simantics.event.Activator;
import org.simantics.event.ontology.EventResource;
if (model == null)
throw new CancelTransactionException();
- indexFunction = graph.adapt(L0X.Dependencies, Function.class);
+ indexFunction = graph.adapt(L0X.DependencyResources, Function.class);
if (!initialEventsResolved) {
MapList<String, Resource> initialEventsBySource = new MapList<String,Resource>();
monitor.subTask("Resolve events with source " + sourceName);
if (DEBUG)
System.out.println(EventSourceResolver.this + ": resolving source name " + sourceName);
- List<Map<String, Object>> results = (List<Map<String, Object>>) indexFunction.apply(graph, model, "Name:" + sourceName);
- for (Map<String, Object> result : results) {
- Resource r = (Resource) result.get(Dependencies.FIELD_RESOURCE);
+ List<Resource> results = (List<Resource>) indexFunction.apply(graph, model,
+ IndexQueries.quoteTerm(Dependencies.FIELD_NAME, sourceName));
+ for (Resource r : results) {
if (eventSourceFilter != null && !eventSourceFilter.accept(graph, r))
continue;
Resource rModel = graph.sync(new PossibleModel(r));
List<Resource> l = ListUtils.toList(graph, list);
if (l.size() > 0) {
Resource mainContext = l.get(0);
- if (!graph.hasStatement(mainContext))
+ if (!BatchValidations.isLinkedToOtherThan(graph, mainContext, issue))
result.add(mainContext);
}
}
import org.simantics.db.common.request.UnaryRead;
import org.simantics.db.common.utils.NameUtils;
import org.simantics.db.exception.DatabaseException;
+import org.simantics.db.layer0.genericrelation.Dependencies;
import org.simantics.db.layer0.genericrelation.IndexQueries;
import org.simantics.db.service.GraphChangeListenerSupport;
import org.simantics.layer0.Layer0;
*
* <p>
* The type of the function is expected to be:
- * <code>ReadGraph => Resource -> String -> Integer -> List<Map<String,Object>></code>
+ * <code>ReadGraph => Resource -> String -> Integer -> List<Resource></code>
*
* @author Tuukka Lehtonen
*
synchronized (this) {
- String search = "Name:" + lowercaseName + "*";
+ String search = IndexQueries.escapeTerm(Dependencies.FIELD_NAME_SEARCH, lowercaseName, true) + "*"; //$NON-NLS-1$
@SuppressWarnings("unchecked")
List<Resource> components = (List<Resource>) index.apply(graph, indexRoot, search, Integer.MAX_VALUE);
synchronized (this) {
- String search = "Name:" + proposition + "*";
+ String search = Dependencies.FIELD_NAME_SEARCH + ":" + IndexQueries.escape(proposition.toLowerCase(), true) + "*"; //$NON-NLS-1$ //$NON-NLS-2$
Set<String> reserved = graph.syncRequest(new ComponentsRequest(new Tuple4(indexRoot, index, search, getComparator())), TransientCacheAsyncListener.instance());
if (propositionPreFilter != null)
proposition = propositionPreFilter.apply(proposition);
- String search = "Name:" + IndexQueries.quoteTerm( proposition );
+ String search = IndexQueries.quoteTerm(Dependencies.FIELD_NAME_SEARCH, proposition.toLowerCase());
@SuppressWarnings("unchecked")
List<Resource> components = (List<Resource>) index.apply(graph, indexRoot, search, Integer.MAX_VALUE);
import org.eclipse.core.runtime.SubMonitor;
import org.simantics.Simantics;
import org.simantics.db.Issue;
+import org.simantics.db.ReadGraph;
import org.simantics.db.Resource;
import org.simantics.db.Session;
+import org.simantics.db.Statement;
import org.simantics.db.VirtualGraph;
import org.simantics.db.WriteGraph;
import org.simantics.db.common.request.WriteRequest;
return result;
}
+ /**
+ * Checks if the specified <code>resourceToCheckForLinks</code> is linked to
+ * anything else besides itself and <code>excludeLinksTo</code>.
+ *
+ * <p>
+ * This is used to if an issue context is still valid. We consider any issue
+ * context that is not attached to something else besides its issue context to
+ * be an invalid issue. Assertions and L0.InstanceOf do not count as external
+ * links.
+ *
+ * @param graph database access handle
+ * @param resourceToCheckForLinks the resource to check for "external" links
+ * @param excludeLinksTo exclude links to this resource from evaluation
+ * @return <code>true</code> if there are links, <code>false</code> otherwise
+ * @throws DatabaseException
+ */
+ public static boolean isLinkedToOtherThan(ReadGraph graph, Resource resourceToCheckForLinks,
+ Resource excludeLinksTo)
+ throws DatabaseException
+ {
+ Layer0 L0 = Layer0.getInstance(graph);
+ for (Statement stm : graph.getStatements(resourceToCheckForLinks, L0.IsWeaklyRelatedTo)) {
+ if (stm.isAsserted(resourceToCheckForLinks))
+ continue;
+ if (stm.getPredicate().equals(L0.InstanceOf))
+ continue;
+ Resource o = stm.getObject();
+ if (o.equals(excludeLinksTo) || o.equals(resourceToCheckForLinks))
+ continue;
+
+ return true;
+ }
+ return false;
+ }
+
}
<elements xsi:type="commands:Handler" xmi:id="__O4KgKMJEeW8eee008tTJw" elementId="org.simantics.simulation.ui.handler.run" contributionURI="bundleclass://org.simantics.simulation.ui/org.simantics.simulation.ui.handlers.e4.Run" command="_38VJ8KMJEeW8eee008tTJw"/>
<elements xsi:type="commands:Handler" xmi:id="_TDgKkKMVEeW8eee008tTJw" elementId="org.simantics.simulation.ui.handler.step" contributionURI="bundleclass://org.simantics.simulation.ui/org.simantics.simulation.ui.handlers.e4.Step" command="_NxXikKMVEeW8eee008tTJw"/>
<elements xsi:type="commands:Handler" xmi:id="__eyi4KMWEeW8eee008tTJw" elementId="org.simantics.simulation.ui.handler.setduration" contributionURI="bundleclass://org.simantics.simulation.ui/org.simantics.simulation.ui.handlers.e4.SetDuration" command="_PhrCkKMVEeW8eee008tTJw"/>
+ <elements xsi:type="commands:Handler" xmi:id="_EnmMQGtCEemEZc07DWbcZA" elementId="org.simantics.simulation.ui.handler.setendtime" contributionURI="bundleclass://org.simantics.simulation.ui/org.simantics.simulation.ui.handlers.e4.SetEndTime" command="_-IPjMGtBEemEZc07DWbcZA"/>
<elements xsi:type="commands:Handler" xmi:id="_uxvLIKPkEeW8eee008tTJw" elementId="org.simantics.simulation.ui.handler.reload" contributionURI="bundleclass://org.simantics.simulation.ui/org.simantics.simulation.ui.handlers.e4.Reload" command="_r2lBkKPkEeW8eee008tTJw"/>
<elements xsi:type="commands:Handler" xmi:id="_l75g8KPmEeW8eee008tTJw" elementId="org.simantics.simulation.ui.handler.savestate" contributionURI="bundleclass://org.simantics.simulation.ui/org.simantics.simulation.ui.handlers.e4.SaveState" command="_kjF68KPmEeW8eee008tTJw"/>
</fragments>
<elements xsi:type="commands:Command" xmi:id="_38VJ8KMJEeW8eee008tTJw" elementId="org.simantics.simulation.ui.command.run" commandName="Run Simulation" description="Runs active simulator" category="_mEzHsKMJEeW8eee008tTJw"/>
<elements xsi:type="commands:Command" xmi:id="_NxXikKMVEeW8eee008tTJw" elementId="org.simantics.simulation.ui.command.step" commandName="Step" category="_mEzHsKMJEeW8eee008tTJw"/>
<elements xsi:type="commands:Command" xmi:id="_PhrCkKMVEeW8eee008tTJw" elementId="org.simantics.simulation.ui.command.setduration" commandName="Set Duration" category="_mEzHsKMJEeW8eee008tTJw"/>
+ <elements xsi:type="commands:Command" xmi:id="_-IPjMGtBEemEZc07DWbcZA" elementId="org.simantics.simulation.ui.command.setendtime" commandName="Set End Time" category="_mEzHsKMJEeW8eee008tTJw"/>
<elements xsi:type="commands:Command" xmi:id="_r2lBkKPkEeW8eee008tTJw" elementId="org.simantics.simulation.ui.command.reload" commandName="Reload"/>
<elements xsi:type="commands:Command" xmi:id="_kjF68KPmEeW8eee008tTJw" elementId="org.simantics.simulation.ui.command.savestate" commandName="Save State"/>
</fragments>
categoryId="org.simantics.simulation.ui.category"
id="org.simantics.simulation.ui.dispose">
</command>
- <command
- defaultHandler="org.simantics.simulation.ui.handlers.SetDuration"
- name="Set Duration"
- categoryId="org.simantics.simulation.ui.category"
- id="org.simantics.simulation.ui.setDuration">
- </command>
<command
defaultHandler="org.simantics.simulation.ui.handlers.SaveState"
name="Save State"
+++ /dev/null
-/*******************************************************************************
- * 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.simulation.ui.handlers;
-
-import org.eclipse.core.commands.AbstractHandler;
-import org.eclipse.core.commands.Command;
-import org.eclipse.core.commands.ExecutionEvent;
-import org.eclipse.core.commands.ExecutionException;
-import org.eclipse.jface.dialogs.InputDialog;
-import org.eclipse.ui.PlatformUI;
-import org.eclipse.ui.commands.ICommandService;
-import org.osgi.service.prefs.BackingStoreException;
-import org.simantics.simulation.ui.preferences.SimulationPreferenceUtil;
-import org.simantics.simulation.ui.preferences.SimulationPreferences;
-import org.simantics.utils.ui.ExceptionUtils;
-import org.simantics.utils.ui.validators.DoubleValidator;
-
-public class SetDuration extends AbstractHandler {
-
- @Override
- public Object execute(ExecutionEvent event) throws ExecutionException {
- SimulationPreferences prefs = SimulationPreferenceUtil.getPrefs();
-
- InputDialog dialog = new InputDialog(PlatformUI.getWorkbench().getActiveWorkbenchWindow().getShell(),
- "Set Simulation Step Duration", "Simulation step duration in seconds", "" + prefs.stepDuration, new DoubleValidator());
- if (dialog.open() == InputDialog.OK) {
- final double duration = Double.parseDouble(dialog.getValue());
- try {
- SimulationPreferenceUtil.flushPrefs(new SimulationPreferences(duration));
- } catch (BackingStoreException e) {
- ExceptionUtils.logAndShowError(e);
- }
-
- // Update tool-tip for Step command
- ICommandService service = (ICommandService) PlatformUI.getWorkbench().getService(ICommandService.class);
- Command command = service.getCommand("org.simantics.simulation.ui.step");
- service.refreshElements(command.getId(), null);
-
-// IExperimentManager manager = SimanticsUI.getProject2().getHint(IExperimentManager.KEY_EXPERIMENT_MANAGER);
-// IExperiment experiment = manager.getActiveExperiment();
-// if (experiment instanceof IDynamicExperiment)
-// ((IDynamicExperiment) experiment).simulateDuration(duration);
- }
-
- return null;
- }
-
-}
*******************************************************************************/
package org.simantics.simulation.ui.handlers.e4;
+import javax.inject.Inject;
+
import org.eclipse.e4.core.di.annotations.Execute;
+import org.eclipse.e4.core.di.annotations.Optional;
import org.eclipse.e4.core.services.events.IEventBroker;
-import org.eclipse.e4.ui.internal.workbench.E4Workbench;
+import org.eclipse.e4.ui.di.UIEventTopic;
+import org.eclipse.e4.ui.model.application.MApplication;
+import org.eclipse.e4.ui.model.application.ui.menu.MMenuItem;
+import org.eclipse.e4.ui.workbench.modeling.EModelService;
import org.eclipse.jface.dialogs.InputDialog;
import org.eclipse.ui.PlatformUI;
import org.osgi.service.prefs.BackingStoreException;
import org.simantics.simulation.SimulationEvents;
import org.simantics.simulation.ui.preferences.SimulationPreferenceUtil;
import org.simantics.simulation.ui.preferences.SimulationPreferences;
+import org.simantics.simulation.ui.preferences.SimulationPreferences.StepMode;
import org.simantics.utils.ui.ExceptionUtils;
-import org.simantics.utils.ui.validators.DoubleValidator;
public class SetDuration {
+ private static final String SET_DURATION_ITEM_ID = "org.simantics.simulation.ui.handledmenuitem.setduration";
+
+ @Inject
+ private EModelService modelService;
+
+ @Inject
private IEventBroker eventBroker;
-
- public SetDuration() {
- eventBroker = E4Workbench.getServiceContext().get(IEventBroker.class);
- }
-
+
@Execute
- public void execute() {
+ public void execute(MMenuItem item) {
+ // This is a radio menu item, execute is called also when it is deselected
+ if (!item.isSelected())
+ return;
+
SimulationPreferences prefs = SimulationPreferenceUtil.getPrefs();
- InputDialog dialog = new InputDialog(PlatformUI.getWorkbench().getActiveWorkbenchWindow().getShell(),
- "Set Simulation Step Duration", "Simulation step duration in seconds", "" + prefs.stepDuration, new DoubleValidator());
+ TimeInputDialog dialog = new TimeInputDialog(PlatformUI.getWorkbench().getActiveWorkbenchWindow().getShell(),
+ "Set Simulation Step Duration", "simulation step duration", "" + prefs.stepDuration);
if (dialog.open() == InputDialog.OK) {
final double duration = Double.parseDouble(dialog.getValue());
try {
- SimulationPreferenceUtil.flushPrefs(new SimulationPreferences(duration));
+ SimulationPreferenceUtil.flushPrefs(prefs.withDuration(duration).withStepMode(StepMode.DURATION));
eventBroker.post(SimulationEvents.TOPIC_STEP_DURATION, duration);
+ eventBroker.post(SimulationEvents.TOPIC_STEP_MODE, StepMode.DURATION);
} catch (BackingStoreException e) {
ExceptionUtils.logAndShowError(e);
}
+ } else {
+ eventBroker.post(SimulationEvents.TOPIC_STEP_MODE, prefs.stepMode);
}
}
+ @Inject
+ @Optional
+ public void updateElement(@Optional @UIEventTopic(SimulationEvents.TOPIC_STEP_MODE) StepMode mode, MApplication application) {
+ WorkbenchUtil.setMenuItemSelected(modelService, application, Step.HANDLED_ITEM_ID, SET_DURATION_ITEM_ID, mode == StepMode.DURATION);
+ }
+
}
--- /dev/null
+/*******************************************************************************
+ * 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.simulation.ui.handlers.e4;
+
+import java.text.ParseException;
+
+import javax.inject.Inject;
+
+import org.eclipse.e4.core.di.annotations.Execute;
+import org.eclipse.e4.core.di.annotations.Optional;
+import org.eclipse.e4.core.services.events.IEventBroker;
+import org.eclipse.e4.ui.di.UIEventTopic;
+import org.eclipse.e4.ui.model.application.MApplication;
+import org.eclipse.e4.ui.model.application.ui.menu.MMenuItem;
+import org.eclipse.e4.ui.workbench.modeling.EModelService;
+import org.eclipse.jface.dialogs.InputDialog;
+import org.eclipse.ui.PlatformUI;
+import org.osgi.service.prefs.BackingStoreException;
+import org.simantics.simulation.SimulationEvents;
+import org.simantics.simulation.experiment.SimulationTimeUtil;
+import org.simantics.simulation.ui.preferences.SimulationPreferenceUtil;
+import org.simantics.simulation.ui.preferences.SimulationPreferences;
+import org.simantics.simulation.ui.preferences.SimulationPreferences.StepMode;
+import org.simantics.utils.ui.ExceptionUtils;
+
+/**
+ * @author Tuukka Lehtonen
+ * @since 1.39.0
+ */
+public class SetEndTime {
+
+ private static final String SET_END_TIME_ITEM_ID = "org.simantics.simulation.ui.handledmenuitem.setendtime";
+
+ @Inject
+ private EModelService modelService;
+
+ @Inject
+ private IEventBroker eventBroker;
+
+ @Execute
+ public void execute(MMenuItem item) {
+ // This is a radio menu item, execute is called also when it is deselected
+ if (!item.isSelected())
+ return;
+
+ SimulationPreferences prefs = SimulationPreferenceUtil.getPrefs();
+
+ InputDialog dialog = new TimeInputDialog(PlatformUI.getWorkbench().getActiveWorkbenchWindow().getShell(),
+ "Set Simulation Step End Time", "simulation step end time", "" + prefs.stepEndTime);
+ if (dialog.open() == InputDialog.OK) {
+ try {
+ double endTime = (double) SimulationTimeUtil.getTimeFormat().parseObject(dialog.getValue());
+ SimulationPreferenceUtil.flushPrefs(prefs.withEndTime(endTime).withStepMode(StepMode.END_TIME));
+ eventBroker.post(SimulationEvents.TOPIC_STEP_END_TIME, endTime);
+ eventBroker.post(SimulationEvents.TOPIC_STEP_MODE, StepMode.END_TIME);
+ } catch (BackingStoreException e) {
+ ExceptionUtils.logAndShowError(e);
+ } catch (ParseException e) {
+ ExceptionUtils.logAndShowError(e);
+ }
+ } else {
+ eventBroker.post(SimulationEvents.TOPIC_STEP_MODE, prefs.stepMode);
+ }
+ }
+
+ @Inject
+ @Optional
+ public void updateElement(@Optional @UIEventTopic(SimulationEvents.TOPIC_STEP_MODE) StepMode mode, MApplication application) {
+ WorkbenchUtil.setMenuItemSelected(modelService, application, Step.HANDLED_ITEM_ID, SET_END_TIME_ITEM_ID, mode == StepMode.END_TIME);
+ }
+
+}
import org.eclipse.e4.core.di.annotations.Optional;
import org.eclipse.e4.ui.di.UIEventTopic;
import org.eclipse.e4.ui.model.application.MApplication;
+import org.eclipse.e4.ui.model.application.ui.MUILabel;
import org.eclipse.e4.ui.model.application.ui.menu.MHandledItem;
import org.eclipse.e4.ui.workbench.modeling.EModelService;
+import org.eclipse.osgi.util.NLS;
import org.simantics.Simantics;
import org.simantics.simulation.SimulationEvents;
import org.simantics.simulation.experiment.ExperimentUtil;
import org.simantics.simulation.experiment.IExperiment;
+import org.simantics.simulation.experiment.SimulationTimeUtil;
import org.simantics.simulation.project.IExperimentManager;
import org.simantics.simulation.ui.preferences.SimulationPreferenceUtil;
import org.simantics.simulation.ui.preferences.SimulationPreferences;
public class Step {
- private static final String HANDLED_ITEM_ID = "org.simantics.simulation.ui.handledtoolitem.step";
+ static final String HANDLED_ITEM_ID = "org.simantics.simulation.ui.handledtoolitem.step";
@Inject
EModelService modelService;
-
+
@PostConstruct
public void updateToolTip(MApplication application) {
MHandledItem handledItem = (MHandledItem) modelService.find(HANDLED_ITEM_ID, application);
if (handledItem != null) {
- SimulationPreferences prefs = SimulationPreferenceUtil.getPrefs();
- handledItem.setTooltip("Step " + prefs.stepDuration + "s");
+ updateItem(handledItem);
}
}
-
+
@CanExecute
public boolean canExecute() {
IExperimentManager manager = Simantics.getProject().getHint(IExperimentManager.KEY_EXPERIMENT_MANAGER);
return false;
return true;
}
-
+
@Execute
public void execute() {
SimulationPreferences prefs = SimulationPreferenceUtil.getPrefs();
- ExperimentUtil.step(prefs.stepDuration);
+ switch (prefs.stepMode) {
+ case DURATION:
+ ExperimentUtil.step(prefs.stepDuration);
+ break;
+ case END_TIME:
+ ExperimentUtil.stepUntil(prefs.stepEndTime);
+ break;
+ }
}
@Inject
@Optional
- public void updateElement(@UIEventTopic(SimulationEvents.TOPIC_STEP_DURATION) double duration, MApplication application) {
+ public void updateElement(@Optional @UIEventTopic(SimulationEvents.TOPIC_STEP_CHANGE) Object changed, MApplication application) {
MHandledItem handledItem = (MHandledItem) modelService.find(HANDLED_ITEM_ID, application);
if (handledItem != null) {
- handledItem.setTooltip("Step " + duration + "s");
+ updateItem(handledItem);
+ }
+ }
+
+ private static void updateItem(MUILabel item) {
+ SimulationPreferences prefs = SimulationPreferenceUtil.getPrefs();
+ switch (prefs.stepMode) {
+ case DURATION:
+ item.setTooltip(
+ NLS.bind("Step {0} s ({1})",
+ SimulationTimeUtil.formatSeconds(prefs.stepDuration),
+ SimulationTimeUtil.formatHMSS(prefs.stepDuration)));
+ break;
+ case END_TIME:
+ item.setTooltip(
+ NLS.bind("Step Until Simulation Time Reaches {0} s ({1})",
+ SimulationTimeUtil.formatSeconds(prefs.stepEndTime),
+ SimulationTimeUtil.formatHMSS(prefs.stepEndTime)));
+ break;
}
}
--- /dev/null
+package org.simantics.simulation.ui.handlers.e4;
+
+import java.text.ParseException;
+
+import org.eclipse.jface.dialogs.InputDialog;
+import org.eclipse.osgi.util.NLS;
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.layout.GridData;
+import org.eclipse.swt.widgets.Composite;
+import org.eclipse.swt.widgets.Control;
+import org.eclipse.swt.widgets.Shell;
+import org.eclipse.swt.widgets.Text;
+import org.simantics.simulation.experiment.SimulationTimeUtil;
+
+/**
+ * @author Tuukka Lehtonen
+ */
+public class TimeInputDialog extends InputDialog {
+
+ private Text statusText;
+
+ public TimeInputDialog(Shell parentShell, String dialogTitle, String topic, String initialValue) {
+ super(parentShell, dialogTitle, message(topic), initialValue, new TimeValidator());
+ }
+
+ @Override
+ protected Control createDialogArea(Composite parent) {
+ Composite composite = (Composite) super.createDialogArea(parent);
+
+ statusText = new Text(composite, SWT.READ_ONLY | SWT.WRAP);
+ statusText.setLayoutData(new GridData(GridData.GRAB_HORIZONTAL
+ | GridData.HORIZONTAL_ALIGN_FILL));
+
+ return composite;
+ }
+
+ @Override
+ protected void validateInput() {
+ super.validateInput();
+
+ try {
+ double t = (double) SimulationTimeUtil.getTimeFormat().parseObject(getText().getText());
+ statusText.setText(statusMessage(t));
+ } catch (ParseException e) {
+ statusText.setText("");
+ }
+ }
+
+ private static String message(String topic) {
+ return NLS.bind("Give {0} in seconds or timestamp format ([Yy] [Dd] HH:mm:ss.ddd)", topic);
+ }
+
+ private static String statusMessage(double time) {
+ return NLS.bind(
+ "Specified time is {0} s ({1})",
+ SimulationTimeUtil.formatSeconds(time),
+ SimulationTimeUtil.formatHMSS(time));
+ }
+
+}
--- /dev/null
+package org.simantics.simulation.ui.handlers.e4;
+
+import java.text.ParseException;
+
+import org.eclipse.jface.dialogs.IInputValidator;
+import org.eclipse.osgi.util.NLS;
+import org.simantics.simulation.experiment.SimulationTimeUtil;
+
+/**
+ * @author Tuukka Lehtonen
+ * @since 1.39.0
+ */
+class TimeValidator implements IInputValidator {
+
+ public String isValid(String s) {
+ try {
+ SimulationTimeUtil.getTimeFormat().parseObject(s);
+ return null;
+ } catch (ParseException e) {
+ return NLS.bind("\"{0}\" is not a valid timestamp.", s);
+ }
+ }
+
+}
\ No newline at end of file
--- /dev/null
+/*******************************************************************************
+ * Copyright (c) 2019 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:
+ * Semantum Oy - initial API and implementation
+ *******************************************************************************/
+package org.simantics.simulation.ui.handlers.e4;
+
+import org.eclipse.e4.ui.model.application.MApplication;
+import org.eclipse.e4.ui.model.application.ui.menu.MItem;
+import org.eclipse.e4.ui.model.application.ui.menu.MMenu;
+import org.eclipse.e4.ui.model.application.ui.menu.MToolItem;
+import org.eclipse.e4.ui.workbench.modeling.EModelService;
+
+/**
+ * @author Tuukka Lehtonen
+ * @since 1.39.0
+ */
+class WorkbenchUtil {
+
+ public static boolean setMenuItemSelected(EModelService modelService, MApplication application, String toolItemId, String menuItemId, boolean selected) {
+ MToolItem toolItem = (MToolItem) modelService.find(toolItemId, application);
+ if (toolItem != null) {
+ MMenu menu = toolItem.getMenu();
+ if (menu != null) {
+ MItem menuItem = (MItem) modelService.find(menuItemId, menu);
+ if (menuItem != null) {
+ menuItem.setSelected(selected);
+ return true;
+ }
+ }
+ }
+ return false;
+ }
+
+}
import org.osgi.service.prefs.BackingStoreException;
import org.osgi.service.prefs.Preferences;
import org.simantics.simulation.ui.Activator;
+import org.simantics.simulation.ui.preferences.SimulationPreferences.StepMode;
/**
public static SimulationPreferences getPrefs(IScopeContext context) {
IEclipsePreferences node = context.getNode(Activator.PLUGIN_ID);
double stepDuration = node.getDouble(SimulationPreferences.P_SIMULATION_STEP_DURATION, SimulationPreferences.DEFAULT_SIMULATION_STEP_DURATION);
+ double stepEndTime = node.getDouble(SimulationPreferences.P_SIMULATION_STEP_END_TIME, SimulationPreferences.DEFAULT_SIMULATION_STEP_END_TIME);
+ int stepMode = node.getInt(SimulationPreferences.P_SIMULATION_STEP_MODE, SimulationPreferences.DEFAULT_SIMULATION_STEP_MODE.ordinal());
- return new SimulationPreferences(node, stepDuration);
+ return new SimulationPreferences(node, stepDuration, stepEndTime, StepMode.fromInt(stepMode));
}
/**
private static IEclipsePreferences _setPrefs(IScopeContext context, SimulationPreferences prefs) {
IEclipsePreferences node = context.getNode(Activator.PLUGIN_ID);
node.putDouble(SimulationPreferences.P_SIMULATION_STEP_DURATION, prefs.stepDuration);
+ node.putDouble(SimulationPreferences.P_SIMULATION_STEP_END_TIME, prefs.stepEndTime);
+ node.putInt(SimulationPreferences.P_SIMULATION_STEP_MODE, prefs.stepMode.ordinal());
return node;
}
/*******************************************************************************
- * Copyright (c) 2007, 2010 Association for Decentralized Information Management
+ * Copyright (c) 2007, 2019 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
*
* Contributors:
* VTT Technical Research Centre of Finland - initial API and implementation
+ * Semantum Oy - added step end time and mode
*******************************************************************************/
package org.simantics.simulation.ui.preferences;
import org.eclipse.core.runtime.preferences.IEclipsePreferences;
+import org.simantics.utils.format.TimeFormat;
/**
* Constant definitions for plug-in preferences
public final class SimulationPreferences {
public static final String P_SIMULATION_STEP_DURATION = "simulation.step.duration";
+ public static final String P_SIMULATION_STEP_END_TIME = "simulation.step.endTime";
+ public static final String P_SIMULATION_STEP_MODE = "simulation.step.mode";
+
+ public static enum StepMode {
+ DURATION,
+ END_TIME;
+
+ public static StepMode fromInt(int stepMode) {
+ switch (stepMode) {
+ case 1: return END_TIME;
+ default: return DURATION;
+ }
+ }
+ }
public static final double DEFAULT_SIMULATION_STEP_DURATION = 0.1;
+ public static final double DEFAULT_SIMULATION_STEP_END_TIME = 0;
+ public static final StepMode DEFAULT_SIMULATION_STEP_MODE = StepMode.DURATION;
public static final SimulationPreferences DEFAULT_PREFS
- = new SimulationPreferences(null, DEFAULT_SIMULATION_STEP_DURATION);
+ = new SimulationPreferences(null,
+ DEFAULT_SIMULATION_STEP_DURATION,
+ DEFAULT_SIMULATION_STEP_END_TIME,
+ DEFAULT_SIMULATION_STEP_MODE);
public final IEclipsePreferences prefs;
public final double stepDuration;
+ public final double stepEndTime;
+ public final StepMode stepMode;
- public SimulationPreferences(double stepDuration) {
- this(null, stepDuration);
+ public SimulationPreferences(double stepDuration, double stepEndTime, StepMode stepMode) {
+ this(null, stepDuration, stepEndTime, stepMode);
}
- public SimulationPreferences(IEclipsePreferences prefs, double stepDuration) {
+ public SimulationPreferences(IEclipsePreferences prefs, double stepDuration, double stepEndTime, StepMode stepMode) {
this.prefs = prefs;
this.stepDuration = stepDuration;
+ this.stepEndTime = stepEndTime;
+ this.stepMode = stepMode;
+ }
+
+ public SimulationPreferences withDuration(double duration) {
+ return new SimulationPreferences(duration, stepEndTime, stepMode);
+ }
+
+ public SimulationPreferences withEndTime(double endTime) {
+ return new SimulationPreferences(stepDuration, endTime, stepMode);
+ }
+
+ public SimulationPreferences withStepMode(StepMode mode) {
+ return new SimulationPreferences(stepDuration, stepEndTime, mode);
}
@Override
public String toString() {
- return getClass().getSimpleName() + "[step duration=" + stepDuration + "]";
+ return getClass().getSimpleName()
+ + "[step duration=" + stepDuration
+ + ", step end time=" + stepEndTime
+ + ", step mode=" + stepMode
+ + "]";
}
}
public static final String TOPIC_STATE_CHANGE = "org/simantics/simulation/state/*";
public static final String TOPIC_STATE_RUNNING = "org/simantics/simulation/state/running";
public static final String TOPIC_STATE_STOPPED = "org/simantics/simulation/state/stopped";
+ public static final String TOPIC_STEP_CHANGE = "org/simantics/simulation/step/*";
public static final String TOPIC_STEP_DURATION = "org/simantics/simulation/step/duration";
-}
+ public static final String TOPIC_STEP_END_TIME = "org/simantics/simulation/step/endTime";
+ public static final String TOPIC_STEP_MODE = "org/simantics/simulation/step/mode";
+
+}
\ No newline at end of file
((IDynamicExperiment)experiment).simulateDuration(duration);
}
+ public static boolean canStepUntil(double endTime) {
+ IExperimentManager manager =
+ Simantics.getProject().getHint(IExperimentManager.KEY_EXPERIMENT_MANAGER);
+ IExperiment experiment = manager.getActiveExperiment();
+ if (experiment instanceof IDynamicExperiment) {
+ IDynamicExperiment exp = (IDynamicExperiment) experiment;
+ double currentTime = exp.getSimulationTime();
+ return currentTime < endTime;
+ }
+ return false;
+ }
+
+ public static void stepUntil(double endTime) {
+ IExperimentManager manager =
+ Simantics.getProject().getHint(IExperimentManager.KEY_EXPERIMENT_MANAGER);
+ IExperiment experiment = manager.getActiveExperiment();
+ if (experiment instanceof IDynamicExperiment) {
+ IDynamicExperiment exp = (IDynamicExperiment) experiment;
+ double currentTime = exp.getSimulationTime();
+ if (currentTime < endTime) {
+ exp.simulateDuration(endTime - currentTime);
+ }
+ }
+ }
+
public static void simulate(boolean enabled) {
IExperimentManager manager =
Simantics.getProject().getHint(IExperimentManager.KEY_EXPERIMENT_MANAGER);
*/
public void rewindTo(double time);
+ /**
+ * @return current simulation time
+ */
+ double getSimulationTime();
+
/**
* Ensure that the current state of the experiment at the time of invocation
* is stored so that it can be returned to during a later session.
return result;
}
+ public static TimeFormat getTimeFormat() {
+ return timeFormat;
+ }
+
}
</ul>
<div id="tabs-1">
<#list getAllSearchParams() as param>
- <input type="checkbox" name="${param}" value="on" <#if query.getBooleanFlag("${param}")> checked </#if>> ${param}
+ <input type="checkbox" name="${param.getName()}" value="on" <#if query.getBooleanFlag("${param.getName()}")> checked </#if>> ${param.getLabel()}
</#list>
</div>
<div id="tabs-2">
import org.simantics.db.Resource;
import org.simantics.db.common.utils.Logger;
import org.simantics.db.exception.DatabaseException;
+import org.simantics.db.layer0.genericrelation.Dependencies;
import org.simantics.operation.Layer0X;
import org.simantics.scl.runtime.function.FunctionImpl5;
public SearchResult apply(IProgressMonitor monitor, ReadGraph graph, Resource model, SearchQuery query, Integer maxResults) {
try {
Collection<Map<String, Object>> results = Searching.performSearch(graph,
- Layer0X.getInstance(graph).Dependencies, model, query.getQuery("Name","Types"), maxResults);
+ Layer0X.getInstance(graph).Dependencies, model,
+ query.escapedWithForcedCase(false, false).getQuery(Dependencies.FIELD_NAME_SEARCH, Dependencies.FIELD_TYPES_SEARCH),
+ maxResults);
return Searching.generateDependenciesSearchResult(graph, results);
} catch (DatabaseException e) {
import java.io.File;
import java.util.Collection;
-import java.util.HashSet;
-import java.util.Set;
+import java.util.Map;
+import java.util.TreeMap;
/**
return searchEngines;
}
- public Set<String> getAllSearchParams() {
- Set<String> params = new HashSet<String>();
- for (SearchEngine engine : searchEngines)
- params.addAll(engine.getSupportedParams());
- return params;
+ public Collection<SearchParam> getAllSearchParams() {
+ Map<String, SearchParam> params = new TreeMap<>();
+ for (SearchEngine engine : searchEngines) {
+ for (SearchParam param : engine.getSupportedParams()) {
+ params.put(param.getName(), param);
+ }
+ }
+ return params.values();
}
public NamedResource getModel() {
private String id;
private String name;
private Function5<IProgressMonitor, ReadGraph, Resource, SearchQuery, Integer, SearchResult> searchFunction;
- private Set<String> supportedParams = new HashSet<String>();
+ private Set<SearchParam> supportedParams = new HashSet<>();
private boolean enabledByDefault;
public SearchEngine(String id, Function5<IProgressMonitor, ReadGraph, Resource, SearchQuery, Integer, SearchResult> searchFunction, boolean enabledByDefault) {
return id.hashCode();
}
- public void addSupportedParam(String param) {
- this.supportedParams.add(param);
+ public void addSupportedParam(String name) {
+ addSupportedParam(name, name);
}
- public Set<String> getSupportedParams() {
+ public void addSupportedParam(String name, String label) {
+ this.supportedParams.add(new SearchParam(name, label));
+ }
+
+ public Set<SearchParam> getSupportedParams() {
return supportedParams;
}
--- /dev/null
+package org.simantics.workbench.search;
+
+public class SearchParam {
+ private String name;
+ private String label;
+
+ public SearchParam(String name, String label) {
+ this.name = name;
+ this.label = label;
+ }
+
+ public String getName() {
+ return name;
+ }
+
+ public String getLabel() {
+ return label;
+ }
+}
\ No newline at end of file
return withOriginalQuery( IndexQueries.escape( originalQuery, escapeWildcards ) );
}
+ /**
+ * @param uppercase <code>true</code> for uppercased query, <code>false</code>
+ * for lowercased query
+ * @return a clone of this query with the query string in lower or uppercase
+ */
+ public SearchQuery withForcedCase(boolean uppercase) {
+ return withOriginalQuery(uppercase ? originalQuery.toUpperCase() : originalQuery.toLowerCase());
+ }
+
+ /**
+ * @param uppercase <code>true</code> for uppercased query,
+ * <code>false</code> for lowercased query
+ * @param escapeWildcards passed to {@link #escaped(boolean)}
+ * @return a clone of this query with the query string escaped and in lower or
+ * uppercase
+ */
+ public SearchQuery escapedWithForcedCase(boolean uppercase, boolean escapeWildcards) {
+ return withForcedCase(uppercase).escaped(escapeWildcards);
+ }
+
public static URL encode(File file, SearchQuery query) throws IOException {
URL url = file.toURI().toURL();
String s = url.toString() + "?search=" + URLEncoder.encode(query.getOriginalQuery(), "UTF-8");
import org.eclipse.ui.part.ViewPart;
import org.simantics.Simantics;
import org.simantics.db.Session;
+import org.simantics.db.layer0.genericrelation.Dependencies;
import org.simantics.db.layer0.request.ActiveModels;
import org.simantics.db.management.ISessionContext;
import org.simantics.db.management.ISessionContextChangedListener;
protected void initializeViewContent() {
SearchQuery query = new SearchQuery("");
- query.setSearchFlag("Name", "on");
- query.setSearchFlag("Types", "on");
+ query.setSearchFlag(Dependencies.FIELD_NAME_SEARCH, "on");
+ query.setSearchFlag(Dependencies.FIELD_TYPES_SEARCH, "on");
ISearchService searchService = (ISearchService) PlatformUI.getWorkbench().getService(ISearchService.class);
if (searchService != null)
searchService.performQuery(query, ResultBrowser.VIEW, false);
import org.simantics.db.Session;
import org.simantics.db.exception.DatabaseException;
import org.simantics.db.layer0.adapter.Instances;
+import org.simantics.db.layer0.genericrelation.Dependencies;
import org.simantics.db.layer0.request.ActiveModels;
import org.simantics.db.request.Read;
import org.simantics.db.service.SerialisationSupport;
@SuppressWarnings("unchecked")
SearchEngine engine = new SearchEngine(id,name,(Function5<IProgressMonitor, ReadGraph, Resource, SearchQuery, Integer, SearchResult>)f, true);
{
- engine.addSupportedParam("Name");
- engine.addSupportedParam("Types");
+ engine.addSupportedParam(Dependencies.FIELD_NAME_SEARCH, "Name");
+ engine.addSupportedParam(Dependencies.FIELD_TYPES_SEARCH, "Types");
}
searchEngines.add(engine);
}
@SuppressWarnings("unchecked")
SearchEngine engine = new SearchEngine(id,name,(Function5<IProgressMonitor, ReadGraph, Resource, SearchQuery, Integer, SearchResult>)f, enabled);
{
- engine.addSupportedParam("Name");
- engine.addSupportedParam("Types");
+ engine.addSupportedParam(Dependencies.FIELD_NAME_SEARCH, "Name");
+ engine.addSupportedParam(Dependencies.FIELD_TYPES_SEARCH, "Types");
}
return engine;
}
import org.eclipse.swt.widgets.Text;
import org.eclipse.ui.PlatformUI;
import org.eclipse.ui.swt.IFocusService;
+import org.simantics.db.layer0.genericrelation.Dependencies;
import org.simantics.utils.ui.BundleUtils;
import org.simantics.workbench.search.ISearchService;
import org.simantics.workbench.search.SearchQuery;
query = filter(query);
SearchQuery searchQuery = new SearchQuery(originalInput);
- searchQuery.setSearchFlag("Name", "on");
+ searchQuery.setSearchFlag(Dependencies.FIELD_NAME_SEARCH, "on");
performQuery(searchQuery, browserType);
}
return;
SearchQuery searchQuery = new SearchQuery(originalInput);
- searchQuery.setSearchFlag("Types", "on");
+ searchQuery.setSearchFlag(Dependencies.FIELD_TYPES_SEARCH, "on");
performQuery(searchQuery, browserType);
}
return;
SearchQuery searchQuery = new SearchQuery(originalInput);
- searchQuery.setSearchFlag("Name", "on");
- searchQuery.setSearchFlag("Types", "on");
+ searchQuery.setSearchFlag(Dependencies.FIELD_NAME_SEARCH, "on");
+ searchQuery.setSearchFlag(Dependencies.FIELD_TYPES_SEARCH, "on");
performQuery(searchQuery, browserType);
}
<feature
id="org.simantics.sdk"
label="Simantics SDK"
- version="1.39.0.qualifier"
+ version="1.40.0.qualifier"
provider-name="VTT Technical Research Centre of Finland">
<description url="http://www.example.com/description">
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<?pde?>
<!-- generated with https://github.com/mbarbero/fr.obeo.releng.targetplatform -->
-<target name="Simantics 1.39.0" sequenceNumber="1536142643">
+<target name="Simantics 1.40.0" sequenceNumber="1536142643">
<locations>
<location includeMode="slicer" includeAllPlatforms="true" includeSource="true" includeConfigurePhase="false" type="InstallableUnit">
<unit id="com.google.guava" version="21.0.0.v20170206-1425"/>
-target "Simantics 1.39.0"
+target "Simantics 1.40.0"
with source allEnvironments
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<artifactId>org.simantics.sdk.repository</artifactId>
- <version>1.39.0-SNAPSHOT</version>
+ <version>1.40.0-SNAPSHOT</version>
<packaging>eclipse-repository</packaging>
<parent>
package org.simantics.scl.osgi.tests;
+import java.io.IOException;
+import java.nio.file.Files;
+import java.nio.file.Path;
+import java.nio.file.Paths;
+
import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.core.runtime.NullProgressMonitor;
import org.junit.AfterClass;
import org.simantics.application.arguments.IArgumentFactory;
import org.simantics.application.arguments.IArguments;
import org.simantics.application.arguments.SimanticsArguments;
+import org.simantics.scl.compiler.markdown.html.GenerateAllHtmlDocumentation;
import org.simantics.scl.osgi.SCLOsgi;
public class TestSCLOsgi {
Assert.fail(possibleError);
}
}
+
+ @Test
+ public void exportAllSCLDocumentation() throws IOException {
+ // "./scldoc" evaluates to "tests/org.simantics.scl.osgi.tests/scldoc" when these tests are ran with Tycho/Maven
+ Path dir = Paths.get("./target/scldoc");
+ Files.createDirectories(dir);
+ GenerateAllHtmlDocumentation.generate(SCLOsgi.MODULE_REPOSITORY, dir);
+ }
}