| /******************************************************************************* |
| * <copyright> |
| * |
| * Copyright (c) 2011, 2012 SAP AG. |
| * 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: |
| * Bug 336488 - DiagramEditor API |
| * pjpaulin - Bug 352120 - Now uses IDiagramContainerUI interface |
| * |
| * </copyright> |
| * |
| *******************************************************************************/ |
| package org.eclipse.graphiti.ui.editor; |
| |
| import org.eclipse.draw2d.Figure; |
| import org.eclipse.gef.EditPart; |
| import org.eclipse.gef.GraphicalEditPart; |
| import org.eclipse.graphiti.dt.IDiagramTypeProvider; |
| import org.eclipse.graphiti.features.IDirectEditingInfo; |
| import org.eclipse.graphiti.features.IFeatureProvider; |
| import org.eclipse.graphiti.features.IUpdateFeature; |
| import org.eclipse.graphiti.features.context.IUpdateContext; |
| import org.eclipse.graphiti.features.context.impl.UpdateContext; |
| import org.eclipse.graphiti.internal.pref.GFPreferences; |
| import org.eclipse.graphiti.internal.util.T; |
| import org.eclipse.graphiti.mm.pictograms.Diagram; |
| import org.eclipse.graphiti.mm.pictograms.PictogramElement; |
| import org.eclipse.graphiti.tb.IToolBehaviorProvider; |
| import org.eclipse.graphiti.ui.internal.config.IConfigurationProviderInternal; |
| import org.eclipse.graphiti.ui.internal.editor.RefreshPerformanceCache; |
| import org.eclipse.graphiti.ui.internal.parts.IPictogramElementDelegate; |
| import org.eclipse.graphiti.ui.internal.parts.IPictogramElementEditPart; |
| import org.eclipse.graphiti.ui.internal.parts.IShapeEditPart; |
| import org.eclipse.graphiti.ui.internal.parts.ShapeEditPart; |
| import org.eclipse.swt.widgets.Display; |
| |
| /** |
| * The default implementation for the {@link DiagramBehavior} behavior extension |
| * that controls the refresh behavior of the Graphiti diagram editor. Clients |
| * may subclass to change the behavior; use |
| * {@link DiagramBehavior#createRefreshBehavior()} to return the instance that |
| * shall be used.<br> |
| * Note that there is always a 1:1 relation with a {@link DiagramBehavior}. |
| * |
| * @since 0.9 |
| */ |
| public class DefaultRefreshBehavior { |
| |
| /** |
| * The associated {@link DiagramBehavior}. Set on construction of this class. |
| * |
| * @since 0.10 |
| */ |
| protected final DiagramBehavior diagramBehavior; |
| |
| private RefreshPerformanceCache refreshPerformanceCache = new RefreshPerformanceCache(); |
| |
| /** |
| * Creates a new standard refresh behaviour for a Graphiti diagram editor. |
| * The passed {@link DiagramBehavior} is closely linked to this instance (1:1 |
| * relation) and both instances will have a common lifecycle. |
| * |
| * @param diagramEditor |
| * The associated {@link DiagramBehavior}. |
| * @since 0.10 |
| */ |
| public DefaultRefreshBehavior(DiagramBehavior diagramBehavior) { |
| super(); |
| this.diagramBehavior = diagramBehavior; |
| } |
| |
| /** |
| * Initializes the performance cache and is called by the Graphiti framework |
| * before a refresh is triggered. Should not be called by clients. |
| * |
| * @noreference This method is not intended to be referenced by clients. |
| * @since 0.9 |
| */ |
| public void initRefresh() { |
| getRefreshPerformanceCache().initRefresh(); |
| } |
| |
| /** |
| * Handles the auto update at startup of the editor and is called by the |
| * Graphiti {@link DiagramBehavior} when the input is set ( |
| * {@link DiagramBehavior#setInput(org.eclipse.ui.IEditorInput)}). The |
| * default implementation checks the desired behavior as defined in |
| * {@link IDiagramTypeProvider#isAutoUpdateAtStartup()} and calls |
| * {@link #autoUpdate(Diagram, IDiagramTypeProvider)} in case an update |
| * shall be done. |
| * |
| * @since 0.9 |
| */ |
| protected void handleAutoUpdateAtStartup() { |
| IDiagramTypeProvider diagramTypeProvider = diagramBehavior.getDiagramTypeProvider(); |
| if (diagramTypeProvider.isAutoUpdateAtStartup()) { |
| autoUpdate(); |
| } |
| } |
| |
| /** |
| * Handles the auto update at rest of the editor (the editor performs a |
| * reload of the EMF resources because e.g. the underlying file has been |
| * changed by another editor) and is called by the Graphiti |
| * {@link DiagramBehavior} after the {@link Diagram} has been reloaded. The |
| * default implementation checks the desired behavior as defined in |
| * {@link IDiagramTypeProvider#isAutoUpdateAtReset()} and calls |
| * {@link #autoUpdate(Diagram, IDiagramTypeProvider)} in case an update |
| * shall be done. |
| * |
| * @since 0.9 |
| */ |
| protected void handleAutoUpdateAtReset() { |
| IDiagramTypeProvider diagramTypeProvider = diagramBehavior.getDiagramTypeProvider(); |
| if (diagramTypeProvider.isAutoUpdateAtReset()) { |
| autoUpdate(); |
| } |
| } |
| |
| /** |
| * Handles the auto update of the editor and triggers an update of the |
| * {@link Diagram} by delegating to the {@link IUpdateFeature} regsitered |
| * for the {@link Diagram}. In the end {@link #refresh()} is called to |
| * reflect the update in the editor UI. This method is called by |
| * {@link #handleAutoUpdateAtStartup()} and |
| * {@link #handleAutoUpdateAtReset()}. |
| * |
| * @since 0.9 |
| */ |
| protected void autoUpdate() { |
| IDiagramTypeProvider diagramTypeProvider = diagramBehavior.getDiagramTypeProvider(); |
| Diagram diagram = diagramTypeProvider.getDiagram(); |
| IFeatureProvider featureProvider = diagramTypeProvider.getFeatureProvider(); |
| IUpdateContext updateCtx = new UpdateContext(diagram); |
| featureProvider.updateIfPossible(updateCtx); |
| refresh(); |
| } |
| |
| /** |
| * Does the refresh of the editor, so that the UI reflects the current state |
| * of the Graphiti pictograms model. Also the editor title is updated; in |
| * case direct editing is active it is cancelled. |
| */ |
| public void refresh() { |
| if (!diagramBehavior.isAlive()) { |
| return; |
| } |
| |
| if (Display.getCurrent() == null) { |
| Display.getDefault().asyncExec(new Runnable() { |
| public void run() { |
| refresh(); |
| } |
| }); |
| return; |
| } |
| |
| if (GFPreferences.getInstance().isCPUProfilingTraceActive()) { |
| if (T.racer().info()) { |
| T.racer().info("DiagramEditorInternal.refresh()"); //$NON-NLS-1$ |
| } |
| } |
| |
| long start = System.currentTimeMillis(); |
| |
| final EditPart contentEditPart = diagramBehavior.getContentEditPart(); |
| if (contentEditPart == null) { |
| return; |
| } |
| |
| internalRefreshEditPart(contentEditPart); |
| |
| diagramBehavior.getDiagramContainer().refreshTitle(); |
| |
| long stop = System.currentTimeMillis(); |
| long time = (stop - start); |
| if (time > 500) { |
| String output = "refresh took " + time + " ms."; //$NON-NLS-1$ //$NON-NLS-2$ |
| T.racer().warning("DiagramEditorInternal.refresh() ", output); //$NON-NLS-1$ |
| } |
| |
| // prove if switch to direct editing is required |
| IDirectEditingInfo dei = diagramBehavior.getConfigurationProvider().getFeatureProvider().getDirectEditingInfo(); |
| if (dei.isActive()) { |
| EditPart editPart = (EditPart) diagramBehavior.getDiagramContainer().getGraphicalViewer().getEditPartRegistry() |
| .get(dei.getMainPictogramElement()); |
| if (editPart instanceof ShapeEditPart) { |
| ShapeEditPart shapeEditPart = (ShapeEditPart) editPart; |
| shapeEditPart.switchToDirectEditingMode(dei.getPictogramElement(), dei.getGraphicsAlgorithm()); |
| // reset values |
| dei.reset(); |
| } |
| } |
| diagramBehavior.selectBufferedPictogramElements(); |
| } |
| |
| /** |
| * Refreshes the given {@link PictogramElement} so that the UI reflects the |
| * current state in the Graphiti pictograms model. |
| * |
| * @param pe |
| * the {@link PictogramElement} to refresh |
| */ |
| protected void refresh(PictogramElement pe) { |
| if (pe == null || !pe.isActive()) { |
| return; |
| } |
| GraphicalEditPart editPart = diagramBehavior.getEditPartForPictogramElement(pe); |
| if (editPart != null && editPart instanceof IPictogramElementEditPart) { |
| IPictogramElementEditPart ep = (IPictogramElementEditPart) editPart; |
| IPictogramElementDelegate delegate = ep.getPictogramElementDelegate(); |
| delegate.setForceRefresh(true); |
| editPart.refresh(); |
| delegate.setForceRefresh(false); |
| } |
| } |
| |
| /** |
| * Refreshes all rendering decorators for the given {@link PictogramElement} |
| * as defined in |
| * {@link IToolBehaviorProvider#getDecorators(PictogramElement)}. |
| * |
| * @param pe |
| * the {@link PictogramElement} to refresh the decorators for |
| */ |
| public void refreshRenderingDecorators(PictogramElement pe) { |
| GraphicalEditPart ep = diagramBehavior.getEditPartForPictogramElement(pe); |
| if (ep instanceof IShapeEditPart) { |
| IShapeEditPart sep = (IShapeEditPart) ep; |
| sep.refreshDecorators(); |
| } |
| } |
| |
| /** |
| * Internal refresh of a given {@link EditPart}. |
| * |
| * @param editPart |
| * the edit part to refresh |
| * @noreference This method is not intended to be referenced by clients. |
| */ |
| public void internalRefreshEditPart(final EditPart editPart) { |
| if (Display.getCurrent() == null) { |
| Display.getDefault().syncExec(new Runnable() { |
| public void run() { |
| internalRefreshEditPart(editPart); |
| // refreshOutline(); |
| } |
| }); |
| return; |
| } |
| |
| long start = System.currentTimeMillis(); |
| |
| try { |
| ((IConfigurationProviderInternal) diagramBehavior.getConfigurationProvider()).getContextButtonManager() |
| .hideContextButtonsInstantly(); |
| |
| editPart.refresh(); |
| |
| long stop = System.currentTimeMillis(); |
| long time = (stop - start); |
| if (time > 500) { |
| String output = "refreshEditPart took " + time + " ms."; //$NON-NLS-1$ //$NON-NLS-2$ |
| T.racer().warning("DiagramEditorInternal.refreshEditPart() ", output); //$NON-NLS-1$ |
| } |
| } catch (NullPointerException e) { |
| T.racer().error("refresh edit part problem", e); //$NON-NLS-1$ |
| } |
| } |
| |
| /** |
| * Returns if auto refresh is enabled or not. In case it is enabled the |
| * editor will automatically react on EMF resource changes. |
| * <p> |
| * The default implementation here simply returns <code>true</code>. |
| * |
| * @return true, if is auto refresh |
| */ |
| public boolean isAutoRefresh() { |
| return true; |
| } |
| |
| /** |
| * Returns if multiple refreshes shall be omitted and a bundled refresh |
| * should happen instead. Is called by the framework on creation and |
| * refreshing of {@link Figure}s. |
| * <p> |
| * The default implementation simply returns <code>true</code>. <b>Note:</b> |
| * returning false here might have large performance implications, so use |
| * this option only with extra care! |
| * |
| * @return |
| */ |
| public boolean isMultipleRefreshSupressionActive() { |
| return true; |
| } |
| |
| /** |
| * Checks the performance cache if a refresh shall be triggered for the |
| * given object. Should not be called by external clients. |
| * |
| * @noreference This method is not intended to be referenced by clients. |
| * @since 0.9 |
| */ |
| public boolean shouldRefresh(Object obj) { |
| return getRefreshPerformanceCache().shouldRefresh(obj); |
| } |
| |
| private RefreshPerformanceCache getRefreshPerformanceCache() { |
| return refreshPerformanceCache; |
| } |
| } |