/** * Copyright (c) 2011 Cloudsmith Inc. and other contributors, as listed below. * 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: * Cloudsmith * */ package org.cloudsmith.geppetto.pp.dsl.formatting; import org.cloudsmith.geppetto.pp.dsl.formatting.IBreakAndAlignAdvice.WhenToApply; import org.cloudsmith.xtext.dommodel.IDomNode; import org.cloudsmith.xtext.dommodel.formatter.DomNodeLayoutFeeder; import org.cloudsmith.xtext.dommodel.formatter.ILayoutManager.ILayoutContext; import org.cloudsmith.xtext.dommodel.formatter.LayoutUtils; import org.cloudsmith.xtext.textflow.ITextFlow; import org.eclipse.emf.ecore.EObject; import org.eclipse.xtext.AbstractElement; import com.google.inject.Inject; import com.google.inject.Provider; /** * @author henrik * */ public abstract class AbstractListLayout { @Inject DomNodeLayoutFeeder feeder; @Inject LayoutUtils layoutUtils; @Inject Provider<IBreakAndAlignAdvice> breakAlignAdviceProvider; protected boolean format(IDomNode node, ITextFlow flow, ILayoutContext context) { final IBreakAndAlignAdvice advisor = getAlignAdvice(); final WhenToApply advice = advisor.listsAdvice(); final int clusterWidth = advisor.clusterSize(); boolean breakAndAlign = false; // Do not break and align unless there is more than one element in the list/hash if(hasMoreThanOneElement(node.getSemanticObject())) switch(advice) { case Never: break; case Always: breakAndAlign = true; break; case OnOverflow: // Measure fit from start to final significant element (not counting trailing WS/breaks) if(!layoutUtils.fitsOnSameLine(node, getLastSignificantGrammarElement(), flow, context)) breakAndAlign = true; break; } markup(node, breakAndAlign, clusterWidth, flow, context); // that was easy return false; } protected IBreakAndAlignAdvice getAlignAdvice() { return breakAlignAdviceProvider.get(); } protected abstract AbstractElement getLastSignificantGrammarElement(); protected abstract boolean hasMoreThanOneElement(EObject semantic); protected abstract void markup(IDomNode node, final boolean breakAndAlign, final int clusterWidth, ITextFlow flow, ILayoutContext context); }