/******************************************************************************* * Copyright (c) 2011 - 2015 Red Hat, Inc. * All rights reserved. * This program is 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: * Red Hat, Inc. - initial API and implementation * * @author Innar Made ******************************************************************************/ package org.eclipse.bpmn2.modeler.ui.editor; import java.io.IOException; import java.util.ArrayList; import java.util.Iterator; import java.util.List; import org.eclipse.bpmn2.BaseElement; import org.eclipse.bpmn2.Definitions; import org.eclipse.bpmn2.di.BPMNDiagram; import org.eclipse.bpmn2.modeler.core.LifecycleEvent; import org.eclipse.bpmn2.modeler.core.LifecycleEvent.EventType; import org.eclipse.bpmn2.modeler.core.di.DIImport; import org.eclipse.bpmn2.modeler.core.di.DIUtils; import org.eclipse.bpmn2.modeler.core.merrimac.clad.Bpmn2TabbedPropertySheetPage; import org.eclipse.bpmn2.modeler.core.model.Bpmn2ModelerResourceImpl; import org.eclipse.bpmn2.modeler.core.model.ModelHandler; import org.eclipse.bpmn2.modeler.core.model.ModelHandlerLocator; import org.eclipse.bpmn2.modeler.core.model.ProxyURIConverterImplExtension; import org.eclipse.bpmn2.modeler.core.preferences.Bpmn2Preferences; import org.eclipse.bpmn2.modeler.core.preferences.ModelEnablements; import org.eclipse.bpmn2.modeler.core.preferences.ShapeStyle; import org.eclipse.bpmn2.modeler.core.runtime.TargetRuntime; import org.eclipse.bpmn2.modeler.core.runtime.TargetRuntimeAdapter; import org.eclipse.bpmn2.modeler.core.runtime.ToolPaletteDescriptor; import org.eclipse.bpmn2.modeler.core.utils.BusinessObjectUtil; import org.eclipse.bpmn2.modeler.core.utils.DiagramEditorAdapter; import org.eclipse.bpmn2.modeler.core.utils.FeatureSupport; import org.eclipse.bpmn2.modeler.core.utils.ModelUtil; import org.eclipse.bpmn2.modeler.core.utils.ModelUtil.Bpmn2DiagramType; import org.eclipse.bpmn2.modeler.core.utils.StyleUtil; import org.eclipse.bpmn2.modeler.help.IHelpContexts; import org.eclipse.bpmn2.modeler.ui.Activator; import org.eclipse.bpmn2.modeler.ui.Bpmn2DiagramEditorInput; import org.eclipse.bpmn2.modeler.ui.diagram.Bpmn2ToolBehaviorProvider; import org.eclipse.bpmn2.modeler.ui.property.PropertyTabDescriptorProvider; import org.eclipse.bpmn2.modeler.ui.views.outline.BPMN2EditorOutlinePage; import org.eclipse.bpmn2.modeler.ui.views.outline.BPMN2EditorSelectionSynchronizer; import org.eclipse.bpmn2.modeler.ui.wizards.BPMN2DiagramCreator; import org.eclipse.bpmn2.modeler.ui.wizards.FileService; import org.eclipse.bpmn2.util.Bpmn2ResourceImpl; import org.eclipse.core.resources.IFile; import org.eclipse.core.resources.IProject; import org.eclipse.core.resources.ResourcesPlugin; import org.eclipse.core.runtime.IPath; import org.eclipse.core.runtime.IProgressMonitor; import org.eclipse.core.runtime.Path; import org.eclipse.core.runtime.preferences.IEclipsePreferences.IPreferenceChangeListener; import org.eclipse.core.runtime.preferences.IEclipsePreferences.PreferenceChangeEvent; import org.eclipse.draw2d.IFigure; import org.eclipse.draw2d.MarginBorder; import org.eclipse.emf.common.command.BasicCommandStack; import org.eclipse.emf.common.notify.Notification; import org.eclipse.emf.common.util.BasicDiagnostic; import org.eclipse.emf.common.util.URI; import org.eclipse.emf.ecore.resource.Resource; import org.eclipse.emf.ecore.resource.ResourceSet; import org.eclipse.emf.transaction.NotificationFilter; import org.eclipse.emf.transaction.RecordingCommand; import org.eclipse.emf.transaction.TransactionalEditingDomain; import org.eclipse.emf.transaction.TransactionalEditingDomain.Lifecycle; import org.eclipse.emf.transaction.impl.TransactionalEditingDomainImpl; import org.eclipse.gef.EditPart; import org.eclipse.gef.GraphicalViewer; import org.eclipse.gef.MouseWheelHandler; import org.eclipse.gef.MouseWheelZoomHandler; import org.eclipse.gef.editparts.AbstractGraphicalEditPart; import org.eclipse.gef.ui.parts.SelectionSynchronizer; import org.eclipse.graphiti.features.IFeatureProvider; import org.eclipse.graphiti.features.IUpdateFeature; import org.eclipse.graphiti.features.context.impl.UpdateContext; import org.eclipse.graphiti.mm.algorithms.GraphicsAlgorithm; import org.eclipse.graphiti.mm.pictograms.Diagram; import org.eclipse.graphiti.mm.pictograms.PictogramElement; import org.eclipse.graphiti.mm.pictograms.Shape; import org.eclipse.graphiti.services.Graphiti; import org.eclipse.graphiti.services.IGaService; import org.eclipse.graphiti.ui.editor.DiagramBehavior; import org.eclipse.graphiti.ui.editor.DiagramEditor; import org.eclipse.graphiti.ui.editor.DiagramEditorInput; import org.eclipse.graphiti.ui.internal.editor.GFPaletteRoot; import org.eclipse.jface.viewers.ISelection; import org.eclipse.jface.viewers.IStructuredSelection; import org.eclipse.jface.viewers.StructuredSelection; import org.eclipse.swt.SWT; import org.eclipse.swt.events.DisposeEvent; import org.eclipse.swt.events.DisposeListener; import org.eclipse.swt.widgets.Composite; import org.eclipse.swt.widgets.Display; import org.eclipse.ui.IEditorInput; import org.eclipse.ui.IEditorPart; import org.eclipse.ui.IEditorSite; import org.eclipse.ui.IWorkbenchPart; import org.eclipse.ui.PartInitException; import org.eclipse.ui.PlatformUI; import org.eclipse.ui.views.contentoutline.IContentOutlinePage; import org.eclipse.ui.views.properties.IPropertySheetPage; import org.eclipse.ui.views.properties.tabbed.ITabDescriptorProvider; @SuppressWarnings("restriction") public class DefaultBPMN2Editor extends DiagramEditor implements IPreferenceChangeListener { static { TargetRuntime.createTargetRuntimes(); } public static final String CONTRIBUTOR_ID = "org.eclipse.bpmn2.modeler.ui.PropertyContributor"; //$NON-NLS-1$ protected ModelHandler modelHandler; protected URI modelUri; protected URI diagramUri; private boolean editable = true; protected BPMNDiagram bpmnDiagram; protected Bpmn2ResourceImpl bpmnResource; // We need this to find BPMN2 Editors that are already open for this file // Used when opening a New Editor window for an already open editor. private IEditorInput currentInput; private static ITabDescriptorProvider tabDescriptorProvider; private BPMN2EditingDomainListener editingDomainListener; private boolean selectionChanging; protected Bpmn2Preferences preferences; protected TargetRuntime targetRuntime; private ModelEnablements modelEnablements; private boolean importInProgress; private BPMN2EditorSelectionSynchronizer synchronizer; protected DiagramEditorAdapter editorAdapter; protected IPropertySheetPage propertySheetPage; protected IContentOutlinePage outlinePage; protected boolean saveInProgress = false; private static NotificationFilter filterNone = new NotificationFilter.Custom() { @Override public boolean matches(Notification notification) { return false; } }; @Override public IEditorInput getEditorInput() { return currentInput; } protected DiagramEditorAdapter getEditorAdapter() { return editorAdapter; } @Override public void init(IEditorSite site, IEditorInput input) throws PartInitException { currentInput = input; if (this.getDiagramBehavior()==null) { super.init(site, input); } else if (input instanceof Bpmn2DiagramEditorInput) { bpmnDiagram = ((Bpmn2DiagramEditorInput)input).getBpmnDiagram(); if (bpmnDiagram!=null) { setBpmnDiagram(bpmnDiagram); } } } /** * Beware, creates a new input and changes this editor! */ protected Bpmn2DiagramEditorInput createNewDiagramEditorInput(IEditorInput input, Bpmn2DiagramType diagramType, String targetNamespace) throws PartInitException { modelUri = FileService.getInputUri(input); if (modelUri==null) throw new PartInitException(Messages.BPMN2Editor_Cannot_Create_Editor_Input); input = BPMN2DiagramCreator.createDiagram(input, modelUri, diagramType,targetNamespace,this); diagramUri = ((Bpmn2DiagramEditorInput)input).getUri(); return (Bpmn2DiagramEditorInput)input; } /** * Bypasses Graphiti's Persistency Behavior code and save only the BPMN2 model resource. * This is only used after a successful Import if the BPMN2 model was changed in any way, * e.g. missing DI elements were added. */ private void saveModelFile() { try { bpmnResource.save(null); ((BasicCommandStack) getEditingDomain().getCommandStack()).saveIsDone(); updateDirtyState(); } catch (IOException e) { Activator.logError(e); } } protected EditorInputHelper getInputHelper() { return new EditorInputHelper(); } @Override protected void setInput(IEditorInput input) { EditorInputHelper inputHelper = getInputHelper(); inputHelper.preSetInput(input, this); super.setInput(input); inputHelper.postSetInput(input, this); } @Override protected DiagramEditorInput convertToDiagramEditorInput(IEditorInput input) throws PartInitException { IEditorInput newInput = createNewDiagramEditorInput(input, Bpmn2DiagramType.NONE, ""); //$NON-NLS-1$ if (newInput==null) newInput = super.convertToDiagramEditorInput(input); return (DiagramEditorInput) newInput; } protected void importDiagram() { try { importInProgress = true; // make sure this guy is active, otherwise it's not selectable Diagram diagram = getDiagramTypeProvider().getDiagram(); IFeatureProvider featureProvider = getDiagramTypeProvider().getFeatureProvider(); diagram.setActive(true); Bpmn2DiagramEditorInput input = (Bpmn2DiagramEditorInput) getEditorInput(); Bpmn2DiagramType diagramType = input.getInitialDiagramType(); String targetNamespace = input.getTargetNamespace(); if (diagramType != Bpmn2DiagramType.NONE) { bpmnDiagram = modelHandler.createDiagramType(diagramType, targetNamespace); featureProvider.link(diagram, bpmnDiagram); // If the bpmn file was missing DI elements, they would have been added by the importer // so save the file now in case it was changed. saveModelFile(); } else if (targetNamespace != null && !targetNamespace.isEmpty()) { modelHandler.getDefinitions().setTargetNamespace(targetNamespace); } DIImport di = new DIImport(this, getPreferences()); di.setModelHandler(modelHandler); di.generateFromDI(); } finally { importInProgress = false; } } public void setEditable(boolean editable) { this.editable = editable; } public boolean isEditable() { return editable; } @Override public boolean isDirty() { if (!editable) return false; if (getEditorInput()==null) return false; return super.isDirty(); } @Override protected DiagramBehavior createDiagramBehavior() { DiagramBehavior diagramBehavior = new DefaultBPMN2EditorDiagramBehavior(this); return diagramBehavior; } public Bpmn2Preferences getPreferences() { if (preferences==null) { loadPreferences(getProject()); } return preferences; } private void loadPreferences(IProject project) { preferences = Bpmn2Preferences.getInstance(project); preferences.addPreferenceChangeListener(this); } /** * ID for tabbed property sheets. * * @return the contributor id */ @Override public String getContributorId() { return CONTRIBUTOR_ID; } public TargetRuntime getTargetRuntime() { if (targetRuntime==null) { targetRuntime = getTargetRuntime(getEditorInput()); } return targetRuntime; } public ModelEnablements getModelEnablements() { String profileName = getPreferences().getDefaultToolProfile(getTargetRuntime()); if (modelEnablements!=null) { if (!modelEnablements.getId().equals(profileName)) { modelEnablements = null; } } if (modelEnablements==null) { modelEnablements = getPreferences().getModelEnablements(getTargetRuntime(), profileName); if (modelEnablements.size()==0) { // This Target Runtime doesn't define a Tool Profile // so we'll use the one for Default Runtime profileName = getPreferences().getDefaultToolProfile(TargetRuntime.getDefaultRuntime()); ModelEnablements defaultEnablements = getPreferences().getModelEnablements(TargetRuntime.getDefaultRuntime(), profileName); modelEnablements.copy(defaultEnablements); } } return modelEnablements; } protected TargetRuntime getTargetRuntime(IEditorInput input) { if (targetRuntime==null && input!=null) { // If the project has not been configured for a specific runtime through the "BPMN2" // project properties page (i.e. the target is "None") then allow the runtime extension // plug-ins an opportunity to identify the given process file contents as their own. // If none of the plug-ins respond with "yes, this file is targeted for my runtime", // then use the "None" as the extension. This will configure the BPMN2 Modeler with // generic property sheets and other default behavior. if (input instanceof Bpmn2DiagramEditorInput) targetRuntime = ((Bpmn2DiagramEditorInput)input).getRuntime(); if (targetRuntime==null) targetRuntime = TargetRuntime.getRuntime(input); } return targetRuntime; } public void updatePalette() { GFPaletteRoot pr = (GFPaletteRoot)getPaletteRoot(); if (pr!=null) { // force a reload of this modelEnablements = null; pr.updatePaletteEntries(); Bpmn2ToolBehaviorProvider toolBehaviorProvider = (Bpmn2ToolBehaviorProvider)getDiagramTypeProvider(). getCurrentToolBehaviorProvider(); toolBehaviorProvider.createPaletteProfilesGroup(this, pr); } } @Override public void refreshTitle() { if (getEditorInput()!=null) { String name = getEditorInput().getName(); setPartName(URI.decode(name)); } } public BPMN2EditingDomainListener getEditingDomainListener() { if (editingDomainListener==null) { TransactionalEditingDomainImpl editingDomain = (TransactionalEditingDomainImpl)getEditingDomain(); if (editingDomain==null) { return null; } editingDomainListener = new BPMN2EditingDomainListener(this); Lifecycle domainLifeCycle = editingDomain.getAdapter(Lifecycle.class); domainLifeCycle.addTransactionalEditingDomainListener(editingDomainListener); } return editingDomainListener; } public BasicDiagnostic getDiagnostics() { return getEditingDomainListener().getDiagnostics(); } @Override protected SelectionSynchronizer getSelectionSynchronizer() { if (synchronizer == null) synchronizer = new BPMN2EditorSelectionSynchronizer(); return synchronizer; } @SuppressWarnings("rawtypes") @Override public Object getAdapter(Class required) { if (required==DiagramEditor.class) { return this; } if (required==ITabDescriptorProvider.class) { if (tabDescriptorProvider==null) { tabDescriptorProvider = new PropertyTabDescriptorProvider(); // IWorkbenchPage page = getEditorSite().getPage(); // String viewID = "org.eclipse.ui.views.PropertySheet"; //$NON-NLS-1$ // try { // page.showView(viewID, null, IWorkbenchPage.VIEW_CREATE); // page.showView(viewID, null, IWorkbenchPage.VIEW_ACTIVATE); // } // catch (Exception e) {} } return tabDescriptorProvider; } if (required==TargetRuntime.class) return getTargetRuntime(); if (required==Bpmn2Preferences.class) return getPreferences(); if (required == IPropertySheetPage.class) { if (propertySheetPage==null) { propertySheetPage = new Bpmn2TabbedPropertySheetPage(this); Display.getCurrent().asyncExec(new Runnable() { @Override public void run() { if (!propertySheetPage.getControl().isDisposed()) { propertySheetPage.getControl().addDisposeListener(new DisposeListener() { @Override public void widgetDisposed(DisposeEvent e) { propertySheetPage = null; } }); } } }); } return propertySheetPage; } if (required == SelectionSynchronizer.class) { return getSelectionSynchronizer(); } if (required == IContentOutlinePage.class) { if (getDiagramTypeProvider() != null) { if (outlinePage==null) { outlinePage = new BPMN2EditorOutlinePage(this); } return outlinePage; } } if (required == ModelEnablements.class) { return getModelEnablements(); } if (required == ToolPaletteDescriptor.class) { String profileName = getPreferences().getDefaultToolProfile(getTargetRuntime()); return getTargetRuntime().getToolPalette(profileName); } if (required == NotificationFilter.class) { if (saveInProgress) return filterNone; else return null; } if (required==GraphicalViewer.class) { return getGraphicalViewer(); } if (required==Resource.class) { return getResource(); } return super.getAdapter(required); } @Override public void dispose() { if (targetRuntime != null) { targetRuntime.notify(new LifecycleEvent(EventType.EDITOR_SHUTDOWN, this, targetRuntime)); } if (modelHandler!=null) { modelHandler.dispose(); } if (preferences != null) { preferences.removePreferenceChangeListener(this); } // cancel the Property Sheet Page job if (propertySheetPage!=null) propertySheetPage.selectionChanged(this, null); // get rid of cached Property Tab Descriptors if (tabDescriptorProvider instanceof PropertyTabDescriptorProvider) ((PropertyTabDescriptorProvider)tabDescriptorProvider).disposeTabDescriptors(bpmnResource); if (getResourceSet() != null) { getResourceSet().eAdapters().remove(getEditorAdapter()); } super.dispose(); if (modelUri != null) { ModelHandlerLocator.remove(modelUri); } if (preferences != null) { preferences.dispose(); } currentInput = null; } public IPath getModelPath() { if (getModelFile()!=null) return getModelFile().getFullPath(); return null; } public IProject getProject() { if (getModelFile()!=null) return getModelFile().getProject(); return null; } public IFile getModelFile() { if (modelUri!=null) { String uriString = modelUri.trimFragment().toPlatformString(true); if (uriString!=null) { IPath fullPath = new Path(uriString); return ResourcesPlugin.getWorkspace().getRoot().getFile(fullPath); } } return null; } public URI getModelUri() { return modelUri; } public URI getDiagramUri() { return diagramUri; } public ModelHandler getModelHandler() { return modelHandler; } public Resource getResource() { return bpmnResource; } public ResourceSet getResourceSet() { TransactionalEditingDomain editingDomain = getEditingDomain(); return editingDomain != null ? editingDomain.getResourceSet() : null; } public void refresh() { if (!importInProgress) getDiagramBehavior().getRefreshBehavior().refresh(); } @Override public void createPartControl(Composite parent) { if (getGraphicalViewer()==null) { super.createPartControl(parent); PlatformUI.getWorkbench().getHelpSystem().setHelp(parent, IHelpContexts.TOC); } } public BPMNDiagram getBpmnDiagram() { if (bpmnDiagram==null) { Definitions definitions = ModelUtil.getDefinitions(bpmnResource); if (definitions!=null && definitions.getDiagrams().size()>0) bpmnDiagram = definitions.getDiagrams().get(0); } // if (bpmnDiagram!=null) { // GraphicalViewer viewer = getGraphicalViewer(); // mapDiagramToViewer.put(bpmnDiagram, viewer); // } return bpmnDiagram; } public void setBpmnDiagram(final BPMNDiagram bpmnDiagram) { // create a new Graphiti Diagram if needed Diagram diagram = DIUtils.getOrCreateDiagram(getDiagramBehavior(), bpmnDiagram); // clear current selection to avoid confusing the GraphicalViewer selectPictogramElements(new PictogramElement[] {}); // Tell the DTP about the new Diagram getDiagramTypeProvider().resourceReloaded(diagram); getDiagramBehavior().getRefreshBehavior().initRefresh(); setPictogramElementsForSelection(null); // set Diagram as contents for the graphical viewer and refresh GraphicalViewer viewer = getGraphicalViewer(); viewer.setContents(diagram); EditPart ep = viewer.getRootEditPart().getContents(); if (ep instanceof AbstractGraphicalEditPart) { IFigure fig = ((AbstractGraphicalEditPart)ep).getFigure(); fig.setBorder(new MarginBorder(0,0,50,50)); } ConnectionLayerClippingStrategy.applyTo(viewer); getDiagramBehavior().refreshContent(); // remember this for later this.bpmnDiagram = bpmnDiagram; modelEnablements = null; } @Override public void doSave(IProgressMonitor monitor) { final PictogramElement selections[] = getSelectedPictogramElements(); // long start = System.currentTimeMillis(); try { saveInProgress = true; // System.out.print("Saving..."); super.doSave(monitor); } finally { saveInProgress = false; } // System.out.println("done in "+(System.currentTimeMillis()-start)+" ms"); Display.getCurrent().asyncExec(new Runnable() { @Override public void run() { selectPictogramElements(selections); } }); } @Override public boolean isSaveAsAllowed() { return getModelFile()!=null; } //////////////////////////////////////////////////////////////////////////////// // Other handlers //////////////////////////////////////////////////////////////////////////////// @Override public synchronized void selectionChanged(IWorkbenchPart part, ISelection selection) { if (!selectionChanging && selection instanceof IStructuredSelection) { try { selectionChanging = true; // Filter out label shapes as these are controlled by their ContainerShape owners // For example a "Select All" key action would select Labels as well. Iterator iter = ((IStructuredSelection)selection).iterator(); List<Object> filteredObjects = new ArrayList<Object>(); List<PictogramElement> pictogramElements = new ArrayList<PictogramElement>(); while (iter.hasNext()) { boolean addIt = true; Object o = iter.next(); if (o instanceof EditPart) { Object model = ((EditPart)o).getModel(); if (model instanceof PictogramElement) { if (FeatureSupport.isLabelShape((PictogramElement)model)) { addIt = false; } else { pictogramElements.add((PictogramElement)model); } } } if (addIt) filteredObjects.add(o); } IStructuredSelection filteredSelection = new StructuredSelection(filteredObjects); // Graphiti understands multipage editors // but apparently GEF doesn't super.selectionChanged(part,filteredSelection); // Graphiti's DiagramEditorInternal super.selectPictogramElements(pictogramElements.toArray(new PictogramElement[pictogramElements.size()])); updateActions(getSelectionActions()); // usually done in GEF's GraphicalEditor } finally { selectionChanging = false; } } // if the selected element is obscured by another shape // send it to the top of the z-stack. // FIXME: this should be done in the figure's UpdateFeature or LayoutFeature, not here. // final List<ContainerShape> moved = new ArrayList<ContainerShape>(); // for (PictogramElement pe : getSelectedPictogramElements()) { // if (pe instanceof ContainerShape && !(pe instanceof Diagram)) { // final ContainerShape shape = (ContainerShape)pe; // ContainerShape container = shape.getContainer(); // // make sure this shape has not been deleted // if (container==null) // continue; // int size = container.getChildren().size(); // if (size>1) { // // don't send Choreography Participant bands, Pools or Lanes to front // // they're already there... // BaseElement baseElement = BusinessObjectUtil.getFirstBaseElement(shape); // if (baseElement instanceof Participant || baseElement instanceof Lane) // continue; // boolean obscured = false; // int index = container.getChildren().indexOf(shape); // for (int i=index+1; i<container.getChildren().size(); ++i) { // PictogramElement sibling = container.getChildren().get(i); // if (sibling instanceof ContainerShape && // !FeatureSupport.isLabelShape((ContainerShape)sibling)) { // if (GraphicsUtil.intersects(shape, (ContainerShape)sibling)) { // boolean siblingIsBoundaryEvent = false; // if (baseElement instanceof Activity) { // BaseElement be = BusinessObjectUtil.getFirstBaseElement(sibling); // for (BoundaryEvent boundaryEvent : ((Activity)baseElement).getBoundaryEventRefs()) { // if (be==boundaryEvent) { // siblingIsBoundaryEvent = true; // break; // } // } // } // if (!siblingIsBoundaryEvent) { // obscured = true; // } // } // } // } // // if the selected shape is an Activity, it may have Boundary Event shapes // // attached to it - these will have to be moved to the top so they're // // not obscured by the Activity. // if (baseElement instanceof Activity) { // for (BoundaryEvent be : ((Activity)baseElement).getBoundaryEventRefs()) { // for (PictogramElement child : container.getChildren()) { // if (child instanceof ContainerShape && BusinessObjectUtil.getFirstBaseElement(child) == be) { // index = container.getChildren().indexOf(child); // for (int i=index+1; i<container.getChildren().size(); ++i) { // PictogramElement sibling = container.getChildren().get(i); // if (sibling!=shape && sibling instanceof ContainerShape) { // if (GraphicsUtil.intersects((ContainerShape)child, (ContainerShape)sibling)) { // obscured = true; // moved.add((ContainerShape)child); // } // } // } // } // } // } // } // if (obscured) { // moved.add(0,shape); // } // } // } // } // if (!moved.isEmpty()) { // Display.getDefault().asyncExec(new Runnable() { // @Override // public void run() { // getEditingDomain().getCommandStack().execute(new RecordingCommand(getEditingDomain()) { // @Override // protected void doExecute() { // for (ContainerShape child : moved) { // GraphicsUtil.sendToFront(child); // } // } // }); // } // }); // } } @Override public void preferenceChange(final PreferenceChangeEvent event) { getPreferences().reload(); if (event.getKey().contains("/"+Bpmn2Preferences.PREF_MODEL_ENABLEMENT+"/")) //$NON-NLS-1$ //$NON-NLS-2$ modelEnablements = null; if (event.getKey().contains(Bpmn2Preferences.PREF_SHOW_ADVANCED_PROPERTIES) || event.getKey().contains("/"+Bpmn2Preferences.PREF_TOOL_PROFILE+"/")) { //$NON-NLS-1$ //$NON-NLS-2$ // get rid of cached Property Tab Descriptors if (tabDescriptorProvider instanceof PropertyTabDescriptorProvider) ((PropertyTabDescriptorProvider)tabDescriptorProvider).disposeTabDescriptors(bpmnResource); } if (event.getKey().contains("/"+Bpmn2Preferences.PREF_SHAPE_STYLE+"/")) { //$NON-NLS-1$ //$NON-NLS-2$ int i = event.getKey().lastIndexOf('/'); if (i<=0) return; // Get the object type whose ShapeStyle has changed (e.g. "Task") // and change it if possible. This needs to run in a transaction. final String name = event.getKey().substring(i+1); getEditingDomain().getCommandStack().execute(new RecordingCommand(getEditingDomain()) { @Override protected void doExecute() { IFeatureProvider fp = DefaultBPMN2Editor.this.getDiagramTypeProvider().getFeatureProvider(); // Collect all PictogramElements and their corresponding GraphicsAlgorithms // to which the ShapeStyle change applies. Resource resource = getDiagramTypeProvider().getDiagram().eResource(); for (PictogramElement pe : ModelUtil.getAllObjectsOfType(resource, PictogramElement.class)) { BaseElement be = BusinessObjectUtil.getFirstElementOfType(pe, BaseElement.class); // The Business Object class name must match the ShapeStyle type if (be!=null && be.eClass().getName().equals(name)) { // find this PE's GraphicsAlgorithrms that has the // PREF_SHAPE_STYLE property set - this is the GA to // which the ShapeStyle applies. GraphicsAlgorithm ga = StyleUtil.getShapeStyleContainer(pe); // If the ShapeStyle for this BaseElement has already // been changed by the user, do not reset it. String style = ShapeStyle.encode(ShapeStyle.getShapeStyle(be)); if (style.equals(event.getNewValue())) { StyleUtil.applyStyle(ga, be); if (pe instanceof Shape && FeatureSupport.isLabelShape(pe)) { UpdateContext context = new UpdateContext(pe); IUpdateFeature feature = fp.getUpdateFeature(context); if (feature!=null && feature.canUpdate(context)) { feature.update(context); } } } } } } }); } if (event.getKey().contains(ShapeStyle.Category.GRID.toString())) { //$NON-NLS-1$ getEditingDomain().getCommandStack().execute(new RecordingCommand(getEditingDomain()) { @Override protected void doExecute() { ShapeStyle ss = getPreferences().getShapeStyle(ShapeStyle.Category.GRID); Diagram diagram = getDiagramTypeProvider().getDiagram(); diagram.setGridUnit(ss.getDefaultWidth()); diagram.setVerticalGridUnit(ss.getDefaultHeight()); diagram.setSnapToGrid(ss.getSnapToGrid()); GraphicsAlgorithm ga = diagram.getGraphicsAlgorithm(); IGaService gaService = Graphiti.getGaService(); ga.setForeground(gaService.manageColor(diagram, ss.getShapeForeground())); refresh(); getGraphicalControl().redraw(); } }); } if (event.getKey().contains(ShapeStyle.Category.CANVAS.toString())) { //$NON-NLS-1$ getEditingDomain().getCommandStack().execute(new RecordingCommand(getEditingDomain()) { @Override protected void doExecute() { ShapeStyle ss = getPreferences().getShapeStyle(ShapeStyle.Category.CANVAS); Diagram diagram = getDiagramTypeProvider().getDiagram(); GraphicsAlgorithm ga = diagram.getGraphicsAlgorithm(); IGaService gaService = Graphiti.getGaService(); ga.setBackground(gaService.manageColor(diagram, ss.getShapeBackground())); refresh(); getGraphicalControl().redraw(); } }); } } public static IEditorPart openEditor(URI modelURI) { IEditorPart part = null; try { Bpmn2DiagramEditorInput input = BPMN2DiagramCreator.createDiagram(modelURI, Bpmn2DiagramType.NONE, ""); //$NON-NLS-1$ part = BPMN2DiagramCreator.openEditor(input); } catch (Exception e) { e.printStackTrace(); } return part; } @Override public void configureGraphicalViewer() { super.configureGraphicalViewer(); // add zooming action with "CTRL + Mouse Wheel" GraphicalViewer viewer = getGraphicalViewer(); viewer.setProperty(MouseWheelHandler.KeyGenerator.getKey(SWT.MOD1), MouseWheelZoomHandler.SINGLETON); } /** * helper class used to handle setInput() of the editor, because of it's complexity split it up in own class, * which may be overridden and customized * * @author Flavio Donz� * */ public class EditorInputHelper { /** * method called in editor.setInput() previous to super.setInput() * * @param input * @param editor */ public void preSetInput(IEditorInput input, DefaultBPMN2Editor editor) { input = recreateInput(input, editor); ResourceSet resourceSet = initializeResourceSet(input, editor); editor.bpmnResource = createBPMN2Resource(editor, resourceSet); } protected IEditorInput recreateInput(IEditorInput input, DefaultBPMN2Editor editor) { try { if (input instanceof Bpmn2DiagramEditorInput) { Bpmn2DiagramType diagramType = Bpmn2DiagramType.NONE; String targetNamespace = null; diagramType = ((Bpmn2DiagramEditorInput)input).getInitialDiagramType(); targetNamespace = ((Bpmn2DiagramEditorInput)input).getTargetNamespace(); input = editor.createNewDiagramEditorInput(input, diagramType, targetNamespace); } editor.currentInput = input; } catch (Exception e) { Activator.logError(e); } return input; } protected ResourceSet initializeResourceSet(IEditorInput input, DefaultBPMN2Editor editor) { // Determine which Target Runtime to use for this input and initialize the ResourceSet TargetRuntime targetRuntime = editor.getTargetRuntime(input); targetRuntime.notify(new LifecycleEvent(EventType.EDITOR_STARTUP,editor, targetRuntime)); ResourceSet resourceSet = editor.getEditingDomain().getResourceSet(); resourceSet.setURIConverter(new ProxyURIConverterImplExtension(editor.modelUri)); resourceSet.eAdapters().add(editor.editorAdapter = new DiagramEditorAdapter(editor)); // Tell the TargetRuntime about the ResourceSet. This allows the TargetRuntime to provide its // own ResourceFactory if needed. targetRuntime.registerExtensionResourceFactory(resourceSet); return resourceSet; } protected Bpmn2ResourceImpl createBPMN2Resource(DefaultBPMN2Editor editor, ResourceSet resourceSet) { Bpmn2ResourceImpl resource = (Bpmn2ResourceImpl) resourceSet.createResource(editor.modelUri, Bpmn2ModelerResourceImpl.BPMN2_CONTENT_TYPE_ID); // make sure resource has target runtime adapter TargetRuntimeAdapter.adapt(resource, getTargetRuntime()); return resource; } /** * method called in editor.setInput() after super.setInput() * * @param input * @param editor */ public void postSetInput(IEditorInput input, DefaultBPMN2Editor editor) { // Hook a transaction exception handler so we can get diagnostics about EMF validation errors. editor.getEditingDomainListener(); // This does the actual loading of the resource. // TODO: move the loading code to BPMN2PersistencyBehavior where it belongs, // and get rid of ModelHandler and ModelHandlerLocator editor.modelHandler = ModelHandlerLocator.createModelHandler(editor.modelUri, editor.bpmnResource); ModelHandlerLocator.put(editor.diagramUri, editor.modelHandler); TargetRuntime rt = editor.getTargetRuntime(); rt.notify(new LifecycleEvent(EventType.EDITOR_INITIALIZED, editor, rt)); importDiagram(input, editor); } protected void importDiagram(IEditorInput input, final DefaultBPMN2Editor editor) { try { editor.getPreferences().setDoCoreValidation(false); // Import the BPMNDI model that creates the Graphiti shapes, connections, etc. BasicCommandStack commandStack = (BasicCommandStack) editor.getEditingDomain().getCommandStack(); commandStack.execute(new RecordingCommand(editor.getEditingDomain()) { @Override protected void doExecute() { editor.importDiagram(); } }); Definitions definitions = ModelUtil.getDefinitions(editor.bpmnResource); if (definitions!=null) { // we'll need this in case doSaveAs() ((Bpmn2DiagramEditorInput)input).setTargetNamespace(definitions.getTargetNamespace()); ((Bpmn2DiagramEditorInput)input).setInitialDiagramType(ModelUtil.getDiagramType(editor)); } // Reset the save point and initialize the undo stack commandStack.saveIsDone(); commandStack.flush(); } finally { editor.getPreferences().setDoCoreValidation(true); } } } }