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 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
55 public CompletionProcessor(Table allowedVariables, boolean allowFunctions){
\r
56 this.allowedVariables = allowedVariables;
\r
59 functions = new ArrayList<String>();
\r
60 if (allowFunctions) {
\r
62 functions = SimanticsUI.getSession().syncRequest(new Read<ArrayList<String>>() {
\r
64 public ArrayList<String> perform(ReadGraph graph)
\r
65 throws DatabaseException {
\r
66 SysdynResource sr = SysdynResource.getInstance(graph);
\r
67 Layer0 l0 = Layer0.getInstance(graph);
\r
68 ArrayList<String> functions = new ArrayList<String>();
\r
70 Resource funktionlibrary = graph.getPossibleResource(SysdynResource.URIs.Built$in_Functions);
\r
71 for(Resource r : graph.syncRequest(new ObjectsWithType(funktionlibrary, l0.ConsistsOf, sr.SysdynModelicaFunction))) {
\r
72 String name = NameUtils.getSafeName(graph, r);
\r
73 functions.add(name);
\r
76 Resource subfunktionlibrary = graph.getPossibleResource(SysdynResource.URIs.Built$in_Functions_Vensim_Functions);
\r
77 for(Resource r : graph.syncRequest(new ObjectsWithType(subfunktionlibrary, l0.ConsistsOf, sr.SysdynModelicaFunction))) {
\r
78 String name = NameUtils.getSafeName(graph, r);
\r
79 functions.add(name);
\r
86 catch (DatabaseException e) {
\r
87 e.printStackTrace();
\r
90 Collections.sort(functions);
\r
93 private ICompletionProposal[] collectProposals(String token, int offset) {
\r
95 if (variables == null) {
\r
96 variables = new ArrayList<String>();
\r
97 if(allowedVariables != null && !allowedVariables.isDisposed()) {
\r
98 TableItem[] connectedVariables = allowedVariables.getItems();
\r
99 for(TableItem ti : connectedVariables) {
\r
100 this.variables.add(ti.getText());
\r
103 Collections.sort(variables);
\r
106 ArrayList<ICompletionProposal> resultArray = new ArrayList<ICompletionProposal>();
\r
107 for (String function : functions) {
\r
108 if (token.length() == 0 || function.toUpperCase().startsWith(token.toUpperCase())) {
\r
109 resultArray.add(new CompletionProposal(function,
\r
110 offset - token.length(),
\r
112 function.length()));
\r
115 for (String variable : variables) {
\r
116 if (token.length() == 0 || variable.toUpperCase().startsWith(token.toUpperCase())) {
\r
117 resultArray.add(new CompletionProposal(variable,
\r
118 offset - token.length(),
\r
120 variable.length()));
\r
123 ICompletionProposal[] result = new ICompletionProposal[resultArray.size()];
\r
124 for (int i = 0; i < result.length; ++i) {
\r
125 result[i] = resultArray.get(i);
\r
131 public ICompletionProposal[] computeCompletionProposals(
\r
132 ITextViewer viewer, int offset) {
\r
133 String equation = viewer.getDocument().get();
\r
134 // System.out.println(equation + "\noffset = " + offset);
\r
136 if (equation.length() == 0
\r
138 || Character.isWhitespace(equation.charAt(offset - 1))) {
\r
139 return collectProposals("", offset);
\r
142 equation = equation.substring(0, offset);
\r
143 // System.out.println(equation + "\noffset = " + offset);
\r
145 // Split into tokens on whitespace characters
\r
146 String[] tokens = equation.split("\\s+");
\r
147 if (tokens.length == 0) {
\r
148 return collectProposals("", offset);
\r
150 String token = tokens[tokens.length - 1];
\r
151 // System.out.println(token + "\noffset = " + offset);
\r
153 return collectProposals(token, offset);
\r
157 public IContextInformation[] computeContextInformation(
\r
158 ITextViewer viewer, int offset) {
\r
163 public char[] getCompletionProposalAutoActivationCharacters() {
\r
164 return allowedCharacters;
\r
168 public char[] getContextInformationAutoActivationCharacters() {
\r
173 public String getErrorMessage() {
\r
174 return "Error in CompletionProcessor";
\r
178 public IContextInformationValidator getContextInformationValidator() {
\r