/***************************************************************************** * Copyright (c) 2010-2011 Atos Origin. * * * 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: * Mathieu Velten (Atos Origin) mathieu.velten@atosorigin.com - Initial API and implementation * *****************************************************************************/ package org.eclipse.papyrus.infra.gmfdiag.navigation.decorator; import java.util.HashSet; import java.util.LinkedList; import java.util.List; import java.util.Set; import org.eclipse.core.runtime.CoreException; import org.eclipse.core.runtime.IConfigurationElement; import org.eclipse.core.runtime.Platform; import org.eclipse.draw2d.ColorConstants; import org.eclipse.emf.common.notify.Adapter; import org.eclipse.emf.common.notify.Notification; import org.eclipse.emf.common.notify.Notifier; import org.eclipse.emf.ecore.EObject; import org.eclipse.emf.ecore.resource.Resource; import org.eclipse.gef.EditPart; import org.eclipse.gmf.runtime.diagram.ui.editparts.ConnectionEditPart; import org.eclipse.gmf.runtime.diagram.ui.editparts.IGraphicalEditPart; import org.eclipse.gmf.runtime.diagram.ui.editparts.ShapeEditPart; import org.eclipse.gmf.runtime.diagram.ui.services.decorator.AbstractDecorator; import org.eclipse.gmf.runtime.diagram.ui.services.decorator.IDecoratorTarget; import org.eclipse.gmf.runtime.notation.Diagram; import org.eclipse.gmf.runtime.notation.View; import org.eclipse.jface.viewers.IColorProvider; import org.eclipse.papyrus.infra.core.utils.DiResourceSet; import org.eclipse.papyrus.infra.gmfdiag.common.DiagramsUtil; import org.eclipse.papyrus.infra.gmfdiag.navigation.ExistingNavigableElement; import org.eclipse.papyrus.infra.gmfdiag.navigation.NavigableElement; import org.eclipse.papyrus.infra.gmfdiag.navigation.NavigationHelper; import org.eclipse.papyrus.infra.gmfdiag.navigation.preference.INavigationPreferenceConstant; import org.eclipse.papyrus.infra.gmfdiag.preferences.Activator; import org.eclipse.papyrus.infra.widgets.toolbox.draw2d.ManuallyDrawnShortcutDecorationFigure; import org.eclipse.swt.graphics.Color; public class NavigationDecorator extends AbstractDecorator implements Adapter { private static final String EXTENSION_ID = "org.eclipse.papyrus.infra.gmfdiag.navigation.navigationColorProviders"; private static final String COLORPROVIDER_ID = "navigationColorProvider"; private static final String PROVIDER_ID = "provider"; private static List<IColorProvider> navigationColorProviders = new LinkedList<IColorProvider>(); static { // Reading data from plugins IConfigurationElement[] configElements = Platform.getExtensionRegistry().getConfigurationElementsFor(EXTENSION_ID); for(IConfigurationElement configElement : configElements) { if(COLORPROVIDER_ID.equals(configElement.getName())) { try { Object obj = configElement.createExecutableExtension(PROVIDER_ID); if(obj instanceof IColorProvider) { navigationColorProviders.add((IColorProvider)obj); } } catch (CoreException e) { } } } } private Set<Resource> listenedNotationResources = new HashSet<Resource>(); private ManuallyDrawnShortcutDecorationFigure shortcutFigure = new ManuallyDrawnShortcutDecorationFigure(); private IGraphicalEditPart gep = null; private boolean displayOnly; public NavigationDecorator(IDecoratorTarget decoratorTarget) { super(decoratorTarget); decoratorTarget.installDecorator("navigationDecorator", this); shortcutFigure.setVisible(false); String decoratorVisibility = Activator.getDefault().getPreferenceStore().getString(INavigationPreferenceConstant.PAPYRUS_NAVIGATION_DECORATOR_VISIBILITY); displayOnly = INavigationPreferenceConstant.DISPLAY_ONLY.equals(decoratorVisibility); } @Override public void deactivate() { super.deactivate(); removeListenerFromAllResources(); } public void activate() { EditPart editPart = (EditPart)getDecoratorTarget().getAdapter(EditPart.class); if(editPart instanceof IGraphicalEditPart) { gep = (IGraphicalEditPart)editPart; if(editPart instanceof ShapeEditPart) { setDecoration(getDecoratorTarget().addShapeDecoration(shortcutFigure, IDecoratorTarget.Direction.NORTH_EAST, -5, displayOnly)); } else if(editPart instanceof ConnectionEditPart) { setDecoration(getDecoratorTarget().addConnectionDecoration(shortcutFigure, 20, displayOnly)); } } refresh(); } public void refresh() { if(gep != null) { View view = gep.getNotationView(); EObject element = gep.resolveSemanticElement(); removeListenerFromAllResources(); Diagram currentDiagram = null; if(view != null) { currentDiagram = view.getDiagram(); } if(currentDiagram != null) { addResourceListener(currentDiagram.eResource()); } List<NavigableElement> navElements = NavigationHelper.getInstance().getAllNavigableElements(element); Color shortcutColor = null; for(NavigableElement navElement : navElements) { if(navElement instanceof ExistingNavigableElement) { EObject eObj = navElement.getElement(); Resource res = eObj.eResource(); if(res != null && res.getResourceSet() instanceof DiResourceSet) { Resource notationResource = ((DiResourceSet)res.getResourceSet()).getAssociatedNotationResource(eObj); addResourceListener(notationResource); List<Diagram> associatedDiagrams = DiagramsUtil.getAssociatedDiagramsFromNotationResource(eObj, notationResource); if(associatedDiagrams != null) { for(Diagram diag : associatedDiagrams) { addResourceListener(diag.eResource()); if(!diag.equals(currentDiagram)) { for(IColorProvider provider : navigationColorProviders) { Color color = provider.getBackground(navElement); if(color != null) { if(shortcutColor == null) { shortcutColor = color; } else if(!shortcutColor.equals(color)) { // more than one color for this // element : // just use white in this case shortcutColor = ColorConstants.white; } break; } } } } } } } } if(shortcutColor == null) { shortcutFigure.setVisible(false); } else { shortcutFigure.setVisible(true); shortcutFigure.setBackgroundColor(shortcutColor); } } } private void addResourceListener(Resource r) { if(r != null) { synchronized(listenedNotationResources) { if(listenedNotationResources.add(r)) { r.eAdapters().add(this); } } } } private void removeListenerFromAllResources() { synchronized(listenedNotationResources) { for(Resource r : listenedNotationResources) { r.eAdapters().remove(this); } listenedNotationResources.clear(); } } public void notifyChanged(Notification notification) { if(!notification.isTouch() && notification.getFeatureID(Resource.class) == Resource.RESOURCE__CONTENTS) { refresh(); } } Notifier notifier; public Notifier getTarget() { return notifier; } public void setTarget(Notifier newTarget) { notifier = newTarget; } public boolean isAdapterForType(Object type) { return false; } }