package org.simantics.document.ui; import org.eclipse.core.runtime.IProgressMonitor; import org.eclipse.jface.text.BadLocationException; import org.eclipse.jface.text.DefaultInformationControl; import org.eclipse.jface.text.DocumentEvent; import org.eclipse.jface.text.IDocument; import org.eclipse.jface.text.IInformationControl; import org.eclipse.jface.text.IInformationControlCreator; import org.eclipse.jface.text.ITextViewer; import org.eclipse.jface.text.contentassist.ICompletionProposal; import org.eclipse.jface.text.contentassist.ICompletionProposalExtension; import org.eclipse.jface.text.contentassist.ICompletionProposalExtension2; import org.eclipse.jface.text.contentassist.ICompletionProposalExtension3; import org.eclipse.jface.text.contentassist.ICompletionProposalExtension4; import org.eclipse.jface.text.contentassist.ICompletionProposalExtension5; import org.eclipse.jface.text.contentassist.IContextInformation; import org.eclipse.swt.graphics.Image; import org.eclipse.swt.graphics.Point; import org.eclipse.swt.widgets.Shell; import org.simantics.scl.compiler.elaboration.modules.SCLValue; public class CSSCompletionProposal implements ICompletionProposal, ICompletionProposalExtension, ICompletionProposalExtension2, ICompletionProposalExtension3, ICompletionProposalExtension4, ICompletionProposalExtension5 { private static final Image PRIVATE = Activator.imageDescriptorFromPlugin("org.simantics.scl.ui", "icons/private_co.gif").createImage(); private static final Image PUBLIC = Activator.imageDescriptorFromPlugin("org.simantics.scl.ui", "icons/public_co.gif").createImage(); private static final Image CONST = Activator.imageDescriptorFromPlugin("org.simantics.scl.ui", "icons/container_obj.gif").createImage(); private static final Image TYPE = Activator.imageDescriptorFromPlugin("org.simantics.scl.ui", "icons/typedef_obj.gif").createImage(); private final String content; private final String name; private final String module; private final String documentation; private int replacementOffset; private String prefix; private final CSSCompletionType completionType; public CSSCompletionProposal(SCLValue value, int replacementOffset, String prefix) { this.name = value.getName().name; this.module = value.getName().module; this.documentation = value.getDocumentation(); this.content = name + " :: " + value.getType() + " (" + module + ")"; this.replacementOffset = replacementOffset; this.prefix = prefix; // System.out.println(prefix); if (value.isPrivate()) this.completionType = CSSCompletionType.PRIVATE; else this.completionType = CSSCompletionType.PUBLIC; } public CSSCompletionProposal(String name, String module, CSSCompletionType completionType, int replacementOffset, String prefix) { this.name = name; this.module = module; this.content = name + " (" + module + ")"; this.documentation = null; this.replacementOffset = replacementOffset; this.prefix = prefix; this.completionType = completionType; } @Override public void apply(IDocument document) { } @Override public Point getSelection(IDocument document) { return new Point(replacementOffset + getName().length(), 0); } @Override public String getAdditionalProposalInfo() { return documentation; } @Override public String getDisplayString() { return content; } @Override public Image getImage() { switch (completionType) { case PRIVATE: return PRIVATE; case PUBLIC: return PUBLIC; case CONST: return CONST; case TYPE: return TYPE; default: return null; } } @Override public IContextInformation getContextInformation() { return null; } @Override public void apply(IDocument document, char trigger, int offset) { } @Override public boolean isValidFor(IDocument document, int offset) { return validate(document, offset, null); } @Override public char[] getTriggerCharacters() { return null; } @Override public int getContextInformationPosition() { return 0; } @Override public void apply(ITextViewer viewer, char trigger, int stateMask, int offset) { try { // String replacement = getName().substring(offset - replacementOffset); IDocument doc = viewer.getDocument(); Point p = viewer.getSelectedRange(); // System.out.println("selectedRange : " + p); // System.out.println("prefix : " + prefix); // int start = offset - prefix.length(); // int end = prefix.length(); // System.out.println("start : " + start + ", end : " + end); // String sadd = doc.get(start, end); // System.out.println("toReplace : " + sadd); if (p.y > 0) { doc.replace(p.x, p.y, ""); doc.replace(offset, 0, getName()); } else { String currentText = doc.get(offset - prefix.length(), prefix.length()); if (currentText.equals(getName())) return; doc.replace(offset - prefix.length(), prefix.length(), ""); doc.replace(offset - prefix.length(), 0, getName()); } } catch (BadLocationException x) { x.printStackTrace(); } } @Override public void selected(ITextViewer viewer, boolean smartToggle) { } @Override public void unselected(ITextViewer viewer) { } @Override public boolean validate(IDocument document, int offset, DocumentEvent event) { try { // System.out.println("replacementOffset : " + replacementOffset); // System.out.println("offset : " + offset); boolean a = offset >= replacementOffset; boolean b = offset < replacementOffset + getName().length(); String s = document.get(replacementOffset, offset - replacementOffset); prefix = s; String d = getName();//.substring(0, offset - prefixStart); boolean c = d.toLowerCase().startsWith(s.toLowerCase()); return a && b && c; } catch (BadLocationException x) { //x.printStackTrace(); return false; } } @Override public IInformationControlCreator getInformationControlCreator() { return CREATOR; } private static final IInformationControlCreator CREATOR = new IInformationControlCreator() { @Override public IInformationControl createInformationControl(Shell parent) { return new DefaultInformationControl(parent); } }; @Override public CharSequence getPrefixCompletionText(IDocument document, int completionOffset) { return getName(); } @Override public int getPrefixCompletionStart(IDocument document, int completionOffset) { return replacementOffset - prefix.length(); } @Override public boolean isAutoInsertable() { return true; } @Override public Object getAdditionalProposalInfo(IProgressMonitor monitor) { return documentation; } public String getName() { return name; } public boolean isPrivate() { return CSSCompletionType.PRIVATE == completionType; } public String getModule() { return module; } }