Skip to main content
aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorHenrik Rentz-Reichert2011-01-14 02:17:48 -0500
committerHenrik Rentz-Reichert2011-01-14 02:17:48 -0500
commit55e6da33f04893cb2c9d1831e74e70dd3c33a6a8 (patch)
tree0d638ac2bf8b0cd6eb8517990a742050a9d9e589
parent5f393fc4bb4ae20fa60d93cfc93daddc8b67ba35 (diff)
downloadorg.eclipse.etrice-55e6da33f04893cb2c9d1831e74e70dd3c33a6a8.tar.gz
org.eclipse.etrice-55e6da33f04893cb2c9d1831e74e70dd3c33a6a8.tar.xz
org.eclipse.etrice-55e6da33f04893cb2c9d1831e74e70dd3c33a6a8.zip
behavior: initial version, incomplete
-rw-r--r--plugins/org.eclipse.etrice.ui.behavior/.settings/org.eclipse.jdt.core.prefs8
-rw-r--r--plugins/org.eclipse.etrice.ui.behavior/META-INF/MANIFEST.MF24
-rw-r--r--plugins/org.eclipse.etrice.ui.behavior/build.properties5
-rw-r--r--plugins/org.eclipse.etrice.ui.behavior/icons/Behavior.gifbin0 -> 119 bytes
-rw-r--r--plugins/org.eclipse.etrice.ui.behavior/icons/ChoicePoint.gifbin0 -> 122 bytes
-rw-r--r--plugins/org.eclipse.etrice.ui.behavior/icons/EntryPoint.gifbin0 -> 124 bytes
-rw-r--r--plugins/org.eclipse.etrice.ui.behavior/icons/ExitPoint.gifbin0 -> 124 bytes
-rw-r--r--plugins/org.eclipse.etrice.ui.behavior/icons/State.gifbin0 -> 117 bytes
-rw-r--r--plugins/org.eclipse.etrice.ui.behavior/icons/TrPoint.gifbin0 -> 115 bytes
-rw-r--r--plugins/org.eclipse.etrice.ui.behavior/icons/Transition.gifbin0 -> 113 bytes
-rw-r--r--plugins/org.eclipse.etrice.ui.behavior/plugin.xml51
-rw-r--r--plugins/org.eclipse.etrice.ui.behavior/src/org/eclipse/etrice/ui/behavior/Activator.java90
-rw-r--r--plugins/org.eclipse.etrice.ui.behavior/src/org/eclipse/etrice/ui/behavior/DiagramAccess.java122
-rw-r--r--plugins/org.eclipse.etrice.ui.behavior/src/org/eclipse/etrice/ui/behavior/DiagramTypeProvider.java38
-rw-r--r--plugins/org.eclipse.etrice.ui.behavior/src/org/eclipse/etrice/ui/behavior/ImageProvider.java40
-rw-r--r--plugins/org.eclipse.etrice.ui.behavior/src/org/eclipse/etrice/ui/behavior/NoResizeFeature.java46
-rw-r--r--plugins/org.eclipse.etrice.ui.behavior/src/org/eclipse/etrice/ui/behavior/ProviderDispatcher.java400
-rw-r--r--plugins/org.eclipse.etrice.ui.behavior/src/org/eclipse/etrice/ui/behavior/commands/PopulateDiagramCommand.java59
-rw-r--r--plugins/org.eclipse.etrice.ui.behavior/src/org/eclipse/etrice/ui/behavior/editor/BehaviorEditor.java29
-rw-r--r--plugins/org.eclipse.etrice.ui.behavior/src/org/eclipse/etrice/ui/behavior/support/Constants.java24
-rw-r--r--plugins/org.eclipse.etrice.ui.behavior/src/org/eclipse/etrice/ui/behavior/support/StateGraphSupport.java381
-rw-r--r--plugins/org.eclipse.etrice.ui.behavior/src/org/eclipse/etrice/ui/behavior/support/StateSupport.java730
-rw-r--r--plugins/org.eclipse.etrice.ui.behavior/src/org/eclipse/etrice/ui/behavior/support/TrPointSupport.java807
-rw-r--r--plugins/org.eclipse.etrice.ui.behavior/src/org/eclipse/etrice/ui/behavior/support/TransitionSupport.java341
24 files changed, 3195 insertions, 0 deletions
diff --git a/plugins/org.eclipse.etrice.ui.behavior/.settings/org.eclipse.jdt.core.prefs b/plugins/org.eclipse.etrice.ui.behavior/.settings/org.eclipse.jdt.core.prefs
new file mode 100644
index 000000000..dead08d5e
--- /dev/null
+++ b/plugins/org.eclipse.etrice.ui.behavior/.settings/org.eclipse.jdt.core.prefs
@@ -0,0 +1,8 @@
+#Wed Jan 05 13:25:23 CET 2011
+eclipse.preferences.version=1
+org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled
+org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.6
+org.eclipse.jdt.core.compiler.compliance=1.6
+org.eclipse.jdt.core.compiler.problem.assertIdentifier=error
+org.eclipse.jdt.core.compiler.problem.enumIdentifier=error
+org.eclipse.jdt.core.compiler.source=1.6
diff --git a/plugins/org.eclipse.etrice.ui.behavior/META-INF/MANIFEST.MF b/plugins/org.eclipse.etrice.ui.behavior/META-INF/MANIFEST.MF
new file mode 100644
index 000000000..2fe7e0c81
--- /dev/null
+++ b/plugins/org.eclipse.etrice.ui.behavior/META-INF/MANIFEST.MF
@@ -0,0 +1,24 @@
+Manifest-Version: 1.0
+Bundle-ManifestVersion: 2
+Bundle-Name: Actor Behavior Diagram Editor
+Bundle-SymbolicName: org.eclipse.etrice.ui.behavior;singleton:=true
+Bundle-Version: 0.1.0
+Bundle-Activator: org.eclipse.etrice.ui.behavior.Activator
+Require-Bundle: org.eclipse.etrice.core.room;bundle-version="0.1.0",
+ org.eclipse.graphiti;bundle-version="0.7.0",
+ org.eclipse.graphiti.ui;bundle-version="0.7.0",
+ org.eclipse.ui;bundle-version="3.6.0",
+ org.eclipse.ui.ide;bundle-version="3.6.0",
+ org.eclipse.ui.forms;bundle-version="3.5.0",
+ org.eclipse.ui.views.properties.tabbed;bundle-version="3.5.100",
+ org.eclipse.jface.databinding;bundle-version="1.4.0",
+ org.eclipse.core.databinding;bundle-version="1.3.100",
+ org.eclipse.core.databinding.property;bundle-version="1.3.0",
+ org.eclipse.core.databinding.beans;bundle-version="1.2.100",
+ org.eclipse.gef;bundle-version="3.6.1",
+ org.eclipse.emf.ecore.xmi;bundle-version="2.5.0",
+ org.eclipse.emf.transaction;bundle-version="1.4.0"
+Bundle-ActivationPolicy: lazy
+Bundle-RequiredExecutionEnvironment: JavaSE-1.6
+Bundle-Vendor: eTrice (Incubation)
+Export-Package: org.eclipse.etrice.ui.behavior
diff --git a/plugins/org.eclipse.etrice.ui.behavior/build.properties b/plugins/org.eclipse.etrice.ui.behavior/build.properties
new file mode 100644
index 000000000..6f20375d6
--- /dev/null
+++ b/plugins/org.eclipse.etrice.ui.behavior/build.properties
@@ -0,0 +1,5 @@
+source.. = src/
+output.. = bin/
+bin.includes = META-INF/,\
+ .,\
+ plugin.xml
diff --git a/plugins/org.eclipse.etrice.ui.behavior/icons/Behavior.gif b/plugins/org.eclipse.etrice.ui.behavior/icons/Behavior.gif
new file mode 100644
index 000000000..48918e82f
--- /dev/null
+++ b/plugins/org.eclipse.etrice.ui.behavior/icons/Behavior.gif
Binary files differ
diff --git a/plugins/org.eclipse.etrice.ui.behavior/icons/ChoicePoint.gif b/plugins/org.eclipse.etrice.ui.behavior/icons/ChoicePoint.gif
new file mode 100644
index 000000000..51c2b485a
--- /dev/null
+++ b/plugins/org.eclipse.etrice.ui.behavior/icons/ChoicePoint.gif
Binary files differ
diff --git a/plugins/org.eclipse.etrice.ui.behavior/icons/EntryPoint.gif b/plugins/org.eclipse.etrice.ui.behavior/icons/EntryPoint.gif
new file mode 100644
index 000000000..c8fbebfe2
--- /dev/null
+++ b/plugins/org.eclipse.etrice.ui.behavior/icons/EntryPoint.gif
Binary files differ
diff --git a/plugins/org.eclipse.etrice.ui.behavior/icons/ExitPoint.gif b/plugins/org.eclipse.etrice.ui.behavior/icons/ExitPoint.gif
new file mode 100644
index 000000000..39a054ce1
--- /dev/null
+++ b/plugins/org.eclipse.etrice.ui.behavior/icons/ExitPoint.gif
Binary files differ
diff --git a/plugins/org.eclipse.etrice.ui.behavior/icons/State.gif b/plugins/org.eclipse.etrice.ui.behavior/icons/State.gif
new file mode 100644
index 000000000..4c98299d9
--- /dev/null
+++ b/plugins/org.eclipse.etrice.ui.behavior/icons/State.gif
Binary files differ
diff --git a/plugins/org.eclipse.etrice.ui.behavior/icons/TrPoint.gif b/plugins/org.eclipse.etrice.ui.behavior/icons/TrPoint.gif
new file mode 100644
index 000000000..e7c4cb320
--- /dev/null
+++ b/plugins/org.eclipse.etrice.ui.behavior/icons/TrPoint.gif
Binary files differ
diff --git a/plugins/org.eclipse.etrice.ui.behavior/icons/Transition.gif b/plugins/org.eclipse.etrice.ui.behavior/icons/Transition.gif
new file mode 100644
index 000000000..cf02f2d33
--- /dev/null
+++ b/plugins/org.eclipse.etrice.ui.behavior/icons/Transition.gif
Binary files differ
diff --git a/plugins/org.eclipse.etrice.ui.behavior/plugin.xml b/plugins/org.eclipse.etrice.ui.behavior/plugin.xml
new file mode 100644
index 000000000..48e585b8e
--- /dev/null
+++ b/plugins/org.eclipse.etrice.ui.behavior/plugin.xml
@@ -0,0 +1,51 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<?eclipse version="3.4"?>
+<plugin>
+ <extension
+ point="org.eclipse.graphiti.ui.diagramTypes">
+ <diagramType
+ id="org.eclipse.etrice.ui.behavior.diagramType"
+ name="ROOM Behavior Diagram Type"
+ type="room.behavior">
+ </diagramType>
+ </extension>
+ <extension
+ point="org.eclipse.graphiti.ui.diagramTypeProviders">
+ <diagramTypeProvider
+ class="org.eclipse.etrice.ui.behavior.DiagramTypeProvider"
+ id="org.eclipse.etrice.ui.behavior.diagramTypeProvider"
+ name="ROOM Behavior Editor">
+ <diagramType
+ id="org.eclipse.etrice.ui.behavior.diagramType">
+ </diagramType>
+ <imageProvider
+ id="org.eclipse.etrice.ui.behavior.ImageProvider">
+ </imageProvider>
+ </diagramTypeProvider>
+ </extension>
+ <extension
+ point="org.eclipse.ui.editors">
+ <editor
+ class="org.eclipse.etrice.ui.behavior.editor.BehaviorEditor"
+ contributorClass="org.eclipse.graphiti.ui.editor.DiagramEditorActionBarContributor"
+ default="true"
+ extensions="behavior"
+ icon="icons/Behavior.gif"
+ id="org.eclipse.etrice.ui.behavior.editor.BehaviorEditor"
+ matchingStrategy="org.eclipse.graphiti.ui.editor.DiagramEditorFactory$DiagramEditorMatchingStrategy"
+ name="ROOM Behavior Editor">
+ <contentTypeBinding
+ contentTypeId="org.eclipse.graphiti.content.diagram">
+ </contentTypeBinding>
+ </editor>
+ </extension>
+
+ <extension
+ point="org.eclipse.graphiti.ui.imageProviders">
+ <imageProvider
+ class="org.eclipse.etrice.ui.behavior.ImageProvider"
+ id="org.eclipse.etrice.ui.behavior.ImageProvider">
+ </imageProvider>
+ </extension>
+
+</plugin>
diff --git a/plugins/org.eclipse.etrice.ui.behavior/src/org/eclipse/etrice/ui/behavior/Activator.java b/plugins/org.eclipse.etrice.ui.behavior/src/org/eclipse/etrice/ui/behavior/Activator.java
new file mode 100644
index 000000000..e384becdb
--- /dev/null
+++ b/plugins/org.eclipse.etrice.ui.behavior/src/org/eclipse/etrice/ui/behavior/Activator.java
@@ -0,0 +1,90 @@
+/*******************************************************************************
+ * Copyright (c) 2010 protos software gmbh (http://www.protos.de).
+ * 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:
+ * Thomas Schuetz and Henrik Rentz-Reichert (initial contribution)
+ *
+ *******************************************************************************/
+
+package org.eclipse.etrice.ui.behavior;
+
+import org.eclipse.jface.resource.ImageDescriptor;
+import org.eclipse.jface.resource.ImageRegistry;
+import org.eclipse.swt.graphics.Image;
+import org.eclipse.ui.plugin.AbstractUIPlugin;
+import org.osgi.framework.BundleContext;
+
+/**
+ * The activator class controls the plug-in life cycle
+ */
+public class Activator extends AbstractUIPlugin {
+
+ // The plug-in ID
+ public static final String PLUGIN_ID = "org.eclipse.etrice.ui.behavior"; //$NON-NLS-1$
+
+ // The shared instance
+ private static Activator plugin;
+
+ private ImageRegistry imageRegistry = new ImageRegistry();
+
+ /**
+ * The constructor
+ */
+ public Activator() {
+ }
+
+ /*
+ * (non-Javadoc)
+ * @see org.eclipse.ui.plugin.AbstractUIPlugin#start(org.osgi.framework.BundleContext)
+ */
+ public void start(BundleContext context) throws Exception {
+ super.start(context);
+ plugin = this;
+ }
+
+ /*
+ * (non-Javadoc)
+ * @see org.eclipse.ui.plugin.AbstractUIPlugin#stop(org.osgi.framework.BundleContext)
+ */
+ public void stop(BundleContext context) throws Exception {
+ plugin.imageRegistry.dispose();
+ plugin = null;
+ super.stop(context);
+ }
+
+ /**
+ * Returns the shared instance
+ *
+ * @return the shared instance
+ */
+ public static Activator getDefault() {
+ return plugin;
+ }
+
+ /**
+ * Returns an image descriptor for the image file at the given
+ * plug-in relative path
+ *
+ * @param path
+ * the path
+ * @return the image descriptor
+ */
+ public static Image getImage(String path) {
+ Image img = getDefault().imageRegistry.get(path);
+ if (img==null) {
+ ImageDescriptor desc = imageDescriptorFromPlugin(PLUGIN_ID, path);
+ if (desc==null)
+ System.err.println("image not found: "+path);
+ else {
+ getDefault().imageRegistry.put(path, desc);
+ getDefault().imageRegistry.get(path);
+ }
+ }
+ return img;
+ }
+
+}
diff --git a/plugins/org.eclipse.etrice.ui.behavior/src/org/eclipse/etrice/ui/behavior/DiagramAccess.java b/plugins/org.eclipse.etrice.ui.behavior/src/org/eclipse/etrice/ui/behavior/DiagramAccess.java
new file mode 100644
index 000000000..b4ab53a0d
--- /dev/null
+++ b/plugins/org.eclipse.etrice.ui.behavior/src/org/eclipse/etrice/ui/behavior/DiagramAccess.java
@@ -0,0 +1,122 @@
+/*******************************************************************************
+ * Copyright (c) 2010 protos software gmbh (http://www.protos.de).
+ * 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:
+ * Thomas Schuetz and Henrik Rentz-Reichert (initial contribution)
+ *
+ *******************************************************************************/
+
+package org.eclipse.etrice.ui.behavior;
+
+import java.io.IOException;
+import java.util.Collections;
+
+import org.eclipse.core.resources.IFile;
+import org.eclipse.core.resources.IFolder;
+import org.eclipse.core.resources.ResourcesPlugin;
+import org.eclipse.core.runtime.Path;
+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.ecore.resource.impl.ResourceSetImpl;
+import org.eclipse.emf.ecore.util.EcoreUtil;
+import org.eclipse.emf.transaction.TransactionalEditingDomain;
+import org.eclipse.emf.transaction.util.TransactionUtil;
+import org.eclipse.etrice.ui.behavior.commands.PopulateDiagramCommand;
+import org.eclipse.etrice.ui.behavior.editor.BehaviorEditor;
+import org.eclipse.graphiti.mm.pictograms.Diagram;
+import org.eclipse.graphiti.services.Graphiti;
+import org.eclipse.ui.IFileEditorInput;
+import org.eclipse.ui.PartInitException;
+import org.eclipse.ui.PlatformUI;
+import org.eclipse.ui.part.FileEditorInput;
+
+import org.eclipse.etrice.core.room.ActorClass;
+import org.eclipse.etrice.core.room.RoomModel;
+
+public class DiagramAccess {
+
+ private static final String DIAGRAMS_FOLDER_NAME = "diagrams";
+
+ public static Diagram getDiagram(ActorClass ac) {
+ Resource resource = ac.eResource();
+ if (resource==null)
+ return null;
+
+ URI uri = resource.getURI();
+ if (!uri.isPlatformResource())
+ return null;
+
+ uri = uri.trimSegments(1);
+ IFolder parentFolder = ResourcesPlugin.getWorkspace().getRoot().getFolder(new Path(uri.toPlatformString(true)));
+
+ IFolder diagramFolder = parentFolder.getFolder(DIAGRAMS_FOLDER_NAME);
+
+ RoomModel model = (RoomModel) ac.eContainer();
+
+ IFile diagramFile = diagramFolder.getFile(model.getName()+"."+ac.getName()+".behavior");
+ URI diagURI = URI.createPlatformResourceURI(diagramFile.getFullPath().toString(), true);
+
+ ResourceSet rs = new ResourceSetImpl();
+ if (diagramFile.exists()) {
+ Resource diagRes = rs.getResource(diagURI, true);
+ if (diagRes.getContents().isEmpty())
+ return null;
+ if (diagRes.getContents().get(0) instanceof Diagram)
+ return (Diagram) diagRes.getContents().get(0);
+ }
+ else {
+ Resource diagRes = rs.createResource(diagURI);
+
+ Diagram diagram = Graphiti.getPeCreateService().createDiagram("room.behavior", "Behavior of "+ac.getName(), true);
+ diagRes.getContents().add(diagram);
+
+ populatediagram(ac, diagram);
+
+ try {
+ diagRes.save(Collections.EMPTY_MAP);
+ } catch (IOException e) {
+ e.printStackTrace();
+ }
+ return diagram;
+ }
+
+ return null;
+ }
+
+ private static void populatediagram(ActorClass ac, Diagram diagram) {
+ ResourceSet rs = diagram.eResource().getResourceSet();
+ TransactionalEditingDomain editingDomain = TransactionUtil.getEditingDomain(rs);
+ if (editingDomain == null) {
+ // Not yet existing, create one
+ editingDomain = TransactionalEditingDomain.Factory.INSTANCE.createEditingDomain(rs);
+ }
+
+ // IMPORTANT STEP: this resolves the object and creates a new resource in the resource set
+ URI boUri = EcoreUtil.getURI(ac);
+ ac = (ActorClass) editingDomain.getResourceSet().getEObject(boUri, true);
+ ac.eResource().setTrackingModification(true);
+
+ editingDomain.getCommandStack().execute(new PopulateDiagramCommand(diagram, ac, editingDomain));
+ editingDomain.dispose();
+ }
+
+ public static void openDiagramEditor(ActorClass ac) {
+ Diagram diagram = getDiagram(ac);
+
+ String platformString = diagram.eResource().getURI().toPlatformString(true);
+ IFile file = ResourcesPlugin.getWorkspace().getRoot().getFile(new Path(platformString));
+ IFileEditorInput input = new FileEditorInput(file);
+
+ try {
+ PlatformUI.getWorkbench().getActiveWorkbenchWindow().getActivePage().openEditor(input, BehaviorEditor.BEHAVIOR_EDITOR_ID);
+ } catch (PartInitException e) {
+ String error = "Error while opening diagram editor";
+ System.err.println(error);
+ }
+ }
+}
diff --git a/plugins/org.eclipse.etrice.ui.behavior/src/org/eclipse/etrice/ui/behavior/DiagramTypeProvider.java b/plugins/org.eclipse.etrice.ui.behavior/src/org/eclipse/etrice/ui/behavior/DiagramTypeProvider.java
new file mode 100644
index 000000000..2d8617af1
--- /dev/null
+++ b/plugins/org.eclipse.etrice.ui.behavior/src/org/eclipse/etrice/ui/behavior/DiagramTypeProvider.java
@@ -0,0 +1,38 @@
+/*******************************************************************************
+ * Copyright (c) 2010 protos software gmbh (http://www.protos.de).
+ * 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:
+ * Thomas Schuetz and Henrik Rentz-Reichert (initial contribution)
+ *
+ *******************************************************************************/
+
+package org.eclipse.etrice.ui.behavior;
+
+import org.eclipse.graphiti.dt.AbstractDiagramTypeProvider;
+import org.eclipse.graphiti.tb.IToolBehaviorProvider;
+
+public class DiagramTypeProvider extends AbstractDiagramTypeProvider {
+
+ private IToolBehaviorProvider[] toolBehaviorProviders;
+ private ProviderDispatcher dispatcher;
+
+ public DiagramTypeProvider() {
+ super();
+ dispatcher = new ProviderDispatcher(this);
+ setFeatureProvider(dispatcher.getFeatureProvider());
+ }
+
+ @Override
+ public IToolBehaviorProvider[] getAvailableToolBehaviorProviders() {
+ if (toolBehaviorProviders == null) {
+ toolBehaviorProviders =
+ new IToolBehaviorProvider[] {
+ dispatcher.getToolBehaviorProvider() };
+ }
+ return toolBehaviorProviders;
+ }
+}
diff --git a/plugins/org.eclipse.etrice.ui.behavior/src/org/eclipse/etrice/ui/behavior/ImageProvider.java b/plugins/org.eclipse.etrice.ui.behavior/src/org/eclipse/etrice/ui/behavior/ImageProvider.java
new file mode 100644
index 000000000..5e360456c
--- /dev/null
+++ b/plugins/org.eclipse.etrice.ui.behavior/src/org/eclipse/etrice/ui/behavior/ImageProvider.java
@@ -0,0 +1,40 @@
+/*******************************************************************************
+ * Copyright (c) 2010 protos software gmbh (http://www.protos.de).
+ * 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:
+ * Thomas Schuetz and Henrik Rentz-Reichert (initial contribution)
+ *
+ *******************************************************************************/
+
+package org.eclipse.etrice.ui.behavior;
+
+import org.eclipse.graphiti.ui.platform.AbstractImageProvider;
+
+public class ImageProvider extends AbstractImageProvider {
+
+ // The prefix for all identifiers of this image provider
+ protected static final String PREFIX = "org.eclipse.etrice.ui.behavior.";
+
+ // The image identifier for an EReference.
+ public static final String IMG_STATE = PREFIX + "state";
+ public static final String IMG_TRPOINT = PREFIX + "trpoint";
+ public static final String IMG_ENTRYPOINT = PREFIX + "entrypoint";
+ public static final String IMG_EXITPOINT = PREFIX + "exitpoint";
+ public static final String IMG_CP = PREFIX + "cp";
+ public static final String IMG_TRANSITION = PREFIX + "transition";
+
+ @Override
+ protected void addAvailableImages() {
+ addImageFilePath(IMG_STATE, "icons/State.gif");
+ addImageFilePath(IMG_TRPOINT, "icons/TrPoint.gif");
+ addImageFilePath(IMG_ENTRYPOINT, "icons/EntryPoint.gif");
+ addImageFilePath(IMG_EXITPOINT, "icons/ExitPoint.gif");
+ addImageFilePath(IMG_CP, "icons/ChoicePoint.gif");
+ addImageFilePath(IMG_TRANSITION, "icons/Transition.gif");
+ }
+
+}
diff --git a/plugins/org.eclipse.etrice.ui.behavior/src/org/eclipse/etrice/ui/behavior/NoResizeFeature.java b/plugins/org.eclipse.etrice.ui.behavior/src/org/eclipse/etrice/ui/behavior/NoResizeFeature.java
new file mode 100644
index 000000000..af202fb87
--- /dev/null
+++ b/plugins/org.eclipse.etrice.ui.behavior/src/org/eclipse/etrice/ui/behavior/NoResizeFeature.java
@@ -0,0 +1,46 @@
+/*******************************************************************************
+ * Copyright (c) 2010 protos software gmbh (http://www.protos.de).
+ * 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:
+ * Thomas Schuetz and Henrik Rentz-Reichert (initial contribution)
+ *
+ *******************************************************************************/
+
+package org.eclipse.etrice.ui.behavior;
+
+import org.eclipse.graphiti.features.IFeatureProvider;
+import org.eclipse.graphiti.features.IResizeConfiguration;
+import org.eclipse.graphiti.features.context.IResizeShapeContext;
+import org.eclipse.graphiti.features.impl.DefaultResizeShapeFeature;
+
+public class NoResizeFeature extends DefaultResizeShapeFeature {
+
+ public NoResizeFeature(IFeatureProvider fp) {
+ super(fp);
+ }
+
+ @Override
+ public boolean canResizeShape(IResizeShapeContext context) {
+ return false;
+ }
+
+ @Override
+ public IResizeConfiguration getResizeConfiguration() {
+ return new IResizeConfiguration() {
+
+ @Override
+ public boolean isVerticalResizeAllowed() {
+ return false;
+ }
+
+ @Override
+ public boolean isHorizantalResizeAllowed() {
+ return false;
+ }
+ };
+ }
+}
diff --git a/plugins/org.eclipse.etrice.ui.behavior/src/org/eclipse/etrice/ui/behavior/ProviderDispatcher.java b/plugins/org.eclipse.etrice.ui.behavior/src/org/eclipse/etrice/ui/behavior/ProviderDispatcher.java
new file mode 100644
index 000000000..d9ee6b31d
--- /dev/null
+++ b/plugins/org.eclipse.etrice.ui.behavior/src/org/eclipse/etrice/ui/behavior/ProviderDispatcher.java
@@ -0,0 +1,400 @@
+/*******************************************************************************
+ * Copyright (c) 2010 protos software gmbh (http://www.protos.de).
+ * 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:
+ * Thomas Schuetz and Henrik Rentz-Reichert (initial contribution)
+ *
+ *******************************************************************************/
+
+package org.eclipse.etrice.ui.behavior;
+
+import java.util.Arrays;
+
+import org.eclipse.emf.ecore.EObject;
+import org.eclipse.etrice.core.naming.RoomFragmentProvider;
+import org.eclipse.graphiti.dt.IDiagramTypeProvider;
+import org.eclipse.graphiti.features.IAddFeature;
+import org.eclipse.graphiti.features.ICreateConnectionFeature;
+import org.eclipse.graphiti.features.ICreateFeature;
+import org.eclipse.graphiti.features.IDeleteFeature;
+import org.eclipse.graphiti.features.IFeatureProvider;
+import org.eclipse.graphiti.features.ILayoutFeature;
+import org.eclipse.graphiti.features.IMoveShapeFeature;
+import org.eclipse.graphiti.features.IRemoveFeature;
+import org.eclipse.graphiti.features.IResizeShapeFeature;
+import org.eclipse.graphiti.features.IUpdateFeature;
+import org.eclipse.graphiti.features.context.IAddContext;
+import org.eclipse.graphiti.features.context.ICustomContext;
+import org.eclipse.graphiti.features.context.IDeleteContext;
+import org.eclipse.graphiti.features.context.IDoubleClickContext;
+import org.eclipse.graphiti.features.context.ILayoutContext;
+import org.eclipse.graphiti.features.context.IMoveShapeContext;
+import org.eclipse.graphiti.features.context.IPictogramElementContext;
+import org.eclipse.graphiti.features.context.IRemoveContext;
+import org.eclipse.graphiti.features.context.IResizeShapeContext;
+import org.eclipse.graphiti.features.context.IUpdateContext;
+import org.eclipse.graphiti.features.custom.ICustomFeature;
+import org.eclipse.graphiti.mm.algorithms.GraphicsAlgorithm;
+import org.eclipse.graphiti.mm.algorithms.styles.LineStyle;
+import org.eclipse.graphiti.mm.pictograms.PictogramElement;
+import org.eclipse.graphiti.mm.pictograms.Shape;
+import org.eclipse.graphiti.tb.DefaultToolBehaviorProvider;
+import org.eclipse.graphiti.tb.IContextButtonPadData;
+import org.eclipse.graphiti.tb.ISelectionInfo;
+import org.eclipse.graphiti.tb.IToolBehaviorProvider;
+import org.eclipse.graphiti.tb.SelectionInfoImpl;
+import org.eclipse.graphiti.ui.features.DefaultFeatureProvider;
+import org.eclipse.graphiti.util.IColorConstant;
+
+import org.eclipse.etrice.core.room.ActorContainerRef;
+import org.eclipse.etrice.core.room.Binding;
+import org.eclipse.etrice.core.room.LayerConnection;
+import org.eclipse.etrice.core.room.Port;
+import org.eclipse.etrice.core.room.SPPRef;
+import org.eclipse.etrice.core.room.State;
+import org.eclipse.etrice.core.room.StateGraph;
+import org.eclipse.etrice.core.room.StructureClass;
+import org.eclipse.etrice.core.room.TrPoint;
+import org.eclipse.etrice.core.room.Transition;
+import org.eclipse.etrice.core.room.util.RoomSwitch;
+import org.eclipse.etrice.ui.behavior.support.StateGraphSupport;
+import org.eclipse.etrice.ui.behavior.support.StateSupport;
+import org.eclipse.etrice.ui.behavior.support.TrPointSupport;
+import org.eclipse.etrice.ui.behavior.support.TransitionSupport;
+
+public class ProviderDispatcher {
+
+ private class FeatureProviderSwitch extends RoomSwitch<IFeatureProvider> {
+ @Override
+ public IFeatureProvider doSwitch(EObject theEObject) {
+
+ if (theEObject==null)
+ return null;
+
+ if (theEObject.eIsProxy()) {
+ if (RoomFragmentProvider.isState(theEObject))
+ return stateGraphSupport.getFeatureProvider();
+ if (RoomFragmentProvider.isTrPoint(theEObject))
+ return trPointSupport.getFeatureProvider();
+ // TODOHRR-B cp
+// if (RoomFragmentProvider.isChoicePoint(theEObject))
+// return choicePointSupport.getFeatureProvider();
+ if (RoomFragmentProvider.isStateGraph(theEObject))
+ return stateGraphSupport.getFeatureProvider();
+ if (RoomFragmentProvider.isTransition(theEObject))
+ return transitionSupport.getFeatureProvider();
+ }
+ return super.doSwitch(theEObject);
+ }
+
+ @Override
+ public IFeatureProvider caseStateGraph(StateGraph object) {
+ return stateGraphSupport.getFeatureProvider();
+ }
+
+ @Override
+ public IFeatureProvider caseTrPoint(TrPoint object) {
+ return trPointSupport.getFeatureProvider();
+ }
+ @Override
+ public IFeatureProvider caseState(State object) {
+ return stateSupport.getFeatureProvider();
+ }
+
+ @Override
+ public IFeatureProvider caseTransition(Transition object) {
+ return transitionSupport.getFeatureProvider();
+ }
+
+ @Override
+ public IFeatureProvider defaultCase(EObject object) {
+ return null;
+ }
+
+ public ICreateFeature[] getCreateFeatures() {
+ return concatAll(
+ stateGraphSupport.getFeatureProvider().getCreateFeatures(),
+ trPointSupport.getFeatureProvider().getCreateFeatures(),
+ stateSupport.getFeatureProvider().getCreateFeatures()
+ );
+ }
+
+ public ICreateConnectionFeature[] getCreateConnectionFeatures() {
+ return transitionSupport.getFeatureProvider().getCreateConnectionFeatures();
+ }
+
+ public ICustomFeature[] getCustomFeatures(ICustomContext context) {
+ return concatAll(
+ trPointSupport.getFeatureProvider().getCustomFeatures(context),
+ stateSupport.getFeatureProvider().getCustomFeatures(context)
+ );
+ }
+ }
+
+ private class ToolBehaviorProviderSwitch extends RoomSwitch<IToolBehaviorProvider> {
+ @Override
+ public IToolBehaviorProvider doSwitch(EObject theEObject) {
+
+ if (theEObject==null)
+ return null;
+
+ if (theEObject.eIsProxy()) {
+ if (RoomFragmentProvider.isState(theEObject))
+ return stateGraphSupport.getToolBehaviorProvider();
+ if (RoomFragmentProvider.isTrPoint(theEObject))
+ return trPointSupport.getToolBehaviorProvider();
+ // TODOHRR-B cp
+// if (RoomFragmentProvider.isChoicePoint(theEObject))
+// return choicePointSupport.getToolBehaviorProvider();
+ if (RoomFragmentProvider.isStateGraph(theEObject))
+ return stateGraphSupport.getToolBehaviorProvider();
+ if (RoomFragmentProvider.isTransition(theEObject))
+ return transitionSupport.getToolBehaviorProvider();
+ }
+
+ return super.doSwitch(theEObject);
+ }
+
+ @Override
+ public IToolBehaviorProvider caseStateGraph(StateGraph object) {
+ return stateGraphSupport.getToolBehaviorProvider();
+ }
+
+ @Override
+ public IToolBehaviorProvider caseTrPoint(TrPoint object) {
+ return trPointSupport.getToolBehaviorProvider();
+ }
+
+ @Override
+ public IToolBehaviorProvider caseState(State object) {
+ return stateSupport.getToolBehaviorProvider();
+ }
+
+ @Override
+ public IToolBehaviorProvider caseTransition(Transition object) {
+ return transitionSupport.getToolBehaviorProvider();
+ }
+
+ @Override
+ public IToolBehaviorProvider defaultCase(EObject object) {
+ return null;
+ }
+
+ }
+
+ private class DispatchingFeatureProvider extends DefaultFeatureProvider {
+
+ public DispatchingFeatureProvider(IDiagramTypeProvider dtp) {
+ super(dtp);
+ }
+
+ @Override
+ public ICreateFeature[] getCreateFeatures() {
+ return getAllCreateFeatures();
+ }
+
+ @Override
+ public ICreateConnectionFeature[] getCreateConnectionFeatures() {
+ return getAllCreateConnectionFeatures();
+ }
+
+ @Override
+ public IAddFeature getAddFeature(IAddContext context) {
+ IFeatureProvider fp = featureSwitch.doSwitch(((EObject) context.getNewObject()));
+ if (fp==null)
+ return super.getAddFeature(context);
+ else
+ return fp.getAddFeature(context);
+ }
+
+ @Override
+ public ILayoutFeature getLayoutFeature(ILayoutContext context) {
+ IFeatureProvider fp = featureSwitch.doSwitch(getBusinessObject(context));
+ if (fp==null)
+ return super.getLayoutFeature(context);
+ else
+ return fp.getLayoutFeature(context);
+ }
+
+ @Override
+ public IMoveShapeFeature getMoveShapeFeature(IMoveShapeContext context) {
+ IFeatureProvider fp = featureSwitch.doSwitch(getBusinessObject(context));
+ if (fp==null)
+ return super.getMoveShapeFeature(context);
+ else
+ return fp.getMoveShapeFeature(context);
+ }
+
+ @Override
+ public IResizeShapeFeature getResizeShapeFeature(IResizeShapeContext context) {
+ IFeatureProvider fp = featureSwitch.doSwitch(getBusinessObject(context));
+ if (fp==null)
+ return super.getResizeShapeFeature(context);
+ else
+ return fp.getResizeShapeFeature(context);
+ }
+
+ @Override
+ public IUpdateFeature getUpdateFeature(IUpdateContext context) {
+ IFeatureProvider fp = featureSwitch.doSwitch(getBusinessObject(context));
+ if (fp!=null)
+ return fp.getUpdateFeature(context);
+ else
+ return super.getUpdateFeature(context);
+ }
+
+ @Override
+ public IDeleteFeature getDeleteFeature(IDeleteContext context) {
+ IFeatureProvider fp = featureSwitch.doSwitch(getBusinessObject(context));
+ if (fp!=null)
+ return fp.getDeleteFeature(context);
+ else
+ return super.getDeleteFeature(context);
+ }
+
+ @Override
+ public IRemoveFeature getRemoveFeature(IRemoveContext context) {
+ IFeatureProvider fp = featureSwitch.doSwitch(getBusinessObject(context));
+ if (fp!=null)
+ return fp.getRemoveFeature(context);
+ else
+ return super.getRemoveFeature(context);
+ }
+
+ @Override
+ public ICustomFeature[] getCustomFeatures(ICustomContext context) {
+ return getAllCustomFeatures(context);
+ }
+
+ private EObject getBusinessObject(IPictogramElementContext context) {
+ PictogramElement pictogramElement = context.getPictogramElement();
+ EObject bo = (EObject) getBusinessObjectForPictogramElement(pictogramElement);
+ return bo;
+ }
+ }
+
+ private class DispatchingToolBehaviorProvider extends DefaultToolBehaviorProvider {
+
+ public DispatchingToolBehaviorProvider(IDiagramTypeProvider diagramTypeProvider) {
+ super(diagramTypeProvider);
+ }
+
+ @Override
+ public GraphicsAlgorithm[] getClickArea(PictogramElement pe) {
+ IToolBehaviorProvider bp = getToolBehaviorProvider(pe);
+ if (bp==null)
+ return super.getClickArea(pe);
+ else
+ return bp.getClickArea(pe);
+ }
+
+ @Override
+ public GraphicsAlgorithm getSelectionBorder(PictogramElement pe) {
+ IToolBehaviorProvider bp = getToolBehaviorProvider(pe);
+ if (bp==null)
+ return super.getSelectionBorder(pe);
+ else
+ return bp.getSelectionBorder(pe);
+ }
+
+ @Override
+ public ICustomFeature getDoubleClickFeature(IDoubleClickContext context) {
+ IToolBehaviorProvider bp = getToolBehaviorProvider(context.getPictogramElements()[0]);
+ if (bp==null)
+ return super.getDoubleClickFeature(context);
+ else
+ return bp.getDoubleClickFeature(context);
+ }
+
+ protected IToolBehaviorProvider getToolBehaviorProvider(PictogramElement pe) {
+ IFeatureProvider fp = getFeatureProvider();
+ EObject bo = (EObject) fp.getBusinessObjectForPictogramElement(pe);
+ if (bo==null)
+ return null;
+
+ IToolBehaviorProvider bp = behaviorSwitch.doSwitch(bo);
+ return bp;
+ }
+
+ @Override
+ public IContextButtonPadData getContextButtonPad(IPictogramElementContext context) {
+ IToolBehaviorProvider bp = getToolBehaviorProvider(context.getPictogramElement());
+ if (bp==null)
+ return super.getContextButtonPad(context);
+ else
+ return bp.getContextButtonPad(context);
+ }
+
+ public ISelectionInfo getSelectionInfoForShape(Shape shape) {
+ ISelectionInfo si = new SelectionInfoImpl(IColorConstant.SHAPE_SELECTION_FG, IColorConstant.HANDLE_FG, IColorConstant.HANDLE_BG,
+ LineStyle.DASH);
+// si.setPrimarySelectionBackgroundColor(IColorConstant.LIGHT_GRAY);
+// si.setSecondarySelectionBackgroundColor(IColorConstant.LIGHT_GRAY);
+ return si;
+ }
+ }
+
+ private StateGraphSupport stateGraphSupport;
+ private TrPointSupport trPointSupport;
+ private StateSupport stateSupport;
+ private TransitionSupport transitionSupport;
+
+ private FeatureProviderSwitch featureSwitch;
+ private ToolBehaviorProviderSwitch behaviorSwitch;
+
+ private DispatchingFeatureProvider dispatchingFP;
+ private DispatchingToolBehaviorProvider dispatchingBP;
+
+
+ public ProviderDispatcher(IDiagramTypeProvider dtp) {
+ // create those first before using them
+ dispatchingFP = new DispatchingFeatureProvider(dtp);
+ dispatchingBP = new DispatchingToolBehaviorProvider(dtp);
+
+ stateGraphSupport = new StateGraphSupport(dtp, dispatchingFP);
+ trPointSupport = new TrPointSupport(dtp, dispatchingFP);
+ stateSupport = new StateSupport(dtp, dispatchingFP);
+ transitionSupport = new TransitionSupport(dtp, dispatchingFP);
+
+ featureSwitch = new FeatureProviderSwitch();
+ behaviorSwitch = new ToolBehaviorProviderSwitch();
+ }
+
+ public IFeatureProvider getFeatureProvider() {
+ return dispatchingFP;
+ }
+
+ public IToolBehaviorProvider getToolBehaviorProvider() {
+ return dispatchingBP;
+ }
+
+ private ICreateFeature[] getAllCreateFeatures() {
+ return featureSwitch.getCreateFeatures();
+ }
+
+ private ICreateConnectionFeature[] getAllCreateConnectionFeatures() {
+ return featureSwitch.getCreateConnectionFeatures();
+ }
+
+ private ICustomFeature[] getAllCustomFeatures(ICustomContext context) {
+ return featureSwitch.getCustomFeatures(context);
+ }
+
+ private static <T> T[] concatAll(T[] first, T[]... rest) {
+ int totalLength = first.length;
+ for (T[] array : rest) {
+ totalLength += array.length;
+ }
+ T[] result = Arrays.copyOf(first, totalLength);
+ int offset = first.length;
+ for (T[] array : rest) {
+ System.arraycopy(array, 0, result, offset, array.length);
+ offset += array.length;
+ }
+ return result;
+ }
+}
diff --git a/plugins/org.eclipse.etrice.ui.behavior/src/org/eclipse/etrice/ui/behavior/commands/PopulateDiagramCommand.java b/plugins/org.eclipse.etrice.ui.behavior/src/org/eclipse/etrice/ui/behavior/commands/PopulateDiagramCommand.java
new file mode 100644
index 000000000..6555b8bdc
--- /dev/null
+++ b/plugins/org.eclipse.etrice.ui.behavior/src/org/eclipse/etrice/ui/behavior/commands/PopulateDiagramCommand.java
@@ -0,0 +1,59 @@
+/*******************************************************************************
+ * Copyright (c) 2010 protos software gmbh (http://www.protos.de).
+ * 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:
+ * Thomas Schuetz and Henrik Rentz-Reichert (initial contribution)
+ *
+ *******************************************************************************/
+
+package org.eclipse.etrice.ui.behavior.commands;
+
+import org.eclipse.emf.transaction.RecordingCommand;
+import org.eclipse.emf.transaction.TransactionalEditingDomain;
+import org.eclipse.etrice.core.room.ActorClass;
+import org.eclipse.etrice.core.room.RoomFactory;
+import org.eclipse.etrice.ui.behavior.support.StateGraphSupport;
+import org.eclipse.graphiti.dt.IDiagramTypeProvider;
+import org.eclipse.graphiti.features.IAddFeature;
+import org.eclipse.graphiti.features.IFeatureProvider;
+import org.eclipse.graphiti.features.context.impl.AddContext;
+import org.eclipse.graphiti.mm.pictograms.ContainerShape;
+import org.eclipse.graphiti.mm.pictograms.Diagram;
+import org.eclipse.graphiti.ui.services.GraphitiUi;
+
+
+public class PopulateDiagramCommand extends RecordingCommand {
+
+ private ActorClass ac;
+ private Diagram diagram;
+
+ public PopulateDiagramCommand(Diagram diag, ActorClass ac, TransactionalEditingDomain domain) {
+ super(domain);
+ this.diagram = diag;
+ this.ac = ac;
+ }
+
+ @Override
+ protected void doExecute() {
+ IDiagramTypeProvider dtp = GraphitiUi.getExtensionManager().createDiagramTypeProvider(diagram, "org.eclipse.etrice.ui.behavior.diagramTypeProvider"); //$NON-NLS-1$
+ IFeatureProvider featureProvider = dtp.getFeatureProvider();
+
+ if (ac.getStateMachine()==null)
+ ac.setStateMachine(RoomFactory.eINSTANCE.createStateGraph());
+
+ AddContext addContext = new AddContext();
+ addContext.setNewObject(ac.getStateMachine());
+ addContext.setTargetContainer(diagram);
+ addContext.setX(StateGraphSupport.MARGIN);
+ addContext.setY(StateGraphSupport.MARGIN);
+
+ IAddFeature addFeature = featureProvider.getAddFeature(addContext);
+ if (addFeature!=null && addFeature.canAdd(addContext)) {
+ ContainerShape acShape = (ContainerShape) addFeature.add(addContext);
+ }
+ }
+}
diff --git a/plugins/org.eclipse.etrice.ui.behavior/src/org/eclipse/etrice/ui/behavior/editor/BehaviorEditor.java b/plugins/org.eclipse.etrice.ui.behavior/src/org/eclipse/etrice/ui/behavior/editor/BehaviorEditor.java
new file mode 100644
index 000000000..440e0b451
--- /dev/null
+++ b/plugins/org.eclipse.etrice.ui.behavior/src/org/eclipse/etrice/ui/behavior/editor/BehaviorEditor.java
@@ -0,0 +1,29 @@
+/*******************************************************************************
+ * Copyright (c) 2010 protos software gmbh (http://www.protos.de).
+ * 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
+ *******************************************************************************/
+
+package org.eclipse.etrice.ui.behavior.editor;
+
+import org.eclipse.etrice.ui.behavior.Activator;
+import org.eclipse.graphiti.ui.editor.DiagramEditor;
+import org.eclipse.swt.graphics.Image;
+
+
+public class BehaviorEditor extends DiagramEditor {
+
+ public static final String BEHAVIOR_EDITOR_ID = "org.eclipse.etrice.ui.behavior.editor.BehaviorEditor";
+
+ public BehaviorEditor() {
+ super();
+ }
+
+ @Override
+ public Image getDefaultImage() {
+ return Activator.getImage("icons/Behavior.gif");
+ }
+
+}
diff --git a/plugins/org.eclipse.etrice.ui.behavior/src/org/eclipse/etrice/ui/behavior/support/Constants.java b/plugins/org.eclipse.etrice.ui.behavior/src/org/eclipse/etrice/ui/behavior/support/Constants.java
new file mode 100644
index 000000000..e48fc40a2
--- /dev/null
+++ b/plugins/org.eclipse.etrice.ui.behavior/src/org/eclipse/etrice/ui/behavior/support/Constants.java
@@ -0,0 +1,24 @@
+/*******************************************************************************
+ * Copyright (c) 2010 protos software gmbh (http://www.protos.de).
+ * 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:
+ * Thomas Schuetz and Henrik Rentz-Reichert (initial contribution)
+ *
+ *******************************************************************************/
+
+package org.eclipse.etrice.ui.behavior.support;
+
+public interface Constants {
+
+ static final String TYPE_KEY = "obj-type";
+
+ static final String SG_TYPE = "sg";
+ static final String STATE_TYPE = "state";
+ static final String CP_TYPE = "cp";
+ static final String TRP_TYPE = "trp";
+ static final String TRANS_TYPE = "trans";
+}
diff --git a/plugins/org.eclipse.etrice.ui.behavior/src/org/eclipse/etrice/ui/behavior/support/StateGraphSupport.java b/plugins/org.eclipse.etrice.ui.behavior/src/org/eclipse/etrice/ui/behavior/support/StateGraphSupport.java
new file mode 100644
index 000000000..839f2e922
--- /dev/null
+++ b/plugins/org.eclipse.etrice.ui.behavior/src/org/eclipse/etrice/ui/behavior/support/StateGraphSupport.java
@@ -0,0 +1,381 @@
+/*******************************************************************************
+ * Copyright (c) 2010 protos software gmbh (http://www.protos.de).
+ * 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:
+ * Thomas Schuetz and Henrik Rentz-Reichert (initial contribution)
+ *
+ *******************************************************************************/
+
+package org.eclipse.etrice.ui.behavior.support;
+
+import org.eclipse.emf.common.util.EList;
+import org.eclipse.emf.ecore.EObject;
+import org.eclipse.emf.ecore.util.EcoreUtil;
+import org.eclipse.etrice.core.room.ActorClass;
+import org.eclipse.etrice.core.room.StateGraph;
+import org.eclipse.etrice.core.room.StructureClass;
+import org.eclipse.etrice.core.room.TrPoint;
+import org.eclipse.graphiti.dt.IDiagramTypeProvider;
+import org.eclipse.graphiti.features.IAddFeature;
+import org.eclipse.graphiti.features.IFeatureProvider;
+import org.eclipse.graphiti.features.ILayoutFeature;
+import org.eclipse.graphiti.features.IReason;
+import org.eclipse.graphiti.features.IRemoveFeature;
+import org.eclipse.graphiti.features.IResizeShapeFeature;
+import org.eclipse.graphiti.features.IUpdateFeature;
+import org.eclipse.graphiti.features.context.IAddContext;
+import org.eclipse.graphiti.features.context.ILayoutContext;
+import org.eclipse.graphiti.features.context.IRemoveContext;
+import org.eclipse.graphiti.features.context.IResizeShapeContext;
+import org.eclipse.graphiti.features.context.IUpdateContext;
+import org.eclipse.graphiti.features.context.impl.RemoveContext;
+import org.eclipse.graphiti.features.impl.AbstractAddFeature;
+import org.eclipse.graphiti.features.impl.AbstractLayoutFeature;
+import org.eclipse.graphiti.features.impl.AbstractUpdateFeature;
+import org.eclipse.graphiti.features.impl.DefaultResizeShapeFeature;
+import org.eclipse.graphiti.features.impl.Reason;
+import org.eclipse.graphiti.mm.algorithms.GraphicsAlgorithm;
+import org.eclipse.graphiti.mm.algorithms.Rectangle;
+import org.eclipse.graphiti.mm.algorithms.RoundedRectangle;
+import org.eclipse.graphiti.mm.pictograms.ContainerShape;
+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.services.IPeCreateService;
+import org.eclipse.graphiti.tb.DefaultToolBehaviorProvider;
+import org.eclipse.graphiti.tb.IToolBehaviorProvider;
+import org.eclipse.graphiti.ui.features.DefaultFeatureProvider;
+import org.eclipse.graphiti.util.ColorConstant;
+import org.eclipse.graphiti.util.IColorConstant;
+
+public class StateGraphSupport {
+
+ public static final int MARGIN = 20;
+
+ private static final int CORNER_SIZE = 20;
+ private static final int LINE_WIDTH = 4;
+ public static final int DEFAULT_SIZE_X = 800;
+ public static final int DEFAULT_SIZE_Y = 500;
+ private static final IColorConstant LINE_COLOR = new ColorConstant(0, 0, 0);
+ private static final IColorConstant BACKGROUND = new ColorConstant(255, 255, 255);
+
+ private class FeatureProvider extends DefaultFeatureProvider {
+
+ private class AddFeature extends AbstractAddFeature {
+
+ public AddFeature(IFeatureProvider fp) {
+ super(fp);
+ }
+
+ @Override
+ public boolean canAdd(IAddContext context) {
+ if (context.getNewObject() instanceof StateGraph) {
+ if (context.getTargetContainer() instanceof Diagram) {
+ return true;
+ }
+ }
+ return false;
+ }
+
+ @Override
+ public PictogramElement add(IAddContext context) {
+ StateGraph sg = (StateGraph) context.getNewObject();
+ ContainerShape targetContainer = (ContainerShape) context.getTargetContainer();
+
+ // CONTAINER SHAPE WITH RECTANGLE
+ IPeCreateService peCreateService = Graphiti.getPeCreateService();
+ ContainerShape containerShape =
+ peCreateService.createContainerShape(targetContainer, true);
+
+ Graphiti.getPeService().setPropertyValue(containerShape, Constants.TYPE_KEY, Constants.SG_TYPE);
+
+ // check whether the context has a size (e.g. from a create feature)
+ // otherwise define a default size for the shape
+ int width = context.getWidth() <= 0 ? DEFAULT_SIZE_X : context.getWidth();
+ int height = context.getHeight() <= 0 ? DEFAULT_SIZE_Y : context.getHeight();
+
+ {
+ IGaService gaService = Graphiti.getGaService();
+
+ // create invisible outer rectangle expanded by
+ // the width needed for the ports
+ Rectangle invisibleRectangle =
+ gaService.createInvisibleRectangle(containerShape);
+
+ gaService.setLocationAndSize(invisibleRectangle,
+ context.getX(), context.getY(), width + 2*MARGIN, height + 2*MARGIN);
+
+ // create and set visible rectangle inside invisible rectangle
+ RoundedRectangle rect = gaService.createRoundedRectangle(invisibleRectangle, CORNER_SIZE, CORNER_SIZE);
+ rect.setForeground(manageColor(LINE_COLOR));
+ rect.setBackground(manageColor(BACKGROUND));
+ rect.setLineWidth(LINE_WIDTH);
+ gaService.setLocationAndSize(rect, MARGIN, MARGIN, width, height);
+
+ // create link and wire it
+ link(containerShape, sg);
+
+ if (sg.eContainer() instanceof ActorClass) {
+ link(getDiagram(), sg.eContainer());
+ }
+ }
+
+ // call the layout feature
+ layoutPictogramElement(containerShape);
+
+ return containerShape;
+
+ }
+
+ }
+
+ private class LayoutFeature extends AbstractLayoutFeature {
+
+ private static final int MIN_HEIGHT = 100;
+ private static final int MIN_WIDTH = 250;
+
+ public LayoutFeature(IFeatureProvider fp) {
+ super(fp);
+ }
+
+ @Override
+ public boolean canLayout(ILayoutContext context) {
+ // return true, if pictogram element is linked to an ActorClass
+ PictogramElement pe = context.getPictogramElement();
+ if (!(pe instanceof ContainerShape))
+ return false;
+
+ EList<EObject> businessObjects = pe.getLink().getBusinessObjects();
+ return businessObjects.size() == 1
+ && businessObjects.get(0) instanceof StateGraph;
+ }
+
+ @Override
+ public boolean layout(ILayoutContext context) {
+ boolean anythingChanged = false;
+ ContainerShape containerShape = (ContainerShape) context
+ .getPictogramElement();
+
+ GraphicsAlgorithm containerGa = containerShape.getGraphicsAlgorithm();
+
+ // height
+ if (containerGa.getHeight() < MIN_HEIGHT) {
+ containerGa.setHeight(MIN_HEIGHT);
+ anythingChanged = true;
+ }
+
+ // width
+ if (containerGa.getWidth() < MIN_WIDTH) {
+ containerGa.setWidth(MIN_WIDTH);
+ anythingChanged = true;
+ }
+
+ int w = containerGa.getWidth();
+ int h = containerGa.getHeight();
+
+ if (containerGa.getGraphicsAlgorithmChildren().size()==1) {
+ GraphicsAlgorithm ga = containerGa.getGraphicsAlgorithmChildren().get(0);
+ ga.setWidth(w-2*MARGIN);
+ ga.setHeight(h-2*MARGIN);
+ anythingChanged = true;
+ }
+
+ return anythingChanged;
+ }
+
+ }
+
+ private class UpdateFeature extends AbstractUpdateFeature {
+
+ public UpdateFeature(IFeatureProvider fp) {
+ super(fp);
+ }
+
+ @Override
+ public boolean canUpdate(IUpdateContext context) {
+ Object bo = getBusinessObjectForPictogramElement(context.getPictogramElement());
+ if (bo instanceof EObject && ((EObject)bo).eIsProxy())
+ return true;
+
+ return bo instanceof StructureClass;
+ }
+
+ @Override
+ public IReason updateNeeded(IUpdateContext context) {
+ Object bo = getBusinessObjectForPictogramElement(context.getPictogramElement());
+ if (bo instanceof EObject && ((EObject)bo).eIsProxy()) {
+ return Reason.createTrueReason("State Graph deleted from model");
+ }
+
+ // TODOHRR: check for refs added in model not present in diagram
+ // also inherited
+
+ return Reason.createFalseReason();
+ }
+
+ @Override
+ public boolean update(IUpdateContext context) {
+ ContainerShape containerShape = (ContainerShape)context.getPictogramElement();
+ Object bo = getBusinessObjectForPictogramElement(containerShape);
+ if (bo instanceof EObject && ((EObject)bo).eIsProxy()) {
+ IRemoveContext rc = new RemoveContext(containerShape);
+ IFeatureProvider featureProvider = getFeatureProvider();
+ IRemoveFeature removeFeature = featureProvider.getRemoveFeature(rc);
+ if (removeFeature != null) {
+ removeFeature.remove(rc);
+ }
+ EcoreUtil.delete((EObject) bo);
+ return true;
+ }
+
+ // TODOHRR: check for refs added in model not present in diagram
+ // also add bindings and layer connections
+
+ return true;
+ }
+ }
+
+ private class ResizeFeature extends DefaultResizeShapeFeature {
+
+ public ResizeFeature(IFeatureProvider fp) {
+ super(fp);
+ }
+
+ @Override
+ public boolean canResizeShape(IResizeShapeContext context) {
+ if (!super.canResizeShape(context))
+ return false;
+
+ int width = context.getWidth()-MARGIN;
+ int height = context.getHeight()-MARGIN;
+ int xmax = 0;
+ int ymax = 0;
+ ContainerShape containerShape = (ContainerShape)context.getShape();
+ StateGraph sg = (StateGraph) getBusinessObjectForPictogramElement(containerShape);
+ for (Shape childShape : containerShape.getChildren()) {
+ if (isOnInterface(sg, getBusinessObjectForPictogramElement(childShape)))
+ continue;
+
+ GraphicsAlgorithm ga = childShape.getGraphicsAlgorithm();
+ int x = ga.getX()+ga.getWidth()-StateSupport.MARGIN;
+ int y = ga.getY()+ga.getHeight()-StateSupport.MARGIN;
+ if (x>xmax)
+ xmax = x;
+ if (y>ymax)
+ ymax = y;
+ }
+ if (width>0 && width<xmax)
+ return false;
+ if (height>0 && height<ymax)
+ return false;
+
+ return true;
+ }
+
+ @Override
+ public void resizeShape(IResizeShapeContext context) {
+ ContainerShape containerShape = (ContainerShape) context.getShape();
+ StateGraph sg = (StateGraph) getBusinessObjectForPictogramElement(containerShape);
+
+ if (containerShape.getGraphicsAlgorithm()!=null) {
+ GraphicsAlgorithm containerGa = containerShape.getGraphicsAlgorithm();
+ if (containerGa.getGraphicsAlgorithmChildren().size()==1) {
+ // scale interface item coordinates
+ // we refer to the visible rectangle which defines the border of our structure class
+ // since the margin is not scaled
+ GraphicsAlgorithm ga = containerGa.getGraphicsAlgorithmChildren().get(0);
+ double sx = (context.getWidth()-2*MARGIN)/(double)ga.getWidth();
+ double sy = (context.getHeight()-2*MARGIN)/(double)ga.getHeight();
+
+ for (Shape childShape : containerShape.getChildren()) {
+ if (isOnInterface(sg, getBusinessObjectForPictogramElement(childShape))) {
+ ga = childShape.getGraphicsAlgorithm();
+ ga.setX((int) (ga.getX()*sx));
+ ga.setY((int) (ga.getY()*sy));
+ }
+ }
+ }
+ }
+ super.resizeShape(context);
+ }
+
+ private boolean isOnInterface(StateGraph sg, Object childBo) {
+ return (childBo instanceof TrPoint);
+ }
+ }
+
+ private IFeatureProvider fp;
+
+ public FeatureProvider(IDiagramTypeProvider dtp, IFeatureProvider fp) {
+ super(dtp);
+ this.fp = fp;
+ }
+
+ @Override
+ public IAddFeature getAddFeature(IAddContext context) {
+ return new AddFeature(fp);
+ }
+
+ @Override
+ public ILayoutFeature getLayoutFeature(ILayoutContext context) {
+ return new LayoutFeature(fp);
+ }
+
+ @Override
+ public IUpdateFeature getUpdateFeature(IUpdateContext context) {
+ return new UpdateFeature(fp);
+ }
+
+ @Override
+ public IResizeShapeFeature getResizeShapeFeature(
+ IResizeShapeContext context) {
+ return new ResizeFeature(fp);
+ }
+ }
+
+ private class BehaviorProvider extends DefaultToolBehaviorProvider {
+
+ public BehaviorProvider(IDiagramTypeProvider dtp) {
+ super(dtp);
+ }
+
+ @Override
+ public GraphicsAlgorithm[] getClickArea(PictogramElement pe) {
+ GraphicsAlgorithm invisible = pe.getGraphicsAlgorithm();
+ GraphicsAlgorithm rectangle =
+ invisible.getGraphicsAlgorithmChildren().get(0);
+ return new GraphicsAlgorithm[] { rectangle };
+ }
+
+ @Override
+ public GraphicsAlgorithm getSelectionBorder(PictogramElement pe) {
+ GraphicsAlgorithm invisible = pe.getGraphicsAlgorithm();
+
+ GraphicsAlgorithm rectangle =
+ invisible.getGraphicsAlgorithmChildren().get(0);
+ return rectangle;
+ }
+ }
+
+ private FeatureProvider afp;
+ private BehaviorProvider tbp;
+
+ public StateGraphSupport(IDiagramTypeProvider dtp, IFeatureProvider fp) {
+ afp = new FeatureProvider(dtp, fp);
+ tbp = new BehaviorProvider(dtp);
+ }
+
+ public IFeatureProvider getFeatureProvider() {
+ return afp;
+ }
+
+ public IToolBehaviorProvider getToolBehaviorProvider() {
+ return tbp;
+ }
+}
diff --git a/plugins/org.eclipse.etrice.ui.behavior/src/org/eclipse/etrice/ui/behavior/support/StateSupport.java b/plugins/org.eclipse.etrice.ui.behavior/src/org/eclipse/etrice/ui/behavior/support/StateSupport.java
new file mode 100644
index 000000000..10b01b00d
--- /dev/null
+++ b/plugins/org.eclipse.etrice.ui.behavior/src/org/eclipse/etrice/ui/behavior/support/StateSupport.java
@@ -0,0 +1,730 @@
+/*******************************************************************************
+ * Copyright (c) 2010 protos software gmbh (http://www.protos.de).
+ * 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:
+ * Thomas Schuetz and Henrik Rentz-Reichert (initial contribution)
+ *
+ *******************************************************************************/
+
+package org.eclipse.etrice.ui.behavior.support;
+
+import java.util.ArrayList;
+import java.util.Collection;
+
+import org.eclipse.emf.common.util.EList;
+import org.eclipse.emf.ecore.EObject;
+import org.eclipse.emf.ecore.util.EcoreUtil;
+import org.eclipse.etrice.ui.behavior.DiagramAccess;
+import org.eclipse.etrice.ui.behavior.ImageProvider;
+import org.eclipse.graphiti.dt.IDiagramTypeProvider;
+import org.eclipse.graphiti.features.IAddFeature;
+import org.eclipse.graphiti.features.ICreateFeature;
+import org.eclipse.graphiti.features.IFeatureProvider;
+import org.eclipse.graphiti.features.ILayoutFeature;
+import org.eclipse.graphiti.features.IMoveShapeFeature;
+import org.eclipse.graphiti.features.IReason;
+import org.eclipse.graphiti.features.IRemoveFeature;
+import org.eclipse.graphiti.features.IResizeShapeFeature;
+import org.eclipse.graphiti.features.IUpdateFeature;
+import org.eclipse.graphiti.features.context.IAddContext;
+import org.eclipse.graphiti.features.context.ICreateContext;
+import org.eclipse.graphiti.features.context.ICustomContext;
+import org.eclipse.graphiti.features.context.IDoubleClickContext;
+import org.eclipse.graphiti.features.context.ILayoutContext;
+import org.eclipse.graphiti.features.context.IMoveShapeContext;
+import org.eclipse.graphiti.features.context.IRemoveContext;
+import org.eclipse.graphiti.features.context.IResizeShapeContext;
+import org.eclipse.graphiti.features.context.IUpdateContext;
+import org.eclipse.graphiti.features.context.impl.RemoveContext;
+import org.eclipse.graphiti.features.custom.AbstractCustomFeature;
+import org.eclipse.graphiti.features.custom.ICustomFeature;
+import org.eclipse.graphiti.features.impl.AbstractAddFeature;
+import org.eclipse.graphiti.features.impl.AbstractCreateFeature;
+import org.eclipse.graphiti.features.impl.AbstractLayoutFeature;
+import org.eclipse.graphiti.features.impl.AbstractUpdateFeature;
+import org.eclipse.graphiti.features.impl.DefaultMoveShapeFeature;
+import org.eclipse.graphiti.features.impl.DefaultResizeShapeFeature;
+import org.eclipse.graphiti.features.impl.Reason;
+import org.eclipse.graphiti.mm.algorithms.GraphicsAlgorithm;
+import org.eclipse.graphiti.mm.algorithms.Rectangle;
+import org.eclipse.graphiti.mm.algorithms.RoundedRectangle;
+import org.eclipse.graphiti.mm.algorithms.Text;
+import org.eclipse.graphiti.mm.algorithms.styles.Color;
+import org.eclipse.graphiti.mm.algorithms.styles.Orientation;
+import org.eclipse.graphiti.mm.pictograms.ChopboxAnchor;
+import org.eclipse.graphiti.mm.pictograms.ContainerShape;
+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.services.IPeCreateService;
+import org.eclipse.graphiti.tb.DefaultToolBehaviorProvider;
+import org.eclipse.graphiti.tb.IToolBehaviorProvider;
+import org.eclipse.graphiti.ui.features.AbstractDrillDownFeature;
+import org.eclipse.graphiti.ui.features.DefaultFeatureProvider;
+import org.eclipse.graphiti.util.ColorConstant;
+import org.eclipse.graphiti.util.IColorConstant;
+import org.eclipse.jface.window.Window;
+import org.eclipse.swt.widgets.Shell;
+import org.eclipse.ui.PlatformUI;
+
+import org.eclipse.etrice.core.room.ActorClass;
+import org.eclipse.etrice.core.room.ActorContainerClass;
+import org.eclipse.etrice.core.room.ActorContainerRef;
+import org.eclipse.etrice.core.room.ActorRef;
+import org.eclipse.etrice.core.room.BaseState;
+import org.eclipse.etrice.core.room.InterfaceItem;
+import org.eclipse.etrice.core.room.LogicalSystem;
+import org.eclipse.etrice.core.room.RefinedState;
+import org.eclipse.etrice.core.room.RoomFactory;
+import org.eclipse.etrice.core.room.State;
+import org.eclipse.etrice.core.room.StateGraph;
+import org.eclipse.etrice.core.room.StructureClass;
+import org.eclipse.etrice.core.room.SubSystemRef;
+import org.eclipse.etrice.core.room.TrPoint;
+
+public class StateSupport {
+
+ private static final int LINE_WIDTH = 1;
+ public static final int DEFAULT_SIZE_X = 60;
+ public static final int DEFAULT_SIZE_Y = 30;
+ public static final int MIN_SIZE_X = 60;
+ public static final int MIN_SIZE_Y = 30;
+ public static final int MARGIN = 20;
+ public static final int CORNER_WIDTH = 20;
+ public static final int HINT_CORNER_WIDTH = 10;
+
+ private static final IColorConstant LINE_COLOR = new ColorConstant(0, 0, 0);
+ private static final IColorConstant INHERITED_COLOR = new ColorConstant(100, 100, 100);
+ private static final IColorConstant BACKGROUND = new ColorConstant(200, 200, 200);
+
+ private static class FeatureProvider extends DefaultFeatureProvider {
+
+ private class CreateFeature extends AbstractCreateFeature {
+
+ public CreateFeature(IFeatureProvider fp) {
+ super(fp, "State", "create State");
+ }
+
+ @Override
+ public String getCreateImageId() {
+ return ImageProvider.IMG_STATE;
+ }
+
+ @Override
+ public boolean canCreate(ICreateContext context) {
+ if (context.getTargetContainer().getLink()!=null)
+ if (context.getTargetContainer().getLink().getBusinessObjects().size()==1) {
+ EObject obj = context.getTargetContainer().getLink().getBusinessObjects().get(0);
+ if (obj instanceof StateGraph) {
+ return true;
+ }
+ }
+ return false;
+ }
+
+ @Override
+ public Object[] create(ICreateContext context) {
+
+ StateGraph sg = (StateGraph) context.getTargetContainer().getLink().getBusinessObjects().get(0);
+
+ ActorClass ac = (ActorClass) getDiagram().getLink().getBusinessObjects().get(0);
+ boolean inherited = isInherited(sg, ac);
+
+ if (inherited) {
+ // we have to insert a refined state first
+ RefinedState rs = RoomFactory.eINSTANCE.createRefinedState();
+ rs.setBase((BaseState) sg.eContainer());
+ ac.getStateMachine().getStates().add(rs);
+
+ // now we change the context
+ sg = RoomFactory.eINSTANCE.createStateGraph();
+ rs.setSubgraph(sg);
+ link(context.getTargetContainer(), sg);
+ }
+
+ // create new State
+ BaseState s = RoomFactory.eINSTANCE.createBaseState();
+ s.setName("state");
+
+ // TODOHRR-B StatePropertyDialog
+// Shell shell = PlatformUI.getWorkbench().getActiveWorkbenchWindow().getShell();
+// StatePropertyDialog dlg = new StatePropertyDialog(shell, s, sc, true);
+// if (dlg.open()!=Window.OK)
+// // find a method to abort creation
+// //throw new RuntimeException();
+// return EMPTY;
+
+ sg.getStates().add(s);
+
+ addGraphicalRepresentation(context, s);
+
+ // return newly created business object(s)
+ return new Object[] { s };
+ }
+ }
+
+ private class AddFeature extends AbstractAddFeature {
+
+ public AddFeature(IFeatureProvider fp) {
+ super(fp);
+ }
+
+ @Override
+ public boolean canAdd(IAddContext context) {
+ if (context.getNewObject() instanceof State) {
+ if (context.getTargetContainer().getLink().getBusinessObjects().size()==1) {
+ EObject obj = context.getTargetContainer().getLink().getBusinessObjects().get(0);
+ if (obj instanceof StateGraph) {
+ return true;
+ }
+ }
+ }
+ return false;
+ }
+
+ @Override
+ public PictogramElement add(IAddContext context) {
+ State s = (State) context.getNewObject();
+ ContainerShape acShape = context.getTargetContainer();
+
+ // CONTAINER SHAPE WITH RECTANGLE
+ IPeCreateService peCreateService = Graphiti.getPeCreateService();
+ ContainerShape containerShape =
+ peCreateService.createContainerShape(acShape, true);
+
+ Graphiti.getPeService().setPropertyValue(containerShape, Constants.TYPE_KEY, Constants.STATE_TYPE);
+
+ int width = context.getWidth() <= 0 ? DEFAULT_SIZE_X : context.getWidth();
+ int height = context.getHeight() <= 0 ? DEFAULT_SIZE_Y : context.getHeight();
+
+ ActorClass ac = (ActorClass) getDiagram().getLink().getBusinessObjects().get(0);
+ boolean inherited = isInherited(s, ac);
+ Color lineColor = manageColor(inherited?INHERITED_COLOR:LINE_COLOR);
+ IGaService gaService = Graphiti.getGaService();
+ {
+ final Rectangle invisibleRectangle = gaService.createInvisibleRectangle(containerShape);
+ gaService.setLocationAndSize(invisibleRectangle,
+ context.getX(), context.getY(), width + 2*MARGIN, height + 2*MARGIN);
+
+ RoundedRectangle rect = gaService.createRoundedRectangle(invisibleRectangle, CORNER_WIDTH, CORNER_WIDTH);
+ rect.setForeground(lineColor);
+ rect.setBackground(manageColor(BACKGROUND));
+ rect.setLineWidth(LINE_WIDTH);
+ gaService.setLocationAndSize(rect, MARGIN, MARGIN, width, height);
+
+ addSubStructureHint(s, rect, lineColor);
+
+ // anchor for direct transitions to this state
+ ChopboxAnchor anchor = peCreateService.createChopboxAnchor(containerShape);
+ anchor.setReferencedGraphicsAlgorithm(rect);
+
+ // create link and wire it
+ link(containerShape, s);
+
+ // TODOHRR-B create TrPoints of State
+// if (inherited) {
+// TrPointSupport.createInheritedRefItems(s, containerShape, fp);
+// }
+// else {
+// TrPointSupport.createRefItems(s, containerShape, fp);
+// }
+ }
+
+ {
+ Shape labelShape = peCreateService.createShape(containerShape, false);
+ Text label = gaService.createDefaultText(labelShape, s.getName());
+ label.setForeground(lineColor);
+ label.setBackground(lineColor);
+ label.setHorizontalAlignment(Orientation.ALIGNMENT_CENTER);
+ label.setVerticalAlignment(Orientation.ALIGNMENT_CENTER);
+ gaService.setLocationAndSize(label, MARGIN, MARGIN, width, height);
+ }
+
+ // call the layout feature
+ layoutPictogramElement(containerShape);
+
+ return containerShape;
+ }
+
+ }
+
+ private class LayoutFeature extends AbstractLayoutFeature {
+
+ public LayoutFeature(IFeatureProvider fp) {
+ super(fp);
+ }
+
+ @Override
+ public boolean canLayout(ILayoutContext context) {
+ // return true, if pictogram element is linked to a State
+ PictogramElement pe = context.getPictogramElement();
+ if (!(pe instanceof ContainerShape))
+ return false;
+
+ EList<EObject> businessObjects = pe.getLink().getBusinessObjects();
+ return businessObjects.size() == 1
+ && businessObjects.get(0) instanceof State;
+ }
+
+ @Override
+ public boolean layout(ILayoutContext context) {
+ boolean anythingChanged = false;
+ ContainerShape containerShape = (ContainerShape) context
+ .getPictogramElement();
+
+ // our invisible rectangle
+ GraphicsAlgorithm containerGa = containerShape.getGraphicsAlgorithm();
+
+ int w = containerGa.getWidth();
+ int h = containerGa.getHeight();
+
+ if (containerGa.getGraphicsAlgorithmChildren().size()==1) {
+ // the visible outer frame
+ GraphicsAlgorithm ga = containerGa.getGraphicsAlgorithmChildren().get(0);
+
+ int nw = w-2*MARGIN;
+ int nh = h-2*MARGIN;
+
+ ga.setWidth(nw);
+ ga.setHeight(nh);
+
+ Object bo = getBusinessObjectForPictogramElement(containerShape);
+ if (bo instanceof State) {
+ State s = (State) bo;
+ ga.getGraphicsAlgorithmChildren().clear();
+ ActorClass ac = (ActorClass) getDiagram().getLink().getBusinessObjects().get(0);
+ Color lineColor = manageColor(isInherited(s, ac)?INHERITED_COLOR:LINE_COLOR);
+ addSubStructureHint(s, (RoundedRectangle) ga, lineColor);
+ }
+
+ int last = containerShape.getChildren().size()-1;
+ if (last>=0) {
+ GraphicsAlgorithm childGA = containerShape.getChildren().get(last).getGraphicsAlgorithm();
+ childGA.setWidth(nw);
+ childGA.setHeight(nh);
+ }
+
+ anythingChanged = true;
+ }
+
+ return anythingChanged;
+ }
+ }
+
+ private static class PropertyFeature extends AbstractCustomFeature {
+
+ public PropertyFeature(IFeatureProvider fp) {
+ super(fp);
+ }
+
+ @Override
+ public String getName() {
+ return "Edit State...";
+ }
+
+ @Override
+ public String getDescription() {
+ return "Edit State Properties";
+ }
+
+ @Override
+ public boolean canExecute(ICustomContext context) {
+ PictogramElement[] pes = context.getPictogramElements();
+ if (pes != null && pes.length == 1) {
+ Object bo = getBusinessObjectForPictogramElement(pes[0]);
+ if (bo instanceof State) {
+ return true;
+ }
+ }
+ return false;
+ }
+
+ @Override
+ public void execute(ICustomContext context) {
+ State s = (State) getBusinessObjectForPictogramElement(context.getPictogramElements()[0]);
+ Shell shell = PlatformUI.getWorkbench().getActiveWorkbenchWindow().getShell();
+ StructureClass sc = (StructureClass)s.eContainer();
+
+ // TODOHRR-B StatePropertyDialog
+// StatePropertyDialog dlg = new StatePropertyDialog(shell, s, sc, false);
+// if (dlg.open()!=Window.OK)
+// // TODOHRR: introduce a method to revert changes
+// throw new RuntimeException();
+
+ updateFigure(s, context);
+ }
+
+ private void updateFigure(State s, ICustomContext context) {
+ PictogramElement pe = context.getPictogramElements()[0];
+ ContainerShape container = (ContainerShape)pe;
+
+ // we clear the figure and rebuild it
+// GraphicsAlgorithm invisibleRect = pe.getGraphicsAlgorithm();
+// invisibleRect.getGraphicsAlgorithmChildren().clear();
+
+// createPortFigure(acr, false, container, invisibleRect, manageColor(DARK_COLOR), manageColor(BRIGHT_COLOR));
+
+ GraphicsAlgorithm ga = container.getChildren().get(1).getGraphicsAlgorithm();
+ if (ga instanceof Text) {
+ ((Text)ga).setValue(s.getName());
+ }
+
+ }
+
+ }
+
+ private static class DrillDownFeature extends AbstractCustomFeature {
+
+ public DrillDownFeature(IFeatureProvider fp) {
+ super(fp);
+ }
+
+ @Override
+ public String getName() {
+ return "Open associated diagram";
+ }
+
+ @Override
+ public boolean canExecute(ICustomContext context) {
+ PictogramElement[] pes = context.getPictogramElements();
+ if (pes != null && pes.length == 1) {
+ Object bo = getBusinessObjectForPictogramElement(pes[0]);
+ if (bo instanceof State) {
+ return true;
+ }
+ }
+ return false;
+ }
+
+ @Override
+ public void execute(ICustomContext context) {
+ // TODOHRR-B implement state context switch
+ }
+ }
+
+ private class UpdateFeature extends AbstractUpdateFeature {
+
+ public UpdateFeature(IFeatureProvider fp) {
+ super(fp);
+ }
+
+ @Override
+ public boolean canUpdate(IUpdateContext context) {
+ Object bo = getBusinessObjectForPictogramElement(context.getPictogramElement());
+ if (bo instanceof EObject && ((EObject)bo).eIsProxy())
+ return true;
+
+ return bo instanceof State;
+ }
+
+ @Override
+ public IReason updateNeeded(IUpdateContext context) {
+ Object bo = getBusinessObjectForPictogramElement(context.getPictogramElement());
+ if (bo instanceof EObject && ((EObject)bo).eIsProxy()) {
+ return Reason.createTrueReason("State deleted from model");
+ }
+ State s = (State) bo;
+
+ // check if ref still owned/inherited anymore
+ ContainerShape containerShape = (ContainerShape)context.getPictogramElement();
+ bo = getBusinessObjectForPictogramElement(containerShape);
+ if (bo instanceof ActorClass) {
+ ActorClass ac = (ActorClass) bo;
+ boolean found = false;
+ do {
+ if (ac==s.eContainer())
+ found = true;
+ ac = ac.getBase();
+ }
+ while (!found && ac!=null);
+
+ if (!found)
+ return Reason.createTrueReason("Ref not inherited anymore");
+ }
+
+ // check sub structure hint
+ {
+ boolean hasSubStruct = hasSubStructure(s);
+ GraphicsAlgorithm invisibleRect = containerShape.getGraphicsAlgorithm();
+ if (!invisibleRect.getGraphicsAlgorithmChildren().isEmpty()) {
+
+ GraphicsAlgorithm borderRect = invisibleRect.getGraphicsAlgorithmChildren().get(0);
+ if (hasSubStruct && borderRect.getGraphicsAlgorithmChildren().isEmpty())
+ return Reason.createTrueReason("Ref has sub structure now");
+ if (!hasSubStruct && !borderRect.getGraphicsAlgorithmChildren().isEmpty())
+ return Reason.createTrueReason("Ref has no sub structure anymore");
+ }
+ }
+
+ // check class name
+ int last = containerShape.getChildren().size()-1;
+ if (last>=0) {
+ GraphicsAlgorithm ga = containerShape.getChildren().get(last).getGraphicsAlgorithm();
+ if (ga instanceof Text) {
+ if (bo instanceof ActorContainerRef) {
+ String label = getLabel((ActorContainerRef) bo);
+ if (!((Text)ga).getValue().equals(label))
+ return Reason.createTrueReason("Class name is out of date");
+ }
+ }
+ }
+
+ // TODOHRR: check interface ports and spps added to model not present in diagram
+
+ return Reason.createFalseReason();
+ }
+
+ @Override
+ public boolean update(IUpdateContext context) {
+ ContainerShape containerShape = (ContainerShape)context.getPictogramElement();
+ Object bo = getBusinessObjectForPictogramElement(containerShape);
+ if (bo instanceof EObject && ((EObject)bo).eIsProxy()) {
+ IRemoveContext rc = new RemoveContext(containerShape);
+ IFeatureProvider featureProvider = getFeatureProvider();
+ IRemoveFeature removeFeature = featureProvider.getRemoveFeature(rc);
+ if (removeFeature != null) {
+ removeFeature.remove(rc);
+ }
+ EcoreUtil.delete((EObject) bo);
+ return true;
+ }
+
+ State s = (State) bo;
+ {
+ boolean hasSubStruct = hasSubStructure(s);
+ if (hasSubStruct && containerShape.getGraphicsAlgorithm().getGraphicsAlgorithmChildren().isEmpty()) {
+ ActorClass ac = (ActorClass) getDiagram().getLink().getBusinessObjects().get(0);
+ Color lineColor = manageColor(isInherited(s, ac)?INHERITED_COLOR:LINE_COLOR);
+ addSubStructureHint(s, (RoundedRectangle) containerShape.getGraphicsAlgorithm(), lineColor);
+ }
+ else if (!hasSubStruct && !containerShape.getGraphicsAlgorithm().getGraphicsAlgorithmChildren().isEmpty())
+ containerShape.getGraphicsAlgorithm().getGraphicsAlgorithmChildren().clear();
+ }
+
+ int last = containerShape.getChildren().size()-1;
+ if (last>=0) {
+ GraphicsAlgorithm ga = containerShape.getChildren().get(last).getGraphicsAlgorithm();
+ if (ga instanceof Text) {
+ ((Text)ga).setValue(s.getName());
+ }
+ }
+
+ return true;
+ }
+ }
+
+ private class MoveShapeFeature extends DefaultMoveShapeFeature {
+
+ public MoveShapeFeature(IFeatureProvider fp) {
+ super(fp);
+ }
+
+ @Override
+ public boolean canMoveShape(IMoveShapeContext context) {
+ boolean canMove = super.canMoveShape(context);
+
+ if (canMove) {
+ Object bo = getBusinessObjectForPictogramElement(context.getPictogramElement());
+
+ if (bo instanceof State) {
+ State s = (State) bo;
+ ContainerShape acShape = context.getTargetContainer();
+ ActorClass ac = (ActorClass) getDiagram().getLink().getBusinessObjects().get(0);
+
+ // TODOHRR: also check coordinates (no overlap with state graph boundaries)
+
+ return !isInherited(s, ac);
+ }
+ }
+
+ return canMove;
+ }
+ }
+
+ private class ResizeFeature extends DefaultResizeShapeFeature {
+
+ public ResizeFeature(IFeatureProvider fp) {
+ super(fp);
+ }
+
+ @Override
+ public boolean canResizeShape(IResizeShapeContext context) {
+ if (!super.canResizeShape(context))
+ return false;
+
+ int width = context.getWidth()-MARGIN;
+ int height = context.getHeight()-MARGIN;
+ if (width>0 && height>0)
+ if (width < MIN_SIZE_X+MARGIN || height < MIN_SIZE_Y+MARGIN)
+ return false;
+
+ return true;
+ }
+
+ @Override
+ public void resizeShape(IResizeShapeContext context) {
+ Shape shape = context.getShape();
+
+ if (shape.getGraphicsAlgorithm()!=null) {
+ GraphicsAlgorithm containerGa = shape.getGraphicsAlgorithm();
+ if (containerGa.getGraphicsAlgorithmChildren().size()==1) {
+ // scale interface item coordinates
+ // we refer to the visible rectangle which defines the border of our structure class
+ // since the margin is not scaled
+ GraphicsAlgorithm ga = containerGa.getGraphicsAlgorithmChildren().get(0);
+ double sx = (context.getWidth()-2*MARGIN)/(double)ga.getWidth();
+ double sy = (context.getHeight()-2*MARGIN)/(double)ga.getHeight();
+
+ for (Shape childShape : ((ContainerShape)context.getShape()).getChildren()) {
+ Object childBo = getBusinessObjectForPictogramElement(childShape);
+ if (childBo instanceof TrPoint) {
+ ga = childShape.getGraphicsAlgorithm();
+ ga.setX((int) (ga.getX()*sx));
+ ga.setY((int) (ga.getY()*sy));
+ }
+
+ }
+ }
+ }
+ super.resizeShape(context);
+ }
+ }
+
+ private IFeatureProvider fp;
+
+ public FeatureProvider(IDiagramTypeProvider dtp, IFeatureProvider fp) {
+ super(dtp);
+ this.fp = fp;
+ }
+
+ @Override
+ public ICreateFeature[] getCreateFeatures() {
+ return new ICreateFeature[] { new CreateFeature(fp) };
+ }
+
+ @Override
+ public IAddFeature getAddFeature(IAddContext context) {
+ return new AddFeature(fp);
+ }
+
+ @Override
+ public ILayoutFeature getLayoutFeature(ILayoutContext context) {
+ return new LayoutFeature(fp);
+ }
+
+ @Override
+ public IUpdateFeature getUpdateFeature(IUpdateContext context) {
+ return new UpdateFeature(fp);
+ }
+
+ @Override
+ public IMoveShapeFeature getMoveShapeFeature(IMoveShapeContext context) {
+ return new MoveShapeFeature(fp);
+ }
+
+ @Override
+ public IResizeShapeFeature getResizeShapeFeature(
+ IResizeShapeContext context) {
+ return new ResizeFeature(fp);
+ }
+
+ @Override
+ public ICustomFeature[] getCustomFeatures(ICustomContext context) {
+ return new ICustomFeature[] { new PropertyFeature(fp) };
+ }
+
+ protected static String getLabel(ActorContainerRef acr) {
+ String className = "<unknown>";
+ if (acr instanceof ActorRef) {
+ if (((ActorRef)acr).getType()!=null)
+ className = ((ActorRef)acr).getType().getName();
+ }
+ else if (acr instanceof SubSystemRef) {
+ if (((SubSystemRef)acr).getType()!=null)
+ className = ((SubSystemRef)acr).getType().getName();
+ }
+ return acr.getName()+"\n("+className+")";
+ }
+
+ protected static boolean isInherited(EObject obj, ActorClass parent) {
+ while (obj!=null) {
+ if (obj instanceof ActorClass)
+ return obj!=parent;
+
+ obj = obj.eContainer();
+ }
+ assert(false): "no parent actor class found";
+ return false;
+ }
+
+ private static boolean hasSubStructure(State acr) {
+ return (acr.getSubgraph()!=null);
+ }
+
+ private static void addSubStructureHint(State s,
+ RoundedRectangle rect, Color lineColor) {
+
+ if (hasSubStructure(s)) {
+ int x = rect.getWidth()-30;
+ int y = 20;
+ IGaService gaService = Graphiti.getGaService();
+ RoundedRectangle hint1 = gaService.createRoundedRectangle(rect, HINT_CORNER_WIDTH, HINT_CORNER_WIDTH);
+ hint1.setForeground(lineColor);
+ hint1.setFilled(false);
+ hint1.setLineWidth(LINE_WIDTH);
+ gaService.setLocationAndSize(hint1, x, y, 20, 10);
+ }
+ }
+ }
+
+ private class BehaviorProvider extends DefaultToolBehaviorProvider {
+
+ public BehaviorProvider(IDiagramTypeProvider dtp) {
+ super(dtp);
+ }
+
+ @Override
+ public GraphicsAlgorithm[] getClickArea(PictogramElement pe) {
+ GraphicsAlgorithm invisible = pe.getGraphicsAlgorithm();
+ GraphicsAlgorithm rectangle =
+ invisible.getGraphicsAlgorithmChildren().get(0);
+ return new GraphicsAlgorithm[] { rectangle };
+ }
+
+ @Override
+ public GraphicsAlgorithm getSelectionBorder(PictogramElement pe) {
+ GraphicsAlgorithm invisible = pe.getGraphicsAlgorithm();
+
+ GraphicsAlgorithm rectangle =
+ invisible.getGraphicsAlgorithmChildren().get(0);
+ return rectangle;
+ }
+
+ @Override
+ public ICustomFeature getDoubleClickFeature(IDoubleClickContext context) {
+ return new FeatureProvider.DrillDownFeature(getDiagramTypeProvider().getFeatureProvider());
+ }
+ }
+
+ private FeatureProvider pfp;
+ private BehaviorProvider tbp;
+
+ public StateSupport(IDiagramTypeProvider dtp, IFeatureProvider fp) {
+ pfp = new FeatureProvider(dtp,fp);
+ tbp = new BehaviorProvider(dtp);
+ }
+
+ public IFeatureProvider getFeatureProvider() {
+ return pfp;
+ }
+
+ public IToolBehaviorProvider getToolBehaviorProvider() {
+ return tbp;
+ }
+}
diff --git a/plugins/org.eclipse.etrice.ui.behavior/src/org/eclipse/etrice/ui/behavior/support/TrPointSupport.java b/plugins/org.eclipse.etrice.ui.behavior/src/org/eclipse/etrice/ui/behavior/support/TrPointSupport.java
new file mode 100644
index 000000000..9fa5fd403
--- /dev/null
+++ b/plugins/org.eclipse.etrice.ui.behavior/src/org/eclipse/etrice/ui/behavior/support/TrPointSupport.java
@@ -0,0 +1,807 @@
+/*******************************************************************************
+ * Copyright (c) 2010 protos software gmbh (http://www.protos.de).
+ * 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:
+ * Thomas Schuetz and Henrik Rentz-Reichert (initial contribution)
+ *
+ *******************************************************************************/
+
+package org.eclipse.etrice.ui.behavior.support;
+
+import org.eclipse.emf.ecore.EObject;
+import org.eclipse.emf.ecore.util.EcoreUtil;
+import org.eclipse.etrice.core.room.ActorClass;
+import org.eclipse.etrice.core.room.ActorContainerClass;
+import org.eclipse.etrice.core.room.ActorContainerRef;
+import org.eclipse.etrice.core.room.EntryPoint;
+import org.eclipse.etrice.core.room.ExitPoint;
+import org.eclipse.etrice.core.room.InterfaceItem;
+import org.eclipse.etrice.core.room.Port;
+import org.eclipse.etrice.core.room.RoomFactory;
+import org.eclipse.etrice.core.room.SPPRef;
+import org.eclipse.etrice.core.room.State;
+import org.eclipse.etrice.core.room.StateGraph;
+import org.eclipse.etrice.core.room.TrPoint;
+import org.eclipse.etrice.core.room.TransitionPoint;
+import org.eclipse.etrice.ui.behavior.ImageProvider;
+import org.eclipse.etrice.ui.behavior.NoResizeFeature;
+import org.eclipse.graphiti.dt.IDiagramTypeProvider;
+import org.eclipse.graphiti.features.IAddFeature;
+import org.eclipse.graphiti.features.ICreateConnectionFeature;
+import org.eclipse.graphiti.features.ICreateFeature;
+import org.eclipse.graphiti.features.IDeleteFeature;
+import org.eclipse.graphiti.features.IFeatureProvider;
+import org.eclipse.graphiti.features.IMoveShapeFeature;
+import org.eclipse.graphiti.features.IReason;
+import org.eclipse.graphiti.features.IRemoveFeature;
+import org.eclipse.graphiti.features.IResizeShapeFeature;
+import org.eclipse.graphiti.features.IUpdateFeature;
+import org.eclipse.graphiti.features.context.IAddContext;
+import org.eclipse.graphiti.features.context.ICreateContext;
+import org.eclipse.graphiti.features.context.ICustomContext;
+import org.eclipse.graphiti.features.context.IDeleteContext;
+import org.eclipse.graphiti.features.context.IDoubleClickContext;
+import org.eclipse.graphiti.features.context.ILocationContext;
+import org.eclipse.graphiti.features.context.IMoveShapeContext;
+import org.eclipse.graphiti.features.context.IPictogramElementContext;
+import org.eclipse.graphiti.features.context.IRemoveContext;
+import org.eclipse.graphiti.features.context.IResizeShapeContext;
+import org.eclipse.graphiti.features.context.ITargetContext;
+import org.eclipse.graphiti.features.context.IUpdateContext;
+import org.eclipse.graphiti.features.context.impl.CreateConnectionContext;
+import org.eclipse.graphiti.features.context.impl.RemoveContext;
+import org.eclipse.graphiti.features.custom.AbstractCustomFeature;
+import org.eclipse.graphiti.features.custom.ICustomFeature;
+import org.eclipse.graphiti.features.impl.AbstractAddFeature;
+import org.eclipse.graphiti.features.impl.AbstractCreateFeature;
+import org.eclipse.graphiti.features.impl.AbstractUpdateFeature;
+import org.eclipse.graphiti.features.impl.DefaultMoveShapeFeature;
+import org.eclipse.graphiti.features.impl.DefaultRemoveFeature;
+import org.eclipse.graphiti.features.impl.Reason;
+import org.eclipse.graphiti.mm.algorithms.Ellipse;
+import org.eclipse.graphiti.mm.algorithms.GraphicsAlgorithm;
+import org.eclipse.graphiti.mm.algorithms.Polygon;
+import org.eclipse.graphiti.mm.algorithms.Polyline;
+import org.eclipse.graphiti.mm.algorithms.Rectangle;
+import org.eclipse.graphiti.mm.algorithms.Text;
+import org.eclipse.graphiti.mm.algorithms.styles.Color;
+import org.eclipse.graphiti.mm.algorithms.styles.Orientation;
+import org.eclipse.graphiti.mm.pictograms.Anchor;
+import org.eclipse.graphiti.mm.pictograms.AnchorContainer;
+import org.eclipse.graphiti.mm.pictograms.ChopboxAnchor;
+import org.eclipse.graphiti.mm.pictograms.ContainerShape;
+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.services.IPeCreateService;
+import org.eclipse.graphiti.tb.ContextButtonEntry;
+import org.eclipse.graphiti.tb.DefaultToolBehaviorProvider;
+import org.eclipse.graphiti.tb.IContextButtonPadData;
+import org.eclipse.graphiti.tb.IToolBehaviorProvider;
+import org.eclipse.graphiti.ui.features.DefaultDeleteFeature;
+import org.eclipse.graphiti.ui.features.DefaultFeatureProvider;
+import org.eclipse.graphiti.util.ColorConstant;
+import org.eclipse.graphiti.util.IColorConstant;
+
+public class TrPointSupport {
+
+ public static final int ITEM_SIZE = StateGraphSupport.MARGIN;
+ public static final int ITEM_SIZE_SMALL = StateSupport.MARGIN;
+
+ protected static final int LINE_WIDTH = 2;
+ protected static final IColorConstant DARK_COLOR = new ColorConstant(0, 0, 0);
+ protected static final IColorConstant INHERITED_COLOR = new ColorConstant(100, 100, 100);
+ protected static final IColorConstant BRIGHT_COLOR = new ColorConstant(255, 255, 255);
+ protected static final String PROP_KIND = "item-kind";
+
+ enum Type { TRANS_POINT, ENTRY_POINT, EXIT_POINT }
+
+ private static class FeatureProvider extends DefaultFeatureProvider {
+
+ private static class CreateFeature extends AbstractCreateFeature {
+
+ private boolean doneChanges = false;
+
+ protected Type type;
+
+ public CreateFeature(IFeatureProvider fp, Type type, String name, String description) {
+ super(fp, name, description);
+ this.type = type;
+ }
+
+ @Override
+ public String getCreateImageId() {
+ switch (type) {
+ case ENTRY_POINT:
+ return ImageProvider.IMG_ENTRYPOINT;
+ case EXIT_POINT:
+ return ImageProvider.IMG_EXITPOINT;
+ case TRANS_POINT:
+ return ImageProvider.IMG_TRPOINT;
+ }
+ return null;
+ }
+
+ @Override
+ public Object[] create(ICreateContext context) {
+ // create transition point
+ TrPoint tp = null;
+ switch (type) {
+ case ENTRY_POINT:
+ tp = RoomFactory.eINSTANCE.createEntryPoint();
+ break;
+ case EXIT_POINT:
+ tp = RoomFactory.eINSTANCE.createExitPoint();
+ break;
+ case TRANS_POINT:
+ tp = RoomFactory.eINSTANCE.createTransitionPoint();
+ break;
+ }
+ tp.setName("tp");
+
+ StateGraph sg = (StateGraph) context.getTargetContainer().getLink().getBusinessObjects().get(0);
+
+ // TODOHRR-B add property dialog
+// Shell shell = PlatformUI.getWorkbench().getActiveWorkbenchWindow().getShell();
+// SPPPropertyDialog dlg = new SPPPropertyDialog(shell, spp, acc, true, false);
+// if (dlg.open()!=Window.OK)
+// // find a method to abort creation
+// //throw new RuntimeException();
+// return EMPTY;
+
+ doneChanges = true;
+
+ sg.getTrPoints().add(tp);
+
+ // do the add
+ addGraphicalRepresentation(context, tp);
+
+ // return newly created business object(s)
+ return new Object[] { tp };
+ }
+
+ @Override
+ public boolean canCreate(ICreateContext context) {
+ if (context.getTargetContainer().getLink()!=null)
+ if (context.getTargetContainer().getLink().getBusinessObjects().size()==1) {
+ EObject obj = context.getTargetContainer().getLink().getBusinessObjects().get(0);
+ if (obj instanceof StateGraph) {
+ return isValidPosition(context, context, StateGraphSupport.MARGIN);
+ }
+ }
+ return false;
+ }
+
+ @Override
+ public boolean hasDoneChanges() {
+ return doneChanges;
+ }
+ }
+
+ private class AddFeature extends AbstractAddFeature {
+
+ public AddFeature(IFeatureProvider fp) {
+ super(fp);
+ }
+
+ @Override
+ public boolean canAdd(IAddContext context) {
+ if (context.getNewObject() instanceof TrPoint) {
+ if (context.getTargetContainer().getLink().getBusinessObjects().size()==1) {
+ EObject obj = context.getTargetContainer().getLink().getBusinessObjects().get(0);
+ if (obj instanceof StateGraph) {
+ return true;
+ }
+ }
+ }
+ return false;
+ }
+
+ @Override
+ public PictogramElement add(IAddContext context) {
+ TrPoint tp = (TrPoint) context.getNewObject();
+ ContainerShape acShape = context.getTargetContainer();
+ Object bo = getBusinessObjectForPictogramElement(acShape);
+ boolean inherited = isInherited(tp, bo, acShape);
+ boolean subtp = (bo instanceof State);
+
+ int margin = subtp?ITEM_SIZE_SMALL:ITEM_SIZE;
+ int size = subtp?ITEM_SIZE_SMALL:ITEM_SIZE;
+
+ // CONTAINER SHAPE WITH RECTANGLE
+ IPeCreateService peCreateService = Graphiti.getPeCreateService();
+ ContainerShape containerShape =
+ peCreateService.createContainerShape(acShape, true);
+
+ Graphiti.getPeService().setPropertyValue(containerShape, Constants.TYPE_KEY, Constants.TRP_TYPE);
+
+ String kind = getItemKind(tp);
+ Graphiti.getPeService().setPropertyValue(containerShape, PROP_KIND, kind);
+
+ // we have relative coordinates here
+ int x = context.getX()-size;
+ int y = context.getY()-size;
+ int width = acShape.getGraphicsAlgorithm().getWidth();
+ int height = acShape.getGraphicsAlgorithm().getHeight();
+ {
+ int dx = (x<=width/2)? x:width-x;
+ int dy = (y<=height/2)? y:height-y;
+ if (dx>dy) {
+ // keep x, project y
+ if (y<=height/2)
+ y = 0;
+ else
+ y = height-2*margin;
+ }
+ else {
+ // keep y, project x
+ if (x<=width/2)
+ x = 0;
+ else
+ x = width-2*margin;
+ }
+ }
+
+ Color dark = manageColor(inherited? INHERITED_COLOR:DARK_COLOR);
+ IGaService gaService = Graphiti.getGaService();
+ {
+ final Rectangle invisibleRectangle = gaService.createInvisibleRectangle(containerShape);
+ gaService.setLocationAndSize(invisibleRectangle, x, y, 2*size, 2*size);
+
+ createFigure(tp, subtp,
+ containerShape,
+ invisibleRectangle,
+ dark,
+ manageColor(BRIGHT_COLOR));
+
+ // create link and wire it
+ link(containerShape, tp);
+ }
+
+ {
+ Shape labelShape = peCreateService.createShape(containerShape, false);
+ Text label = gaService.createDefaultText(labelShape, tp.getName());
+ label.setForeground(dark);
+ label.setBackground(dark);
+ label.setHorizontalAlignment(Orientation.ALIGNMENT_CENTER);
+ label.setVerticalAlignment(Orientation.ALIGNMENT_CENTER);
+ gaService.setLocationAndSize(label, 0, 3*size/2, 2*size, size/2);
+ adjustLabel(label, x, y, width, margin, size);
+ }
+
+ // call the layout feature
+ layoutPictogramElement(containerShape);
+
+ return containerShape;
+
+ }
+
+ }
+
+ protected class MoveShapeFeature extends DefaultMoveShapeFeature {
+
+ public MoveShapeFeature(IFeatureProvider fp) {
+ super(fp);
+ }
+
+ @Override
+ public boolean canMoveShape(IMoveShapeContext context) {
+ boolean canMove = super.canMoveShape(context);
+
+ if (canMove) {
+ Object bo = getBusinessObjectForPictogramElement(context.getPictogramElement());
+ if (bo instanceof TrPoint) {
+ TrPoint tp = (TrPoint) bo;
+
+ ContainerShape acShape = context.getTargetContainer();
+ Object parentBO = getBusinessObjectForPictogramElement(acShape);
+ if (isInherited(tp, parentBO, acShape))
+ return false;
+
+ boolean refport = (parentBO instanceof ActorContainerRef);
+ int margin = refport?StateSupport.MARGIN:StateGraphSupport.MARGIN;
+ return isValidPosition(context, context, margin);
+ }
+ return false;
+ }
+
+ return canMove;
+ }
+
+ @Override
+ protected void postMoveShape(IMoveShapeContext context) {
+ ContainerShape shapeToMove = (ContainerShape) context.getShape();
+
+ ContainerShape acShape = context.getTargetContainer();
+ boolean subtp = (getBusinessObjectForPictogramElement(acShape) instanceof ActorContainerRef);
+
+ int margin = subtp?StateSupport.MARGIN:StateGraphSupport.MARGIN;
+ int size = subtp?StateSupport.MARGIN:ITEM_SIZE;
+
+ int x = context.getX();
+ int y = context.getY();
+ int width = context.getTargetContainer().getGraphicsAlgorithm().getGraphicsAlgorithmChildren().get(0).getWidth();
+ int height = context.getTargetContainer().getGraphicsAlgorithm().getGraphicsAlgorithmChildren().get(0).getHeight();
+
+ // project onto boundary
+ if (x<=margin)
+ x = 0;
+ if (y<=margin)
+ y = 0;
+ if ((width-margin)<=x)
+ x = width;
+ if ((height-margin)<=y)
+ y = height;
+
+ Graphiti.getGaService().setLocation(shapeToMove.getGraphicsAlgorithm(), x, y, avoidNegativeCoordinates());
+
+ GraphicsAlgorithm ga = shapeToMove.getChildren().get(0).getGraphicsAlgorithm();
+ if (ga instanceof Text) {
+ adjustLabel((Text) ga, x, y, width, margin, size);
+ }
+ }
+ }
+
+ private static class PropertyFeature extends AbstractCustomFeature {
+
+ private String name;
+ private String description;
+
+ public PropertyFeature(IFeatureProvider fp) {
+ super(fp);
+ this.name = "Edit Transition Point";
+ this.description = "Edit Transition Point";
+ }
+
+ @Override
+ public String getName() {
+ return name;
+ }
+
+ @Override
+ public String getDescription() {
+ return description;
+ }
+
+ @Override
+ public boolean canExecute(ICustomContext context) {
+ PictogramElement[] pes = context.getPictogramElements();
+ if (pes != null && pes.length == 1 && pes[0] instanceof ContainerShape) {
+ Object bo = getBusinessObjectForPictogramElement(pes[0]);
+ if (bo instanceof TrPoint) {
+ ContainerShape container = (ContainerShape)pes[0];
+ bo = getBusinessObjectForPictogramElement(container);
+ return (bo instanceof StateGraph);
+ }
+ }
+ return false;
+ }
+
+ @Override
+ public void execute(ICustomContext context) {
+ TrPoint tp = (TrPoint) getBusinessObjectForPictogramElement(context.getPictogramElements()[0]);
+ StateGraph acc = (StateGraph)tp.eContainer();
+ boolean subtp = isSubTP(context.getPictogramElements()[0]);
+
+ // TODOHRR-B property dialog
+// Shell shell = PlatformUI.getWorkbench().getActiveWorkbenchWindow().getShell();
+// SPPPropertyDialog dlg = new SPPPropertyDialog(shell, tp, acc, false, subtp);
+// if (dlg.open()!=Window.OK)
+// // TODOHRR: introduce a method to revert changes, does hasDoneChanges=false roll back changes?
+// //throw new RuntimeException();
+// return;
+
+ updateSPPFigure(tp, context.getPictogramElements()[0], manageColor(DARK_COLOR), manageColor(BRIGHT_COLOR));
+ }
+
+ }
+
+ private class UpdateFeature extends AbstractUpdateFeature {
+
+ public UpdateFeature(IFeatureProvider fp) {
+ super(fp);
+ }
+
+ @Override
+ public boolean canUpdate(IUpdateContext context) {
+ Object bo = getBusinessObjectForPictogramElement(context.getPictogramElement());
+ if (bo instanceof EObject && ((EObject)bo).eIsProxy())
+ return true;
+
+ return bo instanceof InterfaceItem;
+ }
+
+ @Override
+ public IReason updateNeeded(IUpdateContext context) {
+ Object bo = getBusinessObjectForPictogramElement(context.getPictogramElement());
+ if (bo instanceof EObject && ((EObject)bo).eIsProxy()) {
+ return Reason.createTrueReason("InterfaceItem deleted from model");
+ }
+ TrPoint tp = (TrPoint) bo;
+
+ // check if tp still owned/inherited
+ ContainerShape containerShape = (ContainerShape)context.getPictogramElement();
+ bo = getBusinessObjectForPictogramElement(containerShape);
+ // TODOHRR-B check inheritance
+// if (bo instanceof StateGraph) {
+// StateGraph sg = (StateGraph) bo;
+// boolean found = false;
+// do {
+// if (sg==tp.eContainer())
+// found = true;
+// sg = sg.getBase();
+// }
+// while (!found && sg!=null);
+//
+// if (!found)
+// return Reason.createTrueReason("TransitionPoint not inherited anymore");
+// }
+
+ GraphicsAlgorithm ga = containerShape.getChildren().get(0).getGraphicsAlgorithm();
+ if (ga instanceof Text) {
+ if (!tp.getName().equals(((Text)ga).getValue()))
+ return Reason.createTrueReason("Name is out of date");
+
+ String kind = getItemKind(tp);
+ if (!kind.equals(Graphiti.getPeService().getPropertyValue(context.getPictogramElement(), PROP_KIND)))
+ return Reason.createTrueReason("Figure is out of date");
+ }
+ return Reason.createFalseReason();
+ }
+
+ @Override
+ public boolean update(IUpdateContext context) {
+ ContainerShape containerShape = (ContainerShape)context.getPictogramElement();
+ Object bo = getBusinessObjectForPictogramElement(containerShape);
+ if (bo instanceof EObject && ((EObject)bo).eIsProxy()) {
+ IRemoveContext rc = new RemoveContext(containerShape);
+ IFeatureProvider featureProvider = getFeatureProvider();
+ IRemoveFeature removeFeature = featureProvider.getRemoveFeature(rc);
+ if (removeFeature != null) {
+ removeFeature.remove(rc);
+ }
+ EcoreUtil.delete((EObject) bo);
+ return true;
+ }
+ TrPoint tp = (TrPoint) bo;
+
+ boolean inherited = isInherited(tp, bo, containerShape);
+
+ Color dark = manageColor(inherited? INHERITED_COLOR:DARK_COLOR);
+ updateSPPFigure(tp, containerShape, dark, manageColor(BRIGHT_COLOR));
+ String kind = getItemKind(tp);
+ Graphiti.getPeService().setPropertyValue(containerShape, PROP_KIND, kind);
+ return true;
+ }
+
+ }
+
+ protected static class RemoveFeature extends DefaultRemoveFeature {
+
+ public RemoveFeature(IFeatureProvider fp) {
+ super(fp);
+ }
+
+ public boolean canRemove(IRemoveContext context) {
+ return !isSubTP(context.getPictogramElement());
+ }
+ }
+
+ protected static class DeleteFeature extends DefaultDeleteFeature {
+
+ public DeleteFeature(IFeatureProvider fp) {
+ super(fp);
+ }
+
+ @Override
+ public boolean canDelete(IDeleteContext context) {
+ return !isSubTP(context.getPictogramElement());
+ }
+ }
+
+ protected IFeatureProvider fp;
+
+ protected FeatureProvider(IDiagramTypeProvider dtp, IFeatureProvider fp) {
+ super(dtp);
+ this.fp = fp;
+ }
+
+ @Override
+ public ICreateFeature[] getCreateFeatures() {
+ return new ICreateFeature[] {
+ new CreateFeature(fp, Type.TRANS_POINT, "Transition Point", "Create Transition Point"),
+ new CreateFeature(fp, Type.ENTRY_POINT, "Entry Point", "Create Entry Point"),
+ new CreateFeature(fp, Type.EXIT_POINT, "Exit Point", "Create Exit Point")
+ };
+ }
+
+ @Override
+ public IAddFeature getAddFeature(IAddContext context) {
+ return new AddFeature(fp);
+ }
+
+ @Override
+ public IMoveShapeFeature getMoveShapeFeature(IMoveShapeContext context) {
+ return new MoveShapeFeature(fp);
+ }
+
+ @Override
+ public IResizeShapeFeature getResizeShapeFeature(IResizeShapeContext context) {
+ return new NoResizeFeature(fp);
+ }
+
+ @Override
+ public ICustomFeature[] getCustomFeatures(ICustomContext context) {
+ return new ICustomFeature[] { new PropertyFeature(fp) };
+ }
+
+ @Override
+ public IUpdateFeature getUpdateFeature(IUpdateContext context) {
+ return new UpdateFeature(fp);
+ }
+
+ @Override
+ public IRemoveFeature getRemoveFeature(IRemoveContext context) {
+ return new RemoveFeature(fp);
+ }
+
+ @Override
+ public IDeleteFeature getDeleteFeature(IDeleteContext context) {
+ return new DeleteFeature(fp);
+ }
+
+ protected static void createFigure(TrPoint tp, boolean subtp,
+ ContainerShape containerShape,
+ GraphicsAlgorithm invisibleRectangle, Color darkColor, Color brightColor) {
+
+ int size = subtp?ITEM_SIZE_SMALL:ITEM_SIZE;
+ int line = subtp?LINE_WIDTH/2:LINE_WIDTH;
+
+
+ IGaService gaService = Graphiti.getGaService();
+
+ Ellipse circle = gaService.createEllipse(invisibleRectangle);
+ circle.setForeground(darkColor);
+ circle.setBackground(brightColor);
+ circle.setLineWidth(line);
+ int s2 = size/2;
+ gaService.setLocationAndSize(circle, s2, s2, size, size);
+
+ if (tp instanceof TransitionPoint) {
+ if (((TransitionPoint) tp).isHandler())
+ circle.setBackground(darkColor);
+ }
+ else if (tp instanceof ExitPoint) {
+ int xy[] = new int[] { s2, 0, size, s2, s2, size, 0, s2};
+ Polygon diamond = gaService.createPolygon(invisibleRectangle, xy);
+ diamond.setForeground(darkColor);
+ diamond.setBackground(brightColor);
+ diamond.setLineWidth(line);
+ gaService.setLocation(diamond, s2, s2);
+ }
+ else if (tp instanceof EntryPoint) {
+ int sq = (int) (0.707106*s2);
+ int l1[] = new int[] { size-sq, size+sq, size+sq, size-sq };
+ Polyline line1 = gaService.createPolyline(invisibleRectangle, l1);
+ line1.setLineWidth(line);
+ line1.setForeground(darkColor);
+ int l2[] = new int[] { size-sq, size-sq, size+sq, size+sq };
+ Polyline line2 = gaService.createPolyline(invisibleRectangle, l2);
+ line2.setLineWidth(line);
+ line2.setForeground(darkColor);
+ }
+
+ if (containerShape.getAnchors().isEmpty()) {
+ // here we place our anchor
+ IPeCreateService peCreateService = Graphiti.getPeCreateService();
+ // TODOHRR: EllipseAnchor would be nice
+ ChopboxAnchor anchor = peCreateService.createChopboxAnchor(containerShape);
+ anchor.setReferencedGraphicsAlgorithm(circle);
+ }
+ else {
+ // we just set the referenced GA
+ //containerShape.getAnchors().get(0).setReferencedGraphicsAlgorithm(rect);
+ }
+ }
+
+ private static void updateSPPFigure(TrPoint tp, PictogramElement pe, Color dark, Color bright) {
+ ContainerShape container = (ContainerShape)pe;
+
+ // we clear the figure and rebuild it
+ GraphicsAlgorithm invisibleRect = pe.getGraphicsAlgorithm();
+ invisibleRect.getGraphicsAlgorithmChildren().clear();
+
+ createFigure(tp, false, container, invisibleRect, dark, bright);
+
+ GraphicsAlgorithm ga = container.getChildren().get(0).getGraphicsAlgorithm();
+ if (ga instanceof Text) {
+ ((Text)ga).setValue(tp.getName());
+ }
+
+ }
+
+ protected static boolean isSubTP(PictogramElement pe) {
+ if (!(pe instanceof ContainerShape))
+ return false;
+
+ ContainerShape acShape = ((ContainerShape)pe).getContainer();
+
+ if (acShape.getLink()==null || acShape.getLink().getBusinessObjects().isEmpty())
+ return false;
+
+ Object parent = acShape.getLink().getBusinessObjects().get(0);
+
+ return (parent instanceof ActorContainerRef);
+ }
+
+ protected static boolean isInherited(TrPoint tp, Object container, ContainerShape cs) {
+ if (container instanceof StateGraph) {
+ StateGraph sg = (StateGraph) container;
+ return tp.eContainer()!=sg;
+ }
+ else if (container instanceof State) {
+ // have to check whether the State is inherited
+ State s = (State) container;
+ ContainerShape sCont = cs.getContainer();
+ EObject cls = sCont.getLink().getBusinessObjects().get(0);
+ return s.eContainer()!=cls;
+ }
+
+ return false;
+ }
+
+ protected static boolean isValidPosition(ILocationContext loc, ITargetContext tgt, int margin) {
+ //System.out.println("isValidPosition "+tgt.getTargetContainer());
+ if (tgt.getTargetContainer().getGraphicsAlgorithm()==null)
+ return false;
+ if (tgt.getTargetContainer().getGraphicsAlgorithm().getGraphicsAlgorithmChildren().isEmpty())
+ return false;
+
+ int x = loc.getX();
+ int y = loc.getY();
+ if (loc instanceof ICreateContext) {
+ // adjust position as relative to visible rectangle
+ x -= margin;
+ y -= margin;
+ }
+ int width = tgt.getTargetContainer().getGraphicsAlgorithm().getGraphicsAlgorithmChildren().get(0).getWidth();
+ int height = tgt.getTargetContainer().getGraphicsAlgorithm().getGraphicsAlgorithmChildren().get(0).getHeight();
+
+ boolean inStripe = false;
+
+ // may move in a stripe along the actor class border
+ int stripe = margin/2;
+ if (x<=stripe)
+ inStripe = true;
+ else if (y<=stripe)
+ inStripe = true;
+ else if ((width-stripe)<=x)
+ inStripe = true;
+ else if ((height-stripe)<=y)
+ inStripe = true;
+
+ //System.out.println("w:"+width+" h:"+height+" x:"+x+" y:"+y+" in stripe "+inStripe);
+
+ return inStripe;
+ }
+
+
+ protected static String getItemKind(TrPoint item) {
+ if (item instanceof TransitionPoint) {
+ return ((TransitionPoint) item).isHandler()? "htp":"tp";
+ }
+ else if (item instanceof EntryPoint) {
+ return "entp";
+ }
+ else if (item instanceof ExitPoint) {
+ return "extp";
+ }
+ return "";
+ }
+
+ protected static void adjustLabel(Text label, int x, int y, int width, int margin, int size) {
+ Orientation align = Orientation.ALIGNMENT_CENTER;
+ label.setHorizontalAlignment(align);
+
+ int pos = 3*size/2;
+
+ if (x<=margin)
+ align = Orientation.ALIGNMENT_LEFT;
+ else if ((width-margin)<=x)
+ align = Orientation.ALIGNMENT_RIGHT;
+ if (y<=margin)
+ pos = 0;
+
+ if (align!=label.getHorizontalAlignment()) {
+ label.setHorizontalAlignment(align);
+ }
+ if (pos!=label.getY()) {
+ IGaService gaService = Graphiti.getGaService();
+ gaService.setLocationAndSize(label, 0, pos, 2*size, size/2);
+ }
+ }
+
+ }
+
+ private class BehaviorProvider extends DefaultToolBehaviorProvider {
+
+ public BehaviorProvider(IDiagramTypeProvider dtp) {
+ super(dtp);
+ }
+
+ @Override
+ public GraphicsAlgorithm[] getClickArea(PictogramElement pe) {
+ GraphicsAlgorithm invisible = pe.getGraphicsAlgorithm();
+ GraphicsAlgorithm rectangle =
+ invisible.getGraphicsAlgorithmChildren().get(0);
+ return new GraphicsAlgorithm[] { rectangle };
+ }
+
+ @Override
+ public GraphicsAlgorithm getSelectionBorder(PictogramElement pe) {
+ GraphicsAlgorithm invisible = pe.getGraphicsAlgorithm();
+
+ GraphicsAlgorithm rectangle =
+ invisible.getGraphicsAlgorithmChildren().get(0);
+ return rectangle;
+ }
+
+ @Override
+ public ICustomFeature getDoubleClickFeature(IDoubleClickContext context) {
+ return new FeatureProvider.PropertyFeature(getDiagramTypeProvider().getFeatureProvider());
+ }
+
+ @Override
+ public IContextButtonPadData getContextButtonPad(
+ IPictogramElementContext context) {
+
+ IContextButtonPadData data = super.getContextButtonPad(context);
+ PictogramElement pe = context.getPictogramElement();
+
+ CreateConnectionContext ccc = new CreateConnectionContext();
+ ccc.setSourcePictogramElement(pe);
+ Anchor anchor = null;
+ if (pe instanceof AnchorContainer) {
+ // our spp has four fixed point anchor - we choose the first one
+ anchor = ((ContainerShape)pe).getAnchors().get(0);
+ }
+ ccc.setSourceAnchor(anchor);
+
+ ContextButtonEntry button = new ContextButtonEntry(null, context);
+ button.setText("Create Binding");
+ button.setIconId(ImageProvider.IMG_TRANSITION);
+ ICreateConnectionFeature[] features = getFeatureProvider().getCreateConnectionFeatures();
+ for (ICreateConnectionFeature feature : features) {
+ if (feature.isAvailable(ccc) && feature.canStartConnection(ccc))
+ button.addDragAndDropFeature(feature);
+ }
+
+ if (button.getDragAndDropFeatures().size() > 0) {
+ data.getDomainSpecificContextButtons().add(button);
+ }
+
+ return data;
+ }
+ }
+
+ private FeatureProvider pfp;
+ private BehaviorProvider tbp;
+
+ public TrPointSupport(IDiagramTypeProvider dtp, IFeatureProvider fp) {
+ pfp = new FeatureProvider(dtp,fp);
+ tbp = new BehaviorProvider(dtp);
+ }
+
+ public IFeatureProvider getFeatureProvider() {
+ return pfp;
+ }
+
+ public IToolBehaviorProvider getToolBehaviorProvider() {
+ return tbp;
+ }
+}
diff --git a/plugins/org.eclipse.etrice.ui.behavior/src/org/eclipse/etrice/ui/behavior/support/TransitionSupport.java b/plugins/org.eclipse.etrice.ui.behavior/src/org/eclipse/etrice/ui/behavior/support/TransitionSupport.java
new file mode 100644
index 000000000..a046c6224
--- /dev/null
+++ b/plugins/org.eclipse.etrice.ui.behavior/src/org/eclipse/etrice/ui/behavior/support/TransitionSupport.java
@@ -0,0 +1,341 @@
+/*******************************************************************************
+ * Copyright (c) 2010 protos software gmbh (http://www.protos.de).
+ * 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:
+ * Thomas Schuetz and Henrik Rentz-Reichert (initial contribution)
+ *
+ *******************************************************************************/
+
+package org.eclipse.etrice.ui.behavior.support;
+
+import org.eclipse.emf.ecore.EObject;
+import org.eclipse.emf.ecore.util.EcoreUtil;
+import org.eclipse.etrice.core.validation.ValidationUtil;
+import org.eclipse.etrice.ui.behavior.ImageProvider;
+import org.eclipse.graphiti.dt.IDiagramTypeProvider;
+import org.eclipse.graphiti.features.IAddFeature;
+import org.eclipse.graphiti.features.ICreateConnectionFeature;
+import org.eclipse.graphiti.features.IFeatureProvider;
+import org.eclipse.graphiti.features.IReason;
+import org.eclipse.graphiti.features.IRemoveFeature;
+import org.eclipse.graphiti.features.IUpdateFeature;
+import org.eclipse.graphiti.features.context.IAddConnectionContext;
+import org.eclipse.graphiti.features.context.IAddContext;
+import org.eclipse.graphiti.features.context.ICreateConnectionContext;
+import org.eclipse.graphiti.features.context.IRemoveContext;
+import org.eclipse.graphiti.features.context.IUpdateContext;
+import org.eclipse.graphiti.features.context.impl.AddConnectionContext;
+import org.eclipse.graphiti.features.context.impl.RemoveContext;
+import org.eclipse.graphiti.features.impl.AbstractAddFeature;
+import org.eclipse.graphiti.features.impl.AbstractCreateConnectionFeature;
+import org.eclipse.graphiti.features.impl.AbstractUpdateFeature;
+import org.eclipse.graphiti.features.impl.Reason;
+import org.eclipse.graphiti.mm.algorithms.Polyline;
+import org.eclipse.graphiti.mm.pictograms.Anchor;
+import org.eclipse.graphiti.mm.pictograms.Connection;
+import org.eclipse.graphiti.mm.pictograms.ContainerShape;
+import org.eclipse.graphiti.mm.pictograms.PictogramElement;
+import org.eclipse.graphiti.services.Graphiti;
+import org.eclipse.graphiti.services.IGaService;
+import org.eclipse.graphiti.services.IPeCreateService;
+import org.eclipse.graphiti.tb.DefaultToolBehaviorProvider;
+import org.eclipse.graphiti.tb.IToolBehaviorProvider;
+import org.eclipse.graphiti.ui.features.DefaultFeatureProvider;
+import org.eclipse.graphiti.util.ColorConstant;
+import org.eclipse.graphiti.util.IColorConstant;
+
+import org.eclipse.etrice.core.room.ActorClass;
+import org.eclipse.etrice.core.room.ActorContainerClass;
+import org.eclipse.etrice.core.room.ActorContainerRef;
+import org.eclipse.etrice.core.room.Binding;
+import org.eclipse.etrice.core.room.BindingEndPoint;
+import org.eclipse.etrice.core.room.LogicalSystem;
+import org.eclipse.etrice.core.room.Port;
+import org.eclipse.etrice.core.room.RoomFactory;
+import org.eclipse.etrice.core.room.StructureClass;
+import org.eclipse.etrice.core.room.SubSystemClass;
+
+public class TransitionSupport {
+
+ private static final IColorConstant LINE_COLOR = new ColorConstant(0, 0, 0);
+
+ class FeatureProvider extends DefaultFeatureProvider {
+
+ private class CreateFeature extends AbstractCreateConnectionFeature {
+
+ private boolean justStarted = false;
+
+ public CreateFeature(IFeatureProvider fp) {
+ super(fp, "Transition", "create Transition");
+ }
+
+ @Override
+ public String getCreateImageId() {
+ return ImageProvider.IMG_TRANSITION;
+ }
+
+ @Override
+ public boolean canCreate(ICreateConnectionContext context) {
+ Port src = getPort(context.getSourceAnchor());
+ Port tgt = getPort(context.getTargetAnchor());
+ ActorContainerRef srcRef = getRef(context.getSourceAnchor());
+
+ if (justStarted) {
+ justStarted = false;
+ beginHighLightMatches(src, srcRef);
+ }
+
+ if (src==null || tgt==null) {
+ return false;
+ }
+
+ StructureClass ac = getParent(context);
+ if (ac==null) {
+ return false;
+ }
+
+ ActorContainerRef tgtRef = getRef(context.getTargetAnchor());
+
+ return ValidationUtil.isConnectable(src, srcRef, tgt, tgtRef, ac);
+ }
+
+ public boolean canStartConnection(ICreateConnectionContext context) {
+ Port src = getPort(context.getSourceAnchor());
+ boolean canStart = src!=null;
+ if (canStart) {
+ ActorContainerRef ref = getRef(context.getSourceAnchor());
+ if (ref==null) {
+ // this port is local, i.e. owned by the parent itself
+ ActorContainerClass acc = (ActorContainerClass) src.eContainer();
+ if (!ValidationUtil.isConnectable(src, null, acc))
+ canStart = false;
+ }
+ else {
+ ActorContainerClass acc = (ActorContainerClass) ref.eContainer();
+ if (!ValidationUtil.isConnectable(src, ref, acc))
+ canStart = false;
+ }
+ }
+ if (canStart)
+ justStarted = true;
+ return canStart;
+ }
+
+ private Port getPort(Anchor anchor) {
+ if (anchor != null) {
+ Object obj = getBusinessObjectForPictogramElement(anchor.getParent());
+ if (obj instanceof Port) {
+ return (Port) obj;
+ }
+ }
+ return null;
+ }
+
+ public StructureClass getParent(ICreateConnectionContext context) {
+ ContainerShape shape = (ContainerShape) context.getSourcePictogramElement().eContainer();
+ Object bo = getBusinessObjectForPictogramElement(shape);
+ if (bo instanceof StructureClass)
+ return (StructureClass) bo;
+
+ shape = (ContainerShape) shape.eContainer();
+ bo = getBusinessObjectForPictogramElement(shape);
+ if (bo instanceof StructureClass)
+ return (StructureClass) bo;
+
+ return null;
+ }
+
+ public ActorContainerRef getRef(Anchor anchor) {
+ ContainerShape shape = (ContainerShape) anchor.getParent().eContainer();
+ Object bo = getBusinessObjectForPictogramElement(shape);
+ if (bo instanceof ActorContainerRef)
+ return (ActorContainerRef) bo;
+
+ return null;
+ }
+
+ @Override
+ public Connection create(ICreateConnectionContext context) {
+ Connection newConnection = null;
+
+ endHighLightMatches();
+
+ Port src = getPort(context.getSourceAnchor());
+ Port dst = getPort(context.getTargetAnchor());
+ StructureClass ac = getParent(context);
+ if (src!=null && dst!=null && ac!=null) {
+ Binding bind = RoomFactory.eINSTANCE.createBinding();
+ BindingEndPoint ep1 = RoomFactory.eINSTANCE.createBindingEndPoint();
+ ActorContainerRef ar1 = getRef(context.getSourceAnchor());
+ ep1.setPort(src);
+ ep1.setActorRef(ar1);
+ BindingEndPoint ep2 = RoomFactory.eINSTANCE.createBindingEndPoint();
+ ActorContainerRef ar2 = getRef(context.getTargetAnchor());
+ ep2.setPort(dst);
+ ep2.setActorRef(ar2);
+ bind.setEndpoint1(ep1);
+ bind.setEndpoint2(ep2);
+ ac.getBindings().add(bind);
+
+ AddConnectionContext addContext = new AddConnectionContext(context.getSourceAnchor(), context.getTargetAnchor());
+ addContext.setNewObject(bind);
+ newConnection = (Connection) getFeatureProvider().addIfPossible(addContext);
+ }
+
+ return newConnection;
+ }
+
+ private void beginHighLightMatches(Port port, ActorContainerRef ref) {
+ if (port==null)
+ return;
+
+ StructureClass acc = (ActorContainerClass) ((ref!=null)? ref.eContainer():port.eContainer());
+ if (acc instanceof ActorClass) {
+
+ }
+ else if (acc instanceof SubSystemClass) {
+
+ }
+ else if (acc instanceof LogicalSystem) {
+
+ }
+ else {
+ assert(false): "unknown kind of StructureClass";
+ }
+ }
+
+ private void endHighLightMatches() {
+ }
+ }
+
+ private class AddFeature extends AbstractAddFeature {
+
+ public AddFeature(IFeatureProvider fp) {
+ super(fp);
+ }
+
+ @Override
+ public boolean canAdd(IAddContext context) {
+ if (context instanceof IAddConnectionContext && context.getNewObject() instanceof Binding) {
+ return true;
+ }
+ return false;
+ }
+
+ @Override
+ public PictogramElement add(IAddContext context) {
+ IAddConnectionContext addConContext = (IAddConnectionContext) context;
+ Binding addedEReference = (Binding) context.getNewObject();
+
+ IPeCreateService peCreateService = Graphiti.getPeCreateService();
+ // CONNECTION WITH POLYLINE
+ Connection connection = peCreateService.createFreeFormConnection(getDiagram());
+ connection.setStart(addConContext.getSourceAnchor());
+ connection.setEnd(addConContext.getTargetAnchor());
+
+ Graphiti.getPeService().setPropertyValue(connection, Constants.TYPE_KEY, Constants.TRANS_TYPE);
+
+ IGaService gaService = Graphiti.getGaService();
+ Polyline polyline = gaService.createPolyline(connection);
+ polyline.setForeground(manageColor(LINE_COLOR));
+
+ // create link and wire it
+ link(connection, addedEReference);
+
+ return connection;
+ }
+
+ }
+
+ private class UpdateFeature extends AbstractUpdateFeature {
+
+ public UpdateFeature(IFeatureProvider fp) {
+ super(fp);
+ }
+
+ @Override
+ public boolean canUpdate(IUpdateContext context) {
+ Object bo = getBusinessObjectForPictogramElement(context.getPictogramElement());
+ if (bo instanceof EObject && ((EObject)bo).eIsProxy())
+ return true;
+
+ return false;
+ }
+
+ @Override
+ public IReason updateNeeded(IUpdateContext context) {
+ Object bo = getBusinessObjectForPictogramElement(context.getPictogramElement());
+ if (bo instanceof EObject && ((EObject)bo).eIsProxy()) {
+ return Reason.createTrueReason("Binding deleted from model");
+ }
+ return Reason.createFalseReason();
+ }
+
+ @Override
+ public boolean update(IUpdateContext context) {
+ ContainerShape containerShape = (ContainerShape)context.getPictogramElement();
+ Object bo = getBusinessObjectForPictogramElement(containerShape);
+ if (bo instanceof EObject && ((EObject)bo).eIsProxy()) {
+ IRemoveContext rc = new RemoveContext(containerShape);
+ IFeatureProvider featureProvider = getFeatureProvider();
+ IRemoveFeature removeFeature = featureProvider.getRemoveFeature(rc);
+ if (removeFeature != null) {
+ removeFeature.remove(rc);
+ }
+ EcoreUtil.delete((EObject) bo);
+ return true;
+ }
+ return false;
+ }
+ }
+
+ private IFeatureProvider fp;
+
+ public FeatureProvider(IDiagramTypeProvider dtp, IFeatureProvider fp) {
+ super(dtp);
+ this.fp = fp;
+ }
+
+ @Override
+ public ICreateConnectionFeature[] getCreateConnectionFeatures() {
+ return new ICreateConnectionFeature[] { new CreateFeature(fp) };
+ }
+
+ @Override
+ public IAddFeature getAddFeature(IAddContext context) {
+ return new AddFeature(fp);
+ }
+
+ @Override
+ public IUpdateFeature getUpdateFeature(IUpdateContext context) {
+ return new UpdateFeature(fp);
+ }
+ }
+
+ class BehaviorProvider extends DefaultToolBehaviorProvider {
+
+ public BehaviorProvider(IDiagramTypeProvider dtp) {
+ super(dtp);
+ }
+ }
+
+ private FeatureProvider pfp;
+ private BehaviorProvider tbp;
+
+ public TransitionSupport(IDiagramTypeProvider dtp, IFeatureProvider fp) {
+ pfp = new FeatureProvider(dtp,fp);
+ tbp = new BehaviorProvider(dtp);
+ }
+
+ public IFeatureProvider getFeatureProvider() {
+ return pfp;
+ }
+
+ public IToolBehaviorProvider getToolBehaviorProvider() {
+ return tbp;
+ }
+}

Back to the top