From: miettinen Date: Thu, 27 Feb 2014 13:40:54 +0000 (+0000) Subject: Multi-part variable support for Sysdyn text feed assistant (refs #4701), fixes also... X-Git-Tag: 1.8.1~124 X-Git-Url: https://gerrit.simantics.org/r/gitweb?a=commitdiff_plain;h=5de0a8dc5b20579130d86e9f07ce9edaa6815078;p=simantics%2Fsysdyn.git Multi-part variable support for Sysdyn text feed assistant (refs #4701), fixes also (refs #4698). Fixed Tourists sample model (refs #4733). git-svn-id: https://www.simantics.org/svn/simantics/sysdyn/trunk@29001 ac1ea38d-2e2b-0410-8846-a27921b304fc --- diff --git a/org.simantics.sysdyn.feature/rootfiles/sampleModels/Tourists Environments And Hotel Facilities.tg b/org.simantics.sysdyn.feature/rootfiles/sampleModels/Tourists Environments And Hotel Facilities.tg index 496ef1cb..d82832a4 100644 Binary files a/org.simantics.sysdyn.feature/rootfiles/sampleModels/Tourists Environments And Hotel Facilities.tg and b/org.simantics.sysdyn.feature/rootfiles/sampleModels/Tourists Environments And Hotel Facilities.tg differ diff --git a/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/properties/widgets/expressions/CompletionProcessor.java b/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/properties/widgets/expressions/CompletionProcessor.java index af2ea930..d2d78a52 100644 --- a/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/properties/widgets/expressions/CompletionProcessor.java +++ b/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/properties/widgets/expressions/CompletionProcessor.java @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2010 Association for Decentralized Information Management in + * Copyright (c) 2010, 2014 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 @@ -13,6 +13,7 @@ package org.simantics.sysdyn.ui.properties.widgets.expressions; import java.util.ArrayList; import java.util.Collections; +import java.util.Comparator; import org.eclipse.jface.resource.ImageDescriptor; import org.eclipse.jface.resource.JFaceResources; @@ -56,12 +57,17 @@ public class CompletionProcessor implements IContentAssistProcessor { private LocalResourceManager resourceManager; - private final char[] allowedCharacters = { + private static final char[] ALLOWED_CHARACTERS = { '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','å','ä','ö', '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','Å','Ä','Ö', '1','2','3','4','5','6','7','8','9','0','.','(',')'}; - private final String allowedConnectedCharactersRegExp = "[\\Q({[:;,<=>+-*/^\\E]"; + private static final String ALLOWED_CONNECTED_CHARACTERS_REG_EXP = "[\\Q({[:;,<=>+-*/^\\E]"; + + private static final ArrayList ALLOW_ALL_COMPLETIONS_LIST = new ArrayList(); + static { + ALLOW_ALL_COMPLETIONS_LIST.add(""); + } public CompletionProcessor(Table allowedVariables, boolean allowFunctions, ExpressionWidgetInput input) { this.allowedVariables = allowedVariables; @@ -121,7 +127,7 @@ public class CompletionProcessor implements IContentAssistProcessor { } /** - * Create CompletionProposals of the variables and add them to array. + * Create CompletionProposals of the variables and add them to array. Do not allow duplicates. * @param array result array of CompletionProposals * @param token current token * @param offset an offset within the document for which completions should be computed @@ -131,8 +137,9 @@ public class CompletionProcessor implements IContentAssistProcessor { Image imageVariableGray = resourceManager.createImage(ImageDescriptor.createFromURL(Activator.getDefault().getBundle().getResource("icons/variableGray.png"))); for (String variable : variables) { - if (token.length() == 0 || variable.toUpperCase().startsWith(token.toUpperCase())) { - array.add(new CompletionProposal(variable, + if ((token.length() == 0 || variable.toUpperCase().startsWith(token.toUpperCase())) + && !listContainsVariable(array, variable)) { + array.add(new CompletionProposal(variable, offset - token.length(), token.length(), variable.length(), @@ -143,7 +150,8 @@ public class CompletionProcessor implements IContentAssistProcessor { } } for (String variable : timeAndSelfVariables) { - if (token.length() == 0 || variable.toUpperCase().startsWith(token.toUpperCase())) { + if ((token.length() == 0 || variable.toUpperCase().startsWith(token.toUpperCase())) + && !listContainsVariable(array, variable)) { array.add(new CompletionProposal(variable, offset - token.length(), token.length(), @@ -156,6 +164,15 @@ public class CompletionProcessor implements IContentAssistProcessor { } } + private boolean listContainsVariable(ArrayList array, + String variable) { + for (ICompletionProposal proposal : array) { + if (proposal.getDisplayString().equals(variable)) + return true; + } + return false; + } + /** * Create CompletionProposals of the functions and add them to array. * @param array result array of CompletionProposals @@ -186,20 +203,38 @@ public class CompletionProcessor implements IContentAssistProcessor { } /** - * Collect all matching proposals - * @param token current token + * Collect all matching proposals. Duplicates are removed; the one with the longest token stays. + * @param possibleLabelBeginnings sets of whitespace delimited tokens (as Strings) * @param offset an offset within the document for which completions should be computed * @return Array of matching proposals */ - private ICompletionProposal[] collectProposals(String token, int offset) { + private ICompletionProposal[] collectProposals(ArrayList possibleLabelBeginnings, int offset) { ArrayList resultArray = new ArrayList(); // Find variables and functions and create CompletionProposals out of them. findVariables(); - addVariables(resultArray, token, offset); - addFunctions(resultArray, token, offset); + + // Sort the list based on the length of the tokens (descending) to get "" to end. + Collections.sort(possibleLabelBeginnings, new Comparator(){ + @Override + public int compare(String o1, String o2) { + if (o1.length() > o2.length()) { + return -1; + } else if (o1.length() < o2.length()) { + return 1; + } + return 0; + } + }); + + for (String possibleLabelBeginning : possibleLabelBeginnings) { + addVariables(resultArray, possibleLabelBeginning, offset); + } - ICompletionProposal[] result = new ICompletionProposal[resultArray.size()]; + // No support for whitespace in function names; get shortest beginning + addFunctions(resultArray, possibleLabelBeginnings.get(possibleLabelBeginnings.size() - 1), offset); + + ICompletionProposal[] result = new ICompletionProposal[resultArray.size()]; for (int i = 0; i < result.length; ++i) { result[i] = resultArray.get(i); } @@ -213,35 +248,75 @@ public class CompletionProcessor implements IContentAssistProcessor { Control control = viewer.getTextWidget(); this.resourceManager = new LocalResourceManager(JFaceResources.getResources(), control); - if (equation.length() == 0 - || offset == 0 - || Character.isWhitespace(equation.charAt(offset - 1))) { - return collectProposals("", offset); + if (equation.length() == 0 || offset == 0) { + return collectProposals(ALLOW_ALL_COMPLETIONS_LIST, offset); } equation = equation.substring(0, offset); - // Split into tokens on whitespace characters - String[] tokens = equation.split("[\\s]"); - if (tokens.length == 0) { - return collectProposals("", offset); + // Split the equation on '+', '-', etc. characters + String stringsBetweenConnectedCharacters[] = equation.split(ALLOWED_CONNECTED_CHARACTERS_REG_EXP); + if (stringsBetweenConnectedCharacters.length == 0) { + return collectProposals(ALLOW_ALL_COMPLETIONS_LIST, offset); } - String token = tokens[tokens.length - 1]; + String stringAfterLastConnectedCharacter = stringsBetweenConnectedCharacters[stringsBetweenConnectedCharacters.length - 1]; + String stringAfterWhitespaceAfterLastConnectedCharacter = removeLeadingWhitespace(stringAfterLastConnectedCharacter); + + // Split into tokens on whitespace characters, include also the trailing empty strings + String[] tokens = stringAfterWhitespaceAfterLastConnectedCharacter.split("[\\s]", -42); - // If a '+', '-', etc. character is in the end, return all. - if (allowedConnectedCharactersRegExp.indexOf(token.charAt(token.length() - 1)) != -1) { - return collectProposals("", offset); - } - - // Split the last token on '+', '-', etc. characters - String tokensOfLastToken[] = token.split(allowedConnectedCharactersRegExp); - if (tokensOfLastToken.length == 0) { - return collectProposals("", offset); + // Only whitespace after the last connection character + if (allTokensAreEmpty(tokens)) + return collectProposals(ALLOW_ALL_COMPLETIONS_LIST, offset); + + return collectProposals(getPossibleLabelBeginnings(tokens), offset); + } + + /** + * Collect all possible strings (with each whitespace replaced by a space character) + * which may be a beginning of a variable. + * Create the beginnings by adding whitespace between. E.g.: + * {"multi", "part", "variab"} + * -> { "multi part variab", + * "part variab", + * "variab" } + * @param tokens list of tokens + * @return all possible label beginnings + */ + private ArrayList getPossibleLabelBeginnings(String[] tokens) { + ArrayList possibleLabelBeginnings = new ArrayList(); + for (int i = 0; i < tokens.length; ++i) { + String token = new String(); + for (int j = i; j < tokens.length; ++j) { + token += " " + tokens[j]; + } + // Remove the excess space character from the beginning + token = token.substring(1); + + possibleLabelBeginnings.add(token); } - token = tokensOfLastToken[tokensOfLastToken.length - 1]; - //System.out.println(token + "\noffset = " + offset); + return possibleLabelBeginnings; + } + + /** + * Remove leading whitespace + * @param input + * @return + */ + private String removeLeadingWhitespace(String input) { + for (int i = 0; i < input.length(); ++i) { + if (!Character.isWhitespace(input.charAt(i))) { + return input.substring(i); + } + } + return ""; + } - return collectProposals(token, offset); + private boolean allTokensAreEmpty(String[] tokens) { + for (String token : tokens) + if (!token.equals("")) + return false; + return true; } @Override @@ -252,7 +327,7 @@ public class CompletionProcessor implements IContentAssistProcessor { @Override public char[] getCompletionProposalAutoActivationCharacters() { - return allowedCharacters; + return ALLOWED_CHARACTERS; } @Override