]> gerrit.simantics Code Review - simantics/sysdyn.git/blob
34140ed84e3bcdc707383cf4e8a9d61135a9bdeb
[simantics/sysdyn.git] /
1 /*******************************************************************************\r
2  * Copyright (c) 2010 Association for Decentralized Information Management in\r
3  * Industry THTH ry.\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
8  *\r
9  * Contributors:\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
13 \r
14 import java.util.ArrayList;\r
15 import java.util.Collections;\r
16 \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
34 \r
35 \r
36 /**\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
41  *\r
42  */\r
43 public class CompletionProcessor implements IContentAssistProcessor {\r
44         \r
45         private Table allowedVariables;\r
46         private ArrayList<String> functions;\r
47         private ArrayList<String> variables = null;\r
48         \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
53             \r
54         private final String allowedConnectedCharactersRegExp = "[\\Q({[:;,<=>+-*/^\\E]";\r
55         \r
56         public CompletionProcessor(Table allowedVariables, boolean allowFunctions){\r
57                 this.allowedVariables = allowedVariables;\r
58                 \r
59                 //Finding functions\r
60         functions = new ArrayList<String>();\r
61         if (allowFunctions) {\r
62                         try {\r
63                                  functions = SimanticsUI.getSession().syncRequest(new Read<ArrayList<String>>() {\r
64                                         @Override\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
70                                                 \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
75                                                 }\r
76                                                 \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
81                                                 }\r
82                                                 \r
83                                                 return functions;\r
84                                         }\r
85                                 });\r
86                         }\r
87                         catch (DatabaseException e) {\r
88                                 e.printStackTrace();\r
89                         }\r
90         }\r
91         Collections.sort(functions);\r
92         for (int i = 0; i < functions.size(); ++i) {\r
93             functions.set(i, functions.get(i) + "()");\r
94         }\r
95         }\r
96 \r
97         private ICompletionProposal[] collectProposals(String token, int offset) {\r
98                 //Finding variables\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
105                         }\r
106                     }\r
107                     Collections.sort(variables);\r
108                 }\r
109                 \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
115                                                 token.length(), \r
116                                                 variable.length()));\r
117                         }       \r
118                 }\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
123                                                 token.length(), \r
124                                                 function.length() - 1));\r
125                         }       \r
126                 }\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
130                 }\r
131                 return result;\r
132         }\r
133         \r
134     @Override\r
135         public ICompletionProposal[] computeCompletionProposals(\r
136                         ITextViewer viewer, int offset) {\r
137                 String equation = viewer.getDocument().get();\r
138 \r
139                 if (equation.length() == 0 \r
140                                 || offset == 0\r
141                                 || Character.isWhitespace(equation.charAt(offset - 1))) {\r
142                         return collectProposals("", offset);\r
143                 }\r
144                 \r
145                 equation = equation.substring(0, offset);\r
146                 \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
151                 }\r
152                 String token = tokens[tokens.length - 1];\r
153                 \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
157             }\r
158             \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
163                 }\r
164                 token = tokensOfLastToken[tokensOfLastToken.length - 1];\r
165                 //System.out.println(token + "\noffset = " + offset);\r
166 \r
167                 return collectProposals(token, offset);\r
168         }\r
169 \r
170         @Override\r
171         public IContextInformation[] computeContextInformation(\r
172                         ITextViewer viewer, int offset) {\r
173                 return null;\r
174         }\r
175 \r
176         @Override\r
177         public char[] getCompletionProposalAutoActivationCharacters() {\r
178                 return allowedCharacters;\r
179         }\r
180 \r
181         @Override\r
182         public char[] getContextInformationAutoActivationCharacters() {\r
183                 return null;\r
184         }\r
185 \r
186         @Override\r
187         public String getErrorMessage() {\r
188                 return "Error in CompletionProcessor";\r
189         }\r
190 \r
191         @Override\r
192         public IContextInformationValidator getContextInformationValidator() {\r
193                 return null;\r
194         }\r
195 \r
196 }\r