]> gerrit.simantics Code Review - simantics/sysdyn.git/commitdiff
Multi-part variable support for Sysdyn text feed assistant (refs #4701), fixes also...
authormiettinen <miettinen@ac1ea38d-2e2b-0410-8846-a27921b304fc>
Thu, 27 Feb 2014 13:40:54 +0000 (13:40 +0000)
committermiettinen <miettinen@ac1ea38d-2e2b-0410-8846-a27921b304fc>
Thu, 27 Feb 2014 13:40:54 +0000 (13:40 +0000)
Fixed Tourists sample model (refs #4733).

git-svn-id: https://www.simantics.org/svn/simantics/sysdyn/trunk@29001 ac1ea38d-2e2b-0410-8846-a27921b304fc

org.simantics.sysdyn.feature/rootfiles/sampleModels/Tourists Environments And Hotel Facilities.tg
org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/properties/widgets/expressions/CompletionProcessor.java

index 496ef1cbb5bee631991f939ee2a619f899b84eae..d82832a45ed6d7e8445ba8c4c5aa7c1ef7eb7507 100644 (file)
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
index af2ea9303608a1aa7911f1a92ceb0f57775b3f1a..d2d78a52aa6588ec6088d219a8367a7c7afc15b4 100644 (file)
@@ -1,5 +1,5 @@
 /*******************************************************************************\r
- * Copyright (c) 2010 Association for Decentralized Information Management in\r
+ * Copyright (c) 2010, 2014 Association for Decentralized Information Management in\r
  * Industry THTH ry.\r
  * All rights reserved. This program and the accompanying materials\r
  * are made available under the terms of the Eclipse Public License v1.0\r
@@ -13,6 +13,7 @@ package org.simantics.sysdyn.ui.properties.widgets.expressions;
 \r
 import java.util.ArrayList;\r
 import java.util.Collections;\r
+import java.util.Comparator;\r
 \r
 import org.eclipse.jface.resource.ImageDescriptor;\r
 import org.eclipse.jface.resource.JFaceResources;\r
@@ -56,12 +57,17 @@ public class CompletionProcessor implements IContentAssistProcessor {
     \r
     private LocalResourceManager resourceManager;\r
     \r
-       private final char[] allowedCharacters = {\r
+       private static final char[] ALLOWED_CHARACTERS = {\r
                '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
                '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
                '1','2','3','4','5','6','7','8','9','0','.','(',')'};\r
            \r
-       private final String allowedConnectedCharactersRegExp = "[\\Q({[:;,<=>+-*/^\\E]";\r
+       private static final String ALLOWED_CONNECTED_CHARACTERS_REG_EXP = "[\\Q({[:;,<=>+-*/^\\E]";\r
+       \r
+       private static final ArrayList<String> ALLOW_ALL_COMPLETIONS_LIST = new ArrayList<String>();\r
+       static {\r
+               ALLOW_ALL_COMPLETIONS_LIST.add("");\r
+       }\r
        \r
        public CompletionProcessor(Table allowedVariables, boolean allowFunctions, ExpressionWidgetInput input) {\r
                this.allowedVariables = allowedVariables;\r
@@ -121,7 +127,7 @@ public class CompletionProcessor implements IContentAssistProcessor {
        }\r
        \r
        /**\r
-        * Create CompletionProposals of the variables and add them to array.\r
+        * Create CompletionProposals of the variables and add them to array. Do not allow duplicates.\r
         * @param array result array of CompletionProposals\r
         * @param token current token\r
         * @param offset an offset within the document for which completions should be computed\r
@@ -131,8 +137,9 @@ public class CompletionProcessor implements IContentAssistProcessor {
         Image imageVariableGray = resourceManager.createImage(ImageDescriptor.createFromURL(Activator.getDefault().getBundle().getResource("icons/variableGray.png")));\r
         \r
         for (String variable : variables) {\r
-            if (token.length() == 0 || variable.toUpperCase().startsWith(token.toUpperCase())) {\r
-                array.add(new CompletionProposal(variable, \r
+            if ((token.length() == 0 || variable.toUpperCase().startsWith(token.toUpperCase()))\r
+                       && !listContainsVariable(array, variable)) {\r
+               array.add(new CompletionProposal(variable, \r
                         offset - token.length(),\r
                         token.length(), \r
                         variable.length(), \r
@@ -143,7 +150,8 @@ public class CompletionProcessor implements IContentAssistProcessor {
             }   \r
         }\r
         for (String variable : timeAndSelfVariables) {\r
-            if (token.length() == 0 || variable.toUpperCase().startsWith(token.toUpperCase())) {\r
+            if ((token.length() == 0 || variable.toUpperCase().startsWith(token.toUpperCase()))\r
+                       && !listContainsVariable(array, variable)) {\r
                 array.add(new CompletionProposal(variable, \r
                         offset - token.length(),\r
                         token.length(), \r
@@ -156,6 +164,15 @@ public class CompletionProcessor implements IContentAssistProcessor {
         }\r
        }\r
        \r
+       private boolean listContainsVariable(ArrayList<ICompletionProposal> array,\r
+                       String variable) {\r
+               for (ICompletionProposal proposal : array) {\r
+                       if (proposal.getDisplayString().equals(variable))\r
+                               return true;\r
+               }\r
+               return false;\r
+       }\r
+\r
        /**\r
      * Create CompletionProposals of the functions and add them to array.\r
      * @param array result array of CompletionProposals\r
@@ -186,20 +203,38 @@ public class CompletionProcessor implements IContentAssistProcessor {
        }\r
        \r
        /**\r
-     * Collect all matching proposals\r
-     * @param token current token\r
+     * Collect all matching proposals. Duplicates are removed; the one with the longest token stays.\r
+     * @param possibleLabelBeginnings sets of whitespace delimited tokens (as Strings)\r
      * @param offset an offset within the document for which completions should be computed\r
      * @return Array of matching proposals\r
      */\r
-    private ICompletionProposal[] collectProposals(String token, int offset) {\r
+    private ICompletionProposal[] collectProposals(ArrayList<String> possibleLabelBeginnings, int offset) {\r
            ArrayList<ICompletionProposal> resultArray = new ArrayList<ICompletionProposal>();\r
         \r
            // Find variables and functions and create CompletionProposals out of them.\r
            findVariables();\r
-           addVariables(resultArray, token, offset);\r
-           addFunctions(resultArray, token, offset);\r
+           \r
+           // Sort the list based on the length of the tokens (descending) to get "" to end.\r
+           Collections.sort(possibleLabelBeginnings, new Comparator<String>(){\r
+                       @Override\r
+                       public int compare(String o1, String o2) {\r
+                               if (o1.length() > o2.length()) {\r
+                                       return -1;\r
+                               } else if (o1.length() < o2.length()) {\r
+                                       return 1;\r
+                               }\r
+                               return 0;\r
+                       }\r
+               });\r
+           \r
+           for (String possibleLabelBeginning : possibleLabelBeginnings) {\r
+               addVariables(resultArray, possibleLabelBeginning, offset);\r
+           }\r
  \r
-           ICompletionProposal[] result = new ICompletionProposal[resultArray.size()];\r
+           // No support for whitespace in function names; get shortest beginning\r
+       addFunctions(resultArray, possibleLabelBeginnings.get(possibleLabelBeginnings.size() - 1), offset);\r
+\r
+       ICompletionProposal[] result = new ICompletionProposal[resultArray.size()];\r
                for (int i = 0; i < result.length; ++i) {\r
                        result[i] = resultArray.get(i);\r
                }\r
@@ -213,35 +248,75 @@ public class CompletionProcessor implements IContentAssistProcessor {
                Control control = viewer.getTextWidget();\r
                this.resourceManager = new LocalResourceManager(JFaceResources.getResources(), control);\r
                \r
-               if (equation.length() == 0 \r
-                               || offset == 0\r
-                               || Character.isWhitespace(equation.charAt(offset - 1))) {\r
-                       return collectProposals("", offset);\r
+               if (equation.length() == 0 || offset == 0) {\r
+                       return collectProposals(ALLOW_ALL_COMPLETIONS_LIST, offset);\r
                }\r
                \r
                equation = equation.substring(0, offset);\r
                \r
-               // Split into tokens on whitespace characters\r
-               String[] tokens = equation.split("[\\s]");\r
-               if (tokens.length == 0) {\r
-                       return collectProposals("", offset);\r
+           // Split the equation on '+', '-', etc. characters\r
+        String stringsBetweenConnectedCharacters[] = equation.split(ALLOWED_CONNECTED_CHARACTERS_REG_EXP);\r
+               if (stringsBetweenConnectedCharacters.length == 0) {\r
+                       return collectProposals(ALLOW_ALL_COMPLETIONS_LIST, offset);\r
                }\r
-               String token = tokens[tokens.length - 1];\r
+               String stringAfterLastConnectedCharacter = stringsBetweenConnectedCharacters[stringsBetweenConnectedCharacters.length - 1];\r
+               String stringAfterWhitespaceAfterLastConnectedCharacter = removeLeadingWhitespace(stringAfterLastConnectedCharacter);\r
+                               \r
+               // Split into tokens on whitespace characters, include also the trailing empty strings\r
+               String[] tokens = stringAfterWhitespaceAfterLastConnectedCharacter.split("[\\s]", -42);\r
                \r
-               // If a '+', '-', etc. character is in the end, return all. \r
-           if (allowedConnectedCharactersRegExp.indexOf(token.charAt(token.length() - 1)) != -1) {\r
-               return collectProposals("", offset);\r
-           }\r
-           \r
-           // Split the last token on '+', '-', etc. characters\r
-        String tokensOfLastToken[] = token.split(allowedConnectedCharactersRegExp);\r
-               if (tokensOfLastToken.length == 0) {\r
-                       return collectProposals("", offset);\r
+               // Only whitespace after the last connection character\r
+               if (allTokensAreEmpty(tokens))\r
+                       return collectProposals(ALLOW_ALL_COMPLETIONS_LIST, offset);\r
+                       \r
+               return collectProposals(getPossibleLabelBeginnings(tokens), offset);\r
+       }\r
+\r
+       /**\r
+        * Collect all possible strings (with each whitespace replaced by a space character)\r
+        * which may be a beginning of a variable. \r
+        * Create the beginnings by adding whitespace between. E.g.:\r
+        *       {"multi", "part", "variab"}\r
+        *   -> { "multi part variab",\r
+        *        "part variab",\r
+        *        "variab" }\r
+        * @param tokens list of tokens\r
+     * @return all possible label beginnings\r
+        */\r
+    private ArrayList<String> getPossibleLabelBeginnings(String[] tokens) {\r
+               ArrayList<String> possibleLabelBeginnings = new ArrayList<String>();\r
+               for (int i = 0; i < tokens.length; ++i) {\r
+                       String token = new String();\r
+                       for (int j = i; j < tokens.length; ++j) {\r
+                               token += " " + tokens[j];\r
+                       }\r
+                       // Remove the excess space character from the beginning\r
+                       token = token.substring(1);\r
+                       \r
+                       possibleLabelBeginnings.add(token);\r
                }\r
-               token = tokensOfLastToken[tokensOfLastToken.length - 1];\r
-               //System.out.println(token + "\noffset = " + offset);\r
+               return possibleLabelBeginnings;\r
+       }\r
+\r
+       /**\r
+     * Remove leading whitespace\r
+     * @param input\r
+     * @return\r
+     */\r
+       private String removeLeadingWhitespace(String input) {\r
+               for (int i = 0; i < input.length(); ++i) {\r
+                       if (!Character.isWhitespace(input.charAt(i))) {\r
+                               return input.substring(i);\r
+                       }\r
+               }\r
+               return "";\r
+       }\r
 \r
-               return collectProposals(token, offset);\r
+       private boolean allTokensAreEmpty(String[] tokens) {\r
+               for (String token : tokens)\r
+                       if (!token.equals(""))\r
+                               return false;\r
+               return true;\r
        }\r
 \r
        @Override\r
@@ -252,7 +327,7 @@ public class CompletionProcessor implements IContentAssistProcessor {
 \r
        @Override\r
        public char[] getCompletionProposalAutoActivationCharacters() {\r
-               return allowedCharacters;\r
+               return ALLOWED_CHARACTERS;\r
        }\r
 \r
        @Override\r