1 /*******************************************************************************
\r
2 * Copyright (c) 2010 Association for Decentralized Information Management in
\r
4 * All rights reserved. This program and the accompanying materials
\r
5 * are made available under the terms of the Eclipse Public License v1.0
\r
6 * which accompanies this distribution, and is available at
\r
7 * http://www.eclipse.org/legal/epl-v10.html
\r
10 * VTT Technical Research Centre of Finland - initial API and implementation
\r
11 *******************************************************************************/
\r
12 package org.simantics.sysdyn.ui.properties.widgets.expressions;
\r
14 import java.util.ArrayList;
\r
15 import java.util.Collections;
\r
17 import org.eclipse.jface.text.ITextViewer;
\r
18 import org.eclipse.jface.text.contentassist.CompletionProposal;
\r
19 import org.eclipse.jface.text.contentassist.ICompletionProposal;
\r
20 import org.eclipse.jface.text.contentassist.IContentAssistProcessor;
\r
21 import org.eclipse.jface.text.contentassist.IContextInformation;
\r
22 import org.eclipse.jface.text.contentassist.IContextInformationValidator;
\r
23 import org.eclipse.swt.widgets.Table;
\r
24 import org.eclipse.swt.widgets.TableItem;
\r
25 import org.simantics.db.ReadGraph;
\r
26 import org.simantics.db.Resource;
\r
27 import org.simantics.db.common.request.ObjectsWithType;
\r
28 import org.simantics.db.common.utils.NameUtils;
\r
29 import org.simantics.db.exception.DatabaseException;
\r
30 import org.simantics.db.request.Read;
\r
31 import org.simantics.layer0.Layer0;
\r
32 import org.simantics.sysdyn.SysdynResource;
\r
33 import org.simantics.ui.SimanticsUI;
\r
37 * IContentAssistProcessor to determine which options (the functions and
\r
38 * variables available) are shown for ContentAssistant; this assist of
\r
39 * text field allows long variable names to be selected from a popup menu.
\r
40 * @author Tuomas Miettinen
\r
43 public class CompletionProcessor implements IContentAssistProcessor {
\r
45 private Table allowedVariables;
\r
46 private ArrayList<String> functions;
\r
47 private ArrayList<String> variables = null;
\r
49 private final char[] allowedCharacters = {
\r
50 'a','b','c','d','e','f','g','h','i','j','k','l','m','n','o','p','q','r','s','t','u','v','w','x','y','z','å','ä','ö',
\r
51 'A','B','C','D','E','F','G','H','I','J','K','L','M','N','O','P','Q','R','S','T','U','V','W','X','Y','Z','Å','Ä','Ö',
\r
52 '1','2','3','4','5','6','7','8','9','0','.','_','(',')'};
\r
54 private final String allowedConnectedCharactersRegExp = "[\\Q({[:;,<=>+-*/^\\E]";
\r
56 public CompletionProcessor(Table allowedVariables, boolean allowFunctions){
\r
57 this.allowedVariables = allowedVariables;
\r
60 functions = new ArrayList<String>();
\r
61 if (allowFunctions) {
\r
63 functions = SimanticsUI.getSession().syncRequest(new Read<ArrayList<String>>() {
\r
65 public ArrayList<String> perform(ReadGraph graph)
\r
66 throws DatabaseException {
\r
67 SysdynResource sr = SysdynResource.getInstance(graph);
\r
68 Layer0 l0 = Layer0.getInstance(graph);
\r
69 ArrayList<String> functions = new ArrayList<String>();
\r
71 Resource funktionlibrary = graph.getPossibleResource(SysdynResource.URIs.Built$in_Functions);
\r
72 for(Resource r : graph.syncRequest(new ObjectsWithType(funktionlibrary, l0.ConsistsOf, sr.SysdynModelicaFunction))) {
\r
73 String name = NameUtils.getSafeName(graph, r);
\r
74 functions.add(name);
\r
77 Resource subfunktionlibrary = graph.getPossibleResource(SysdynResource.URIs.Built$in_Functions_Vensim_Functions);
\r
78 for(Resource r : graph.syncRequest(new ObjectsWithType(subfunktionlibrary, l0.ConsistsOf, sr.SysdynModelicaFunction))) {
\r
79 String name = NameUtils.getSafeName(graph, r);
\r
80 functions.add(name);
\r
87 catch (DatabaseException e) {
\r
88 e.printStackTrace();
\r
91 Collections.sort(functions);
\r
92 for (int i = 0; i < functions.size(); ++i) {
\r
93 functions.set(i, functions.get(i) + "()");
\r
97 private ICompletionProposal[] collectProposals(String token, int offset) {
\r
99 if (variables == null) {
\r
100 variables = new ArrayList<String>();
\r
101 if(allowedVariables != null && !allowedVariables.isDisposed()) {
\r
102 TableItem[] connectedVariables = allowedVariables.getItems();
\r
103 for(TableItem ti : connectedVariables) {
\r
104 this.variables.add(ti.getText());
\r
107 Collections.sort(variables);
\r
110 ArrayList<ICompletionProposal> resultArray = new ArrayList<ICompletionProposal>();
\r
111 for (String variable : variables) {
\r
112 if (token.length() == 0 || variable.toUpperCase().startsWith(token.toUpperCase())) {
\r
113 resultArray.add(new CompletionProposal(variable,
\r
114 offset - token.length(),
\r
116 variable.length()));
\r
119 for (String function : functions) {
\r
120 if (token.length() == 0 || function.toUpperCase().startsWith(token.toUpperCase())) {
\r
121 resultArray.add(new CompletionProposal(function,
\r
122 offset - token.length(),
\r
124 function.length() - 1));
\r
127 ICompletionProposal[] result = new ICompletionProposal[resultArray.size()];
\r
128 for (int i = 0; i < result.length; ++i) {
\r
129 result[i] = resultArray.get(i);
\r
135 public ICompletionProposal[] computeCompletionProposals(
\r
136 ITextViewer viewer, int offset) {
\r
137 String equation = viewer.getDocument().get();
\r
139 if (equation.length() == 0
\r
141 || Character.isWhitespace(equation.charAt(offset - 1))) {
\r
142 return collectProposals("", offset);
\r
145 equation = equation.substring(0, offset);
\r
147 // Split into tokens on whitespace characters
\r
148 String[] tokens = equation.split("[\\s]");
\r
149 if (tokens.length == 0) {
\r
150 return collectProposals("", offset);
\r
152 String token = tokens[tokens.length - 1];
\r
154 // If a '+', '-', etc. character is in the end, return all.
\r
155 if (allowedConnectedCharactersRegExp.indexOf(token.charAt(token.length() - 1)) != -1) {
\r
156 return collectProposals("", offset);
\r
159 // Split the last token on '+', '-', etc. characters
\r
160 String tokensOfLastToken[] = token.split(allowedConnectedCharactersRegExp);
\r
161 if (tokensOfLastToken.length == 0) {
\r
162 return collectProposals("", offset);
\r
164 token = tokensOfLastToken[tokensOfLastToken.length - 1];
\r
165 //System.out.println(token + "\noffset = " + offset);
\r
167 return collectProposals(token, offset);
\r
171 public IContextInformation[] computeContextInformation(
\r
172 ITextViewer viewer, int offset) {
\r
177 public char[] getCompletionProposalAutoActivationCharacters() {
\r
178 return allowedCharacters;
\r
182 public char[] getContextInformationAutoActivationCharacters() {
\r
187 public String getErrorMessage() {
\r
188 return "Error in CompletionProcessor";
\r
192 public IContextInformationValidator getContextInformationValidator() {
\r