4c429e7fdda6ced8d40a94b7f77a9467d42f7aa6
[simantics/platform.git] / bundles / org.simantics.scl.ui / src / org / simantics / scl / ui / editor / completion / SCLCompletionProposal.java
1 package org.simantics.scl.ui.editor.completion;
2
3 import org.eclipse.core.runtime.IProgressMonitor;
4 import org.eclipse.jface.text.BadLocationException;
5 import org.eclipse.jface.text.DefaultInformationControl;
6 import org.eclipse.jface.text.DocumentEvent;
7 import org.eclipse.jface.text.IDocument;
8 import org.eclipse.jface.text.IInformationControl;
9 import org.eclipse.jface.text.IInformationControlCreator;
10 import org.eclipse.jface.text.ITextViewer;
11 import org.eclipse.jface.text.contentassist.ICompletionProposal;
12 import org.eclipse.jface.text.contentassist.ICompletionProposalExtension;
13 import org.eclipse.jface.text.contentassist.ICompletionProposalExtension2;
14 import org.eclipse.jface.text.contentassist.ICompletionProposalExtension3;
15 import org.eclipse.jface.text.contentassist.ICompletionProposalExtension4;
16 import org.eclipse.jface.text.contentassist.ICompletionProposalExtension5;
17 import org.eclipse.jface.text.contentassist.IContextInformation;
18 import org.eclipse.swt.graphics.Image;
19 import org.eclipse.swt.graphics.Point;
20 import org.eclipse.swt.widgets.Shell;
21 import org.simantics.scl.compiler.elaboration.modules.SCLValue;
22 import org.simantics.scl.ui.Activator;
23
24 public class SCLCompletionProposal implements ICompletionProposal, ICompletionProposalExtension, ICompletionProposalExtension2, ICompletionProposalExtension3, ICompletionProposalExtension4, ICompletionProposalExtension5 {
25     
26     private static final Image PRIVATE = Activator.imageDescriptorFromPlugin("org.simantics.scl.ui", "icons/private_co.gif").createImage();
27     private static final Image PUBLIC = Activator.imageDescriptorFromPlugin("org.simantics.scl.ui", "icons/public_co.gif").createImage();
28     private static final Image CONST = Activator.imageDescriptorFromPlugin("org.simantics.scl.ui", "icons/container_obj.gif").createImage();
29     private static final Image TYPE = Activator.imageDescriptorFromPlugin("org.simantics.scl.ui", "icons/typedef_obj.gif").createImage();
30     
31     private final String content;
32     private final String name;
33     private final String module;
34     private final String documentation;
35     private int replacementOffset;
36     private String prefix;
37     private final SCLCompletionType completionType;
38     
39     public SCLCompletionProposal(SCLValue value, int replacementOffset, String prefix) {
40         this.name = value.getName().name;
41         this.module = value.getName().module;
42         this.documentation = value.getDocumentation();
43         this.content = name + " :: " + value.getType() + "  (" + module + ")";
44         this.replacementOffset = replacementOffset;
45         this.prefix = prefix;
46 //        System.out.println(prefix);
47         if (value.isPrivate())
48             this.completionType = SCLCompletionType.PRIVATE;
49         else
50             this.completionType = SCLCompletionType.PUBLIC;
51     }
52
53     public SCLCompletionProposal(String name, String module, SCLCompletionType completionType, int replacementOffset, String prefix) {
54         this.name = name;
55         this.module = module;
56         this.content = name + " (" + module + ")";
57         this.documentation = null;
58         this.replacementOffset = replacementOffset;
59         this.prefix = prefix;
60         this.completionType = completionType;
61     }
62
63     @Override
64     public void apply(IDocument document) {
65
66     }
67
68     @Override
69     public Point getSelection(IDocument document) {
70         return new Point(replacementOffset + getName().length(), 0);
71     }
72
73     @Override
74     public String getAdditionalProposalInfo() {
75         return documentation;
76     }
77
78     @Override
79     public String getDisplayString() {
80         return content;
81     }
82
83     @Override
84     public Image getImage() {
85         switch (completionType) {
86         case PRIVATE:
87             return PRIVATE;
88         case PUBLIC:
89             return PUBLIC;
90         case CONST:
91             return CONST;
92         case TYPE:
93             return TYPE;
94         default:
95             return null;
96         }
97     }
98
99     @Override
100     public IContextInformation getContextInformation() {
101         return null;
102     }
103
104     @Override
105     public void apply(IDocument document, char trigger, int offset) {
106     }
107
108     @Override
109     public boolean isValidFor(IDocument document, int offset) {
110         return validate(document, offset, null);
111     }
112
113     @Override
114     public char[] getTriggerCharacters() {
115         return null;
116     }
117
118     @Override
119     public int getContextInformationPosition() {
120         return 0;
121     }
122
123     @Override
124     public void apply(ITextViewer viewer, char trigger, int stateMask, int offset) {
125         try {
126 //            String replacement = getName().substring(offset - replacementOffset);
127             IDocument doc = viewer.getDocument();
128             Point p = viewer.getSelectedRange();
129 //            System.out.println("selectedRange : " + p);
130 //            System.out.println("prefix : " + prefix);
131 //            int start = offset - prefix.length();
132 //            int end = prefix.length();
133 //            System.out.println("start : " + start + ", end : " + end);
134 //            String sadd = doc.get(start, end);
135 //            System.out.println("toReplace : " + sadd);
136             if (p.y > 0) {
137                 doc.replace(p.x, p.y, "");
138                 doc.replace(offset, 0, getName());
139             } else {
140                 String currentText = doc.get(offset - prefix.length(), prefix.length());
141                 if (currentText.equals(getName()))
142                     return;
143                 doc.replace(offset - prefix.length(), prefix.length(), "");
144                 doc.replace(offset - prefix.length(), 0, getName());
145             }
146         } catch (BadLocationException x) {
147             x.printStackTrace();
148         }
149     }
150
151     @Override
152     public void selected(ITextViewer viewer, boolean smartToggle) {
153     }
154
155     @Override
156     public void unselected(ITextViewer viewer) {
157     }
158
159     @Override
160     public boolean validate(IDocument document, int offset, DocumentEvent event) {
161         try {
162 //            System.out.println("replacementOffset : " + replacementOffset);
163 //            System.out.println("offset : " + offset);
164             boolean a = offset >= replacementOffset;
165             boolean b = offset < replacementOffset + getName().length();
166             String s = document.get(replacementOffset, offset - replacementOffset);
167             prefix = s;
168             String d = getName();//.substring(0, offset - prefixStart);
169             boolean c = d.toLowerCase().startsWith(s.toLowerCase());
170             return a && b && c;
171         } catch (BadLocationException x) {
172             //x.printStackTrace();
173             return false;
174         }
175     }
176
177     @Override
178     public IInformationControlCreator getInformationControlCreator() {
179         return CREATOR;
180     }
181     
182     private static final IInformationControlCreator CREATOR = new IInformationControlCreator() {
183         
184         @Override
185         public IInformationControl createInformationControl(Shell parent) {
186             return new DefaultInformationControl(parent);
187         }
188     };
189
190     @Override
191     public CharSequence getPrefixCompletionText(IDocument document, int completionOffset) {
192         return getName();
193     }
194
195     @Override
196     public int getPrefixCompletionStart(IDocument document, int completionOffset) {
197         return replacementOffset - prefix.length();
198     }
199
200     @Override
201     public boolean isAutoInsertable() {
202         return true;
203     }
204
205     @Override
206     public Object getAdditionalProposalInfo(IProgressMonitor monitor) {
207         return documentation;
208     }
209
210     public String getName() {
211         return name;
212     }
213     
214     public boolean isPrivate() {
215         return SCLCompletionType.PRIVATE == completionType;
216     }
217
218     public String getModule() {
219         return module;
220     }
221 }