| package org.eclipse.osbp.xtext.basic.ui.contentassist; |
| |
| import org.eclipse.emf.ecore.EObject; |
| import org.eclipse.jface.text.contentassist.ICompletionProposal; |
| import org.eclipse.osbp.xtext.basic.ui.BasicDSLDocumentationTranslator; |
| import org.eclipse.xtext.Assignment; |
| import org.eclipse.xtext.GrammarUtil; |
| import org.eclipse.xtext.RuleCall; |
| import org.eclipse.xtext.common.ui.contentassist.TerminalsProposalProvider; |
| import org.eclipse.xtext.ui.editor.contentassist.ConfigurableCompletionProposal; |
| import org.eclipse.xtext.ui.editor.contentassist.ContentAssistContext; |
| import org.eclipse.xtext.ui.editor.contentassist.ICompletionProposalAcceptor; |
| import org.eclipse.xtext.ui.editor.contentassist.PrefixMatcher; |
| import org.eclipse.xtext.util.Strings; |
| |
| /** |
| * |
| * @author kraeling |
| * |
| * A derivation from the standard xtext (non-OSBP) class TerminalsProposalProvider that allows to add a description to dummy variables of |
| * a certain type like TRANSLATABLEID. |
| */ |
| |
| public class TerminalsProposalProviderWithDescription extends TerminalsProposalProvider { |
| |
| BasicDSLDocumentationTranslator translator; |
| |
| public void setDocumentationTranslator(BasicDSLDocumentationTranslator translator) |
| { |
| this.translator = translator; |
| } |
| |
| @Override |
| public void complete_ID(EObject model, RuleCall ruleCall, final ContentAssistContext context, |
| ICompletionProposalAcceptor acceptor) { |
| if (doCreateIdProposals()) { |
| PrefixMatcher newMatcher = new PrefixMatcher() { |
| @Override |
| public boolean isCandidateMatchingPrefix(String name, String prefix) { |
| String strippedName = name; |
| if (name.startsWith("^") && !prefix.startsWith("^")) { |
| strippedName = name.substring(1); |
| } |
| return context.getMatcher().isCandidateMatchingPrefix(strippedName, prefix); |
| } |
| }; |
| ContentAssistContext myContext = context.copy().setMatcher(newMatcher).toContext(); |
| String feature = getAssignedFeature(ruleCall); |
| String proposalText = feature != null ? feature : Strings.toFirstUpper(ruleCall.getRule().getName().toLowerCase()); |
| String displayText = proposalText; |
| if (feature != null) |
| displayText = proposalText + " - " + ruleCall.getRule().getName(); |
| // Add a description / translation if one exists. |
| displayText = enrichWithDescription(displayText, model, ruleCall.getRule().getName()); |
| proposalText = getValueConverter().toString(proposalText, ruleCall.getRule().getName()); |
| ICompletionProposal proposal = createCompletionProposal(proposalText, displayText, null, myContext); |
| if (proposal instanceof ConfigurableCompletionProposal) { |
| ConfigurableCompletionProposal configurable = (ConfigurableCompletionProposal) proposal; |
| configurable.setSelectionStart(configurable.getReplacementOffset()); |
| configurable.setSelectionLength(proposalText.length()); |
| configurable.setAutoInsertable(false); |
| configurable.setSimpleLinkedMode(myContext.getViewer(), '\t', ' '); |
| } |
| acceptor.accept(proposal); |
| } |
| } |
| |
| private String getAssignedFeature(RuleCall call) { |
| Assignment ass = GrammarUtil.containingAssignment(call); |
| if (ass != null) { |
| String result = ass.getFeature(); |
| if (result.equals(result.toLowerCase())) |
| result = Strings.toFirstUpper(result); |
| return result; |
| } |
| return null; |
| } |
| |
| |
| /** |
| * |
| * @param displayText A string with the name (and type) of a dummy variable for which we want a description. |
| * @param model The model in which the dummy variable is defined. |
| * @param feature The type of the dummy variable. |
| * @return The display text with an additional description from the associated i18n file for the model (if one exists). |
| */ |
| private String enrichWithDescription(String displayText, EObject model, String feature) |
| { |
| String result = displayText; |
| |
| // The translation key needed for the i18n file can be derived from the translation key of the respective model. |
| // For example, if the model's translation key is "org.eclipse.osbp.xtext.perspective.Perspective", then |
| // the translation key of the dummy variable of type TRANSLATABLESTRING is "org.eclipse.osbp.xtext.perspective.TRANSLATABLESTRING" |
| String modelTranslationKey = BasicDSLDocumentationTranslator.getTranslatorKey(model); |
| |
| int lastDotIndex = modelTranslationKey.lastIndexOf('.'); |
| if (lastDotIndex > 0) |
| { |
| String featureTranslationKey = modelTranslationKey.substring(0, lastDotIndex + 1) + feature; |
| |
| // Try to find a translation / documentation for the translation key. |
| if (translator != null) |
| { |
| String translated = translator.getDocumentation(featureTranslationKey, true); |
| if (translated == null) { |
| translated = ""; |
| } else { |
| // --- if the documentation contains more than one line, use only |
| // the first line --- |
| translated = " - " + (translated.split("<br>"))[0]; |
| } |
| |
| result = result + translated; |
| } |
| } |
| |
| return result; |
| } |
| |
| @Override |
| public void complete_STRING(EObject model, RuleCall ruleCall, ContentAssistContext context, |
| ICompletionProposalAcceptor acceptor) { |
| if (doCreateStringProposals()) { |
| String feature = getAssignedFeature(ruleCall); |
| createStringProposal(context, acceptor, feature, ruleCall); |
| } |
| } |
| |
| private void createStringProposal(ContentAssistContext context, ICompletionProposalAcceptor acceptor, |
| String feature, RuleCall ruleCall) { |
| String proposalText = feature != null ? feature : Strings.toFirstUpper(ruleCall.getRule().getName().toLowerCase()); |
| proposalText = getValueConverter().toString(proposalText, ruleCall.getRule().getName()); |
| String displayText = proposalText; |
| if (feature != null) |
| displayText = displayText + " - " + ruleCall.getRule().getName(); |
| ICompletionProposal proposal = createCompletionProposal(proposalText, displayText, null, context); |
| if (proposal instanceof ConfigurableCompletionProposal) { |
| ConfigurableCompletionProposal configurable = (ConfigurableCompletionProposal) proposal; |
| configurable.setSelectionStart(configurable.getReplacementOffset() + 1); |
| configurable.setSelectionLength(proposalText.length() - 2); |
| configurable.setAutoInsertable(false); |
| configurable.setSimpleLinkedMode(context.getViewer(), proposalText.charAt(0), '\t'); |
| |
| } |
| acceptor.accept(proposal); |
| } |
| |
| @Override |
| public void complete_INT(EObject model, RuleCall ruleCall, ContentAssistContext context, |
| ICompletionProposalAcceptor acceptor) { |
| String feature = getAssignedFeature(ruleCall); |
| if (doCreateIntProposals()) { |
| createIntProposal(context, acceptor, ruleCall, feature, 1); |
| } |
| } |
| |
| private void createIntProposal(ContentAssistContext context, ICompletionProposalAcceptor acceptor, |
| RuleCall ruleCall, String feature, int i) { |
| String proposalText = getValueConverter().toString(i, ruleCall.getRule().getName()); |
| String displayText = proposalText + " - " + ruleCall.getRule().getName(); |
| if (feature != null) |
| displayText = proposalText + " - " + feature; |
| ICompletionProposal proposal = createCompletionProposal(proposalText, displayText, null, context); |
| if (proposal instanceof ConfigurableCompletionProposal) { |
| ConfigurableCompletionProposal configurable = (ConfigurableCompletionProposal) proposal; |
| configurable.setSelectionStart(configurable.getReplacementOffset()); |
| configurable.setSelectionLength(proposalText.length()); |
| configurable.setAutoInsertable(false); |
| configurable.setSimpleLinkedMode(context.getViewer(), '\t', ' '); |
| } |
| acceptor.accept(proposal); |
| } |
| } |