/******************************************************************************* * Copyright (c) 2011 BestSolution.at and others. * All rights reserved. This program and the accompanying materials * are made available under the terms of the Eclipse Public License v1.0 * which accompanies this distribution, and is available at * http://www.eclipse.org/legal/epl-v10.html * * Contributors: * Tom Schindl<tom.schindl@bestsolution.at> - initial API and implementation *******************************************************************************/ package at.bestsolution.efxclipse.tooling.css.ui.contentassist; import java.util.List; import org.eclipse.emf.ecore.EObject; import org.eclipse.jface.viewers.StyledString; import org.eclipse.xtext.RuleCall; 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.ReplacementTextApplier; import org.osgi.framework.BundleContext; import org.osgi.framework.ServiceReference; import at.bestsolution.efxclipse.tooling.css.CssDialectExtension.DialogProposal; import at.bestsolution.efxclipse.tooling.css.CssDialectExtension.MultiTermGroupProperty; import at.bestsolution.efxclipse.tooling.css.CssDialectExtension.MultiValuesGroupProperty; import at.bestsolution.efxclipse.tooling.css.CssDialectExtension.Property; import at.bestsolution.efxclipse.tooling.css.CssDialectExtension.Proposal; import at.bestsolution.efxclipse.tooling.css.cssDsl.css_generic_declaration; import at.bestsolution.efxclipse.tooling.css.cssDsl.expr; import at.bestsolution.efxclipse.tooling.css.cssDsl.ruleset; import at.bestsolution.efxclipse.tooling.css.cssDsl.term; import at.bestsolution.efxclipse.tooling.css.cssDsl.termGroup; import at.bestsolution.efxclipse.tooling.css.ui.internal.CssDialectExtensionComponent; import at.bestsolution.efxclipse.tooling.css.ui.internal.CssDslActivator; /** * see http://www.eclipse.org/Xtext/documentation/latest/xtext.html#contentAssist on how to customize content assistant */ public class CssDslProposalProvider extends AbstractCssDslProposalProvider { private CssDialectExtensionComponent extension; public CssDslProposalProvider() { BundleContext context = CssDslActivator.getInstance().getBundle().getBundleContext(); ServiceReference<CssDialectExtensionComponent> ref = context.getServiceReference(CssDialectExtensionComponent.class); extension = context.getService(ref); } @Override public void complete_css_property(EObject model, RuleCall ruleCall, ContentAssistContext context, ICompletionProposalAcceptor acceptor) { if( model instanceof ruleset ) { for( Property property : extension.getProperties(model.eResource().getURI()) ) { acceptor.accept(createCompletionProposal(property.getName(), property.getName(), null, context)); } } super.complete_css_property(model, ruleCall, context, acceptor); } @Override public void complete_expr(EObject model, RuleCall ruleCall, ContentAssistContext context, ICompletionProposalAcceptor acceptor) { // System.err.println("Expression Proposal: " + model); // if( context.getCurrentModel() instanceof css_generic_declaration ) { // css_generic_declaration o = (css_generic_declaration) model; // Property p = getProperty(extension.getProperties(), o.getProperty()); // // if( p != null ) { // for( Proposal proposal : p.getInitialTermProposals() ) { // acceptor.accept(createCompletionProposal(proposal.getLabel(), proposal.getLabel(), null, context)); // } // } // } else { // super.complete_expr(model, ruleCall, context, acceptor); // } } @Override public void complete_termGroup(EObject model, RuleCall ruleCall, ContentAssistContext context, ICompletionProposalAcceptor acceptor) { // System.err.println("TermGroup proposal: " + context.getCurrentModel()); // if( context.getCurrentModel() instanceof css_generic_declaration ) { // css_generic_declaration dec = (css_generic_declaration) context.getCurrentModel(); // // } // super.complete_termGroup(model, ruleCall, context, acceptor); } @Override public void complete_term(EObject model, RuleCall ruleCall, ContentAssistContext context, ICompletionProposalAcceptor acceptor) { // System.err.println("Term proposal: " + context.getCurrentModel()); //// System.err.println(ruleCall.eContainer()); if( context.getCurrentModel() instanceof css_generic_declaration ) { // We get in here on the 1st value of the first group // We get in here on the 2nd ... value of the first group css_generic_declaration dec = (css_generic_declaration) context.getCurrentModel(); if( dec.getExpression() == null || dec.getExpression().getTermGroups().size() == 0) { // System.err.println("This is the initial"); Property p = getProperty(extension.getProperties(model.eResource().getURI()), dec.getProperty()); if( p != null ) { addProposals(p.getInitialTermProposals(), acceptor, context); return; } } } else if( context.getCurrentModel() instanceof termGroup ) { // We get in here on 2nd value of first group // We get in here on 2nd value of 2nd ... group termGroup group = (termGroup) context.getCurrentModel(); expr expression = (expr) group.eContainer(); css_generic_declaration dec = (css_generic_declaration) expression.eContainer(); if( expression.getTermGroups().indexOf(group) == 0 ) { Property p = getProperty(extension.getProperties(model.eResource().getURI()), dec.getProperty()); // System.err.println("This is the first group"); if( p instanceof MultiValuesGroupProperty ) { addProposals(((MultiValuesGroupProperty) p).getNextTermProposal(group.getTerms().size(), group, null), acceptor, context); // System.err.println("Property with multi terms in a group"); } } else { // System.err.println("This is 2nd ... in 2nd group"); Property p = getProperty(extension.getProperties(model.eResource().getURI()), dec.getProperty()); if( p instanceof MultiTermGroupProperty && p instanceof MultiValuesGroupProperty ) { // System.err.println("Property with multi terms in a group"); addProposals(((MultiValuesGroupProperty) p).getNextTermProposal(group.getTerms().size(), group, null), acceptor, context); } } } else if( context.getCurrentModel() instanceof expr ) { // We get in here on 1st value if 2nd ... group // We get in here on 2nd value of 2nd ... group expr expression = (expr) context.getCurrentModel(); css_generic_declaration dec = (css_generic_declaration) expression.eContainer(); Property p = getProperty(extension.getProperties(model.eResource().getURI()), dec.getProperty()); if( p instanceof MultiTermGroupProperty ) { addProposals(((MultiTermGroupProperty) p).getInitialTermProposal(0, dec), acceptor, context); } /*if( expression.getTermGroups().size() == 0 ) { System.err.println("First in 2nd group"); }*/ // System.err.println(expression.getTermGroups().size()); } else if( context.getCurrentModel() instanceof term ) { term term = (term) context.getCurrentModel(); termGroup group = (termGroup) term.eContainer(); expr expression = (expr) group.eContainer(); if( expression.eContainer() instanceof css_generic_declaration ) { css_generic_declaration dec = (css_generic_declaration) expression.eContainer(); Property p = getProperty(extension.getProperties(model.eResource().getURI()), dec.getProperty()); if( p != null ) { int groupIdx = expression.getTermGroups().indexOf(group); if( groupIdx == 0 ) { // We are in the first group int idx = group.getTerms().indexOf(term) + 1; if( idx == 0 ) { // We are in the first term in the group // System.err.println("First term"); addProposals(p.getInitialTermProposals(), acceptor, context); } else if( p instanceof MultiValuesGroupProperty ) { // System.err.println("Second term"); MultiValuesGroupProperty tmp = (MultiValuesGroupProperty) p; addProposals(tmp.getNextTermProposal(idx, group, term), acceptor, context); } } else { if( p instanceof MultiTermGroupProperty ) { MultiTermGroupProperty tmp = (MultiTermGroupProperty) p; int idx = group.getTerms().indexOf(term) + 1; if( idx == 0 ) { // System.err.println("First term in > 1 group"); addProposals(tmp.getInitialTermProposal(groupIdx, dec), acceptor, context); } else if( p instanceof MultiValuesGroupProperty ) { // System.err.println("2nd term in > 1 group"); MultiValuesGroupProperty tmp2 = (MultiValuesGroupProperty) p; addProposals(tmp2.getNextTermProposal(idx, group, term), acceptor, context); } } } } } } // if( model instanceof term ) { // term t = (term) model; // if( t.eContainer() instanceof termGroup ) { // termGroup tgr = (termGroup) t.eContainer(); // if( tgr.eContainer() instanceof expr ) { // expr expression = (expr) tgr.eContainer(); // if( expression.eContainer() instanceof css_generic_declaration ) { // css_generic_declaration dec = (css_generic_declaration) expression.eContainer(); // if( createExpressionFurtherTermProposals(dec, expression, tgr, t) ) { // return; // } // } // } // } // } super.complete_term(model, ruleCall, context, acceptor); } private void addProposals(List<Proposal> proposals, ICompletionProposalAcceptor acceptor, ContentAssistContext context) { for( Proposal proposal : proposals ) { if( proposal instanceof DialogProposal ) { final DialogProposal dProp = (DialogProposal) proposal; ConfigurableCompletionProposal dialogProposal = (ConfigurableCompletionProposal) createCompletionProposal(proposal.getLabel(),context); if( dialogProposal != null ) { dialogProposal.setTextApplier(new ReplacementTextApplier() { @Override public String getActualReplacementString( ConfigurableCompletionProposal proposal) { return dProp.openProposal(); } }); } acceptor.accept(dialogProposal); } else { acceptor.accept(createCompletionProposal(proposal.getLabel(), new StyledString(proposal.getLabel()), null, proposal.getPriority(), context.getPrefix(), context)); } } } private boolean createExpressionFurtherTermProposals(css_generic_declaration dec, expr expression, termGroup tgr, term t) { // This is the >= 2nd group if( expression.getTermGroups().indexOf(tgr) != 0 ) { Property p = getProperty(extension.getProperties(dec.eResource().getURI()), dec.getProperty()); if( p instanceof MultiTermGroupProperty ) { if( tgr.getTerms().indexOf(t) == 0 ) { // Show the initial proposals return true; } else if( p instanceof MultiValuesGroupProperty ) { // Show the extended proposals } return true; } } else { Property p = getProperty(extension.getProperties(dec.eResource().getURI()), dec.getProperty()); if( p instanceof MultiValuesGroupProperty ) { if( tgr.getTerms().indexOf(t) > 0 ) { // Show the extended proposals } } } return false; } private static Property getProperty(List<Property> properties, String property) { if( property == null || property.trim().length() == 0 ) { return null; } for( Property p : properties ) { if( property.equals(p.getName()) ) { return p; } } return null; } // public static List<String> getProposals(String property) { // if( property.equals("border-top-style") // || property.equals("border-right-style") // || property.equals("border-bottom-style") // || property.equals("border-left-style") ) { // return Arrays.asList("none", "hidden", "dotted", "dashed", "solid", "double", "groove", "ridge", "inset", "outset" ); // } // return Collections.emptyList(); // } }