/** * Copyright (c) 2010 committers of YAKINDU 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: * committers of YAKINDU - initial API and implementation * */ package org.yakindu.sct.ui.editor.providers; import java.util.List; import org.eclipse.draw2d.FlowLayout; import org.eclipse.draw2d.Label; import org.eclipse.emf.ecore.EObject; import org.eclipse.gef.EditDomain; import org.eclipse.gef.EditPart; import org.eclipse.gef.editparts.AbstractConnectionEditPart; import org.eclipse.gmf.runtime.diagram.ui.editparts.GraphicalEditPart; import org.eclipse.gmf.runtime.diagram.ui.editparts.IPrimaryEditPart; import org.eclipse.gmf.runtime.diagram.ui.parts.DiagramEditDomain; import org.eclipse.gmf.runtime.diagram.ui.services.decorator.AbstractDecorator; import org.eclipse.gmf.runtime.diagram.ui.services.decorator.IDecoratorProvider; import org.eclipse.gmf.runtime.diagram.ui.services.decorator.IDecoratorTarget; import org.eclipse.gmf.runtime.notation.Edge; import org.eclipse.gmf.runtime.notation.View; import org.eclipse.swt.graphics.Image; import org.eclipse.ui.IEditorPart; import org.eclipse.ui.ISharedImages; import org.eclipse.ui.PlatformUI; import org.eclipse.xtext.diagnostics.Severity; import org.eclipse.xtext.validation.Issue; import org.yakindu.base.gmf.runtime.decorators.AbstractDecoratorProvider; import org.yakindu.sct.model.sgraph.FinalState; import org.yakindu.sct.model.sgraph.Pseudostate; import org.yakindu.sct.model.sgraph.ui.validation.SCTIssue; import org.yakindu.sct.ui.editor.editor.StatechartDiagramEditor; import org.yakindu.sct.ui.editor.editparts.BorderItemEditPart; import org.yakindu.sct.ui.editor.validation.IValidationIssueStore; import org.yakindu.sct.ui.editor.validation.IValidationIssueStore.IValidationIssueStoreListener; /** * * @author Andreas Muelder - Initial contribution and API * */ public class StatechartValidationDecorationProvider extends AbstractDecoratorProvider implements IDecoratorProvider { private static final String KEY = "org.yakindu.sct.ui.editor.validation"; private IValidationIssueStore issueStore; public void createDecorators(IDecoratorTarget decoratorTarget) { EditPart editPart = (EditPart) decoratorTarget.getAdapter(EditPart.class); if(editPart instanceof BorderItemEditPart) return; if (editPart instanceof IPrimaryEditPart && (editPart instanceof GraphicalEditPart || editPart instanceof AbstractConnectionEditPart)) { EditDomain ed = editPart.getViewer().getEditDomain(); if (!(ed instanceof DiagramEditDomain)) { return; } if (shouldInstall(((DiagramEditDomain) ed).getEditorPart())) { decoratorTarget.installDecorator(getDecoratorKey(), createStatusDecorator(decoratorTarget, issueStore)); } } } protected boolean shouldInstall(IEditorPart part) { if (part instanceof StatechartDiagramEditor) { issueStore = (IValidationIssueStore) part.getAdapter(IValidationIssueStore.class); return true; } return false; } protected String getDecoratorKey() { return KEY; } protected ValidationDecorator createStatusDecorator(IDecoratorTarget decoratorTarget, IValidationIssueStore store) { return new ValidationDecorator(decoratorTarget, store); } public static class ValidationDecorator extends AbstractDecorator implements IValidationIssueStoreListener { private IValidationIssueStore store; private String semanticID; public ValidationDecorator(IDecoratorTarget decoratorTarget, IValidationIssueStore store) { super(decoratorTarget); this.store = store; } public void refresh() { View view = (View) getDecoratorTarget().getAdapter(View.class); if (view == null || view.eResource() == null) { return; } EObject element = view.getElement(); if (element != null) semanticID = element.eResource().getURIFragment(element); removeDecoration(); EditPart editPart = (EditPart) getDecoratorTarget().getAdapter(EditPart.class); if (editPart == null || editPart.getViewer() == null || !(editPart instanceof IPrimaryEditPart)) { return; } decorate(view); } public void activate() { store.addIssueStoreListener(this); } public void deactivate() { super.deactivate(); } protected void decorate(View view) { List<SCTIssue> issues = store.getIssues(semanticID); Severity severity = Severity.INFO; Label toolTip = null; if (issues.isEmpty()) return; for (int i = 0; i < issues.size(); i++) { Issue issue = issues.get(i); Severity nextSeverity = issue.getSeverity(); Image nextImage = getImage(nextSeverity); if (toolTip == null) { toolTip = new Label(issue.getMessage(), nextImage); } else { if (toolTip.getChildren().isEmpty()) { Label comositeLabel = new Label(); FlowLayout fl = new FlowLayout(false); fl.setMinorSpacing(0); comositeLabel.setLayoutManager(fl); comositeLabel.add(toolTip); toolTip = comositeLabel; } toolTip.add(new Label(issue.getMessage(), nextImage)); } severity = (nextSeverity.ordinal() < severity.ordinal()) ? nextSeverity : severity; } if (view instanceof Edge) { setDecoration(getDecoratorTarget().addConnectionDecoration(getImage(severity), 50, true)); getDecoration().setToolTip(toolTip); } else { int margin = view.getElement() instanceof Pseudostate || view.getElement() instanceof FinalState ? 0 : -1; setDecoration(getDecoratorTarget().addShapeDecoration(getImage(severity), IDecoratorTarget.Direction.NORTH_EAST, margin, true)); getDecoration().setToolTip(toolTip); } } protected Image getImage(Severity severity) { String imageName = ISharedImages.IMG_OBJS_ERROR_TSK; switch (severity) { case ERROR: imageName = ISharedImages.IMG_OBJS_ERROR_TSK; break; case WARNING: imageName = ISharedImages.IMG_OBJS_WARN_TSK; break; default: imageName = ISharedImages.IMG_OBJS_INFO_TSK; } return PlatformUI.getWorkbench().getSharedImages().getImage(imageName); } @Override public void issuesChanged() { refresh(); } @Override public String getSemanticURI() { return semanticID; } } }