diff --git a/org.fortiss.tooling.base.ui/trunk/src/org/fortiss/tooling/base/ui/compose/ConnectorConnectionCompositorBase.java b/org.fortiss.tooling.base.ui/trunk/src/org/fortiss/tooling/base/ui/compose/ConnectorConnectionCompositorBase.java new file mode 100644 index 0000000000000000000000000000000000000000..b499336820ef29dad24c5f1ccb659b5423645566 --- /dev/null +++ b/org.fortiss.tooling.base.ui/trunk/src/org/fortiss/tooling/base/ui/compose/ConnectorConnectionCompositorBase.java @@ -0,0 +1,252 @@ +/*--------------------------------------------------------------------------+ +$Id$ +| | +| Copyright 2011 ForTISS GmbH | +| | +| Licensed under the Apache License, Version 2.0 (the "License"); | +| you may not use this file except in compliance with the License. | +| You may obtain a copy of the License at | +| | +| http://www.apache.org/licenses/LICENSE-2.0 | +| | +| Unless required by applicable law or agreed to in writing, software | +| distributed under the License is distributed on an "AS IS" BASIS, | +| WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | +| See the License for the specific language governing permissions and | +| limitations under the License. | ++--------------------------------------------------------------------------*/ +package org.fortiss.tooling.base.ui.compose; + +import org.eclipse.emf.ecore.EObject; +import org.fortiss.tooling.base.model.base.ConnectionSegmentBase; +import org.fortiss.tooling.base.model.base.ConnectorBase; +import org.fortiss.tooling.base.model.base.EntryConnectorBase; +import org.fortiss.tooling.base.model.base.ExitConnectorBase; +import org.fortiss.tooling.base.model.base.HierarchicElementBase; +import org.fortiss.tooling.base.model.element.IConnector; +import org.fortiss.tooling.base.model.element.IHierarchicElement; +import org.fortiss.tooling.base.ui.dnd.DragContext; +import org.fortiss.tooling.base.ui.editpart.interfaces.IFreeConnectorEditPart; +import org.fortiss.tooling.kernel.interfaces.IConnectionCompositionContext; +import org.fortiss.tooling.kernel.interfaces.IConnectionCompositor; +import org.fortiss.tooling.kernel.interfaces.ITopLevelElementContext; +import org.fortiss.tooling.kernel.services.IPersistencyService; + +/** + * Base compositor for connections supporting entry and exit connectors. + * + * @author hoelzl + * @author $Author$ + * @version $Rev$ + * @ConQAT.Rating RED Hash: + */ +public abstract class ConnectorConnectionCompositorBase<HE extends IHierarchicElement, S extends IConnector, T extends IConnector> + implements IConnectionCompositor<S, T> { + + /** {@inheritDoc} */ + @Override + public boolean canConnect(S source, T target, EObject connection, + IConnectionCompositionContext context) { + // Deny creation of feedback connections in internal view + if (!allowInternalFeedback() && context instanceof DragContext) { + DragContext dc = (DragContext) context; + // + if (dc.getSource() instanceof IFreeConnectorEditPart + && dc.getTarget() instanceof IFreeConnectorEditPart) { + return false; + } + } + + if (source instanceof EntryConnectorBase) { + if (target instanceof EntryConnectorBase) { + return checkEntryEntry((EntryConnectorBase) source, + (EntryConnectorBase) target, connection); + } else if (target instanceof ExitConnectorBase) { + // use swapping here + return checkExitEntry((ExitConnectorBase) target, + (EntryConnectorBase) source, connection); + } + } else if (source instanceof ExitConnectorBase) { + if (target instanceof EntryConnectorBase) { + return checkExitEntry((ExitConnectorBase) source, + (EntryConnectorBase) target, connection); + } else if (target instanceof ExitConnectorBase) { + return checkExitExit((ExitConnectorBase) source, + (ExitConnectorBase) target, connection); + } + } + return false; + } + + /** Checks entry to entry connection. */ + private boolean checkEntryEntry(EntryConnectorBase source, + EntryConnectorBase target, EObject connection) { + boolean swapped = false; + + // child input to super input => swap input + if (source.eContainer().eContainer() == target.eContainer()) { + EntryConnectorBase temp = source; + source = target; + target = temp; + swapped = true; + } + + // super input to child input + if (swapped || source.eContainer() == target.eContainer().eContainer()) { + return checkSourceOut(source, connection) + && checkTargetIn(target, connection); + } + return false; + } + + /** Checks exit to entry connection. */ + private boolean checkExitEntry(ExitConnectorBase source, + EntryConnectorBase target, EObject connection) { + if (source.eContainer().eContainer() == target.eContainer() + .eContainer()) { + return checkSourceOut(source, connection) + && checkTargetIn(target, connection); + } + return false; + } + + /** + * Checks exit to exit connection. + */ + private boolean checkExitExit(ExitConnectorBase source, + ExitConnectorBase target, EObject connection) { + boolean swapped = false; + if (source.eContainer() == target.eContainer().eContainer()) { + ExitConnectorBase temp = source; + source = target; + target = temp; + swapped = true; + } + if (swapped || source.eContainer().eContainer() == target.eContainer()) { + return checkSourceOut(source, connection) + && checkTargetIn(target, connection); + } + return false; + } + + /** + * Checks outgoing connection of source connector. + */ + private boolean checkSourceOut(ConnectorBase source, EObject connection) { + // source has no outgoing connection, is already connected, or allows + // multiple connections + return source.getOutgoingLength() == 0 + || (connection instanceof ConnectionSegmentBase && ((ConnectionSegmentBase) connection) + .getSource() == source) || allowOneToMany(); + } + + /** + * Checks incoming connections of target port. + */ + private boolean checkTargetIn(ConnectorBase target, EObject connection) { + // target has no incoming connection, is already connected, or allows + // multiple connections. + return target.getIncomingLength() == 0 + || (connection instanceof ConnectionSegmentBase && ((ConnectionSegmentBase) connection) + .getTarget() == target) || allowManyToOne(); + } + + /** + * {@inheritDoc} + */ + @Override + public void connect(S source, T target, EObject connection, + IConnectionCompositionContext context) { + + ConnectionSegmentBase conn; + if (connection instanceof ConnectionSegmentBase) { + conn = (ConnectionSegmentBase) connection; + } else { + conn = createConnection(source, target, context); + } + + // If we are working in a connected model, deal with IDs + ITopLevelElementContext modelContext = IPersistencyService.INSTANCE + .getTopLevelElementContextFor(source); + if (modelContext != null) { + // FIXME (FH): IDs + // modelContext.prepareIDsForCompose(channel); + } + + boolean swap = false; + + if (source instanceof EntryConnectorBase) { + if (target instanceof EntryConnectorBase) { + if (source.eContainer() == target.eContainer().eContainer()) { + ((HierarchicElementBase) source.eContainer()) + .getConnectionsList().add(conn); + } else { + // source.eContainer().eContainer() == + // target.eContainer() + ((HierarchicElementBase) target.eContainer()) + .getConnectionsList().add(conn); + swap = true; + } + } else if (target instanceof ExitConnectorBase) { + ((HierarchicElementBase) source.eContainer().eContainer()) + .getConnectionsList().add(conn); + swap = true; + } + } else if (source instanceof ExitConnectorBase) { + if (target instanceof EntryConnectorBase) { + ((HierarchicElementBase) source.eContainer().eContainer()) + .getConnectionsList().add(conn); + } else if (target instanceof ExitConnectorBase) { + if (source.eContainer() == target.eContainer().eContainer()) { + ((HierarchicElementBase) source.eContainer()) + .getConnectionsList().add(conn); + swap = true; + } else { + // source.eContainer().eContainer() == + // target.eContainer() + ((HierarchicElementBase) target.eContainer()) + .getConnectionsList().add(conn); + } + } + } + + if (swap) { + conn.setSource(target); + conn.setTarget(source); + } else { + conn.setSource(source); + conn.setTarget(target); + } + } + + /** + * Creates a new {@link ConnectionSegmentBase}. The {@link IConnector}s are + * provided to make use of their names when naming the connection. However + * they should not be used for connecting. + */ + protected abstract ConnectionSegmentBase createConnection(S source, + T target, IConnectionCompositionContext context); + + /** + * Configures multiple connection behavior for 1-to-many connections. The + * default is allow. + */ + protected boolean allowOneToMany() { + return true; + } + + /** + * Configures multiple connection behavior for many-to-1 connections. The + * default is allow. + */ + protected boolean allowManyToOne() { + return true; + } + + /** + * Allows internal feedback connection. The default is disallow. + */ + protected boolean allowInternalFeedback() { + return false; + } +} diff --git a/org.fortiss.tooling.base.ui/trunk/src/org/fortiss/tooling/base/ui/compose/HierarchicElementConnectionCompositorBase.java b/org.fortiss.tooling.base.ui/trunk/src/org/fortiss/tooling/base/ui/compose/HierarchicElementConnectionCompositorBase.java index 3f25e0791e336f768d65b4b6fa18471a9e791113..d13947521d12123c74dd8edc185426f7d1291bc1 100644 --- a/org.fortiss.tooling.base.ui/trunk/src/org/fortiss/tooling/base/ui/compose/HierarchicElementConnectionCompositorBase.java +++ b/org.fortiss.tooling.base.ui/trunk/src/org/fortiss/tooling/base/ui/compose/HierarchicElementConnectionCompositorBase.java @@ -26,6 +26,7 @@ import org.fortiss.tooling.base.ui.dnd.DragContext; import org.fortiss.tooling.base.ui.dnd.DropContext; import org.fortiss.tooling.base.ui.editpart.RootEditPartBase; import org.fortiss.tooling.kernel.interfaces.IConnectionCompositionContext; +import org.fortiss.tooling.kernel.interfaces.IConnectionCompositor; import org.fortiss.tooling.kernel.services.ICompositorService; /** @@ -57,7 +58,7 @@ import org.fortiss.tooling.kernel.services.ICompositorService; * @ConQAT.Rating RED Hash: */ public abstract class HierarchicElementConnectionCompositorBase<HE extends IHierarchicElement, S extends IHierarchicElement, T extends IHierarchicElement> - implements org.fortiss.tooling.kernel.interfaces.IConnectionCompositor<S, T> { + implements IConnectionCompositor<S, T> { /** * Determines whether connectors of the component may be connected diff --git a/org.fortiss.tooling.base.ui/trunk/src/org/fortiss/tooling/base/ui/editpart/LabeledConnectorEditPartBase.java b/org.fortiss.tooling.base.ui/trunk/src/org/fortiss/tooling/base/ui/editpart/LabeledConnectorEditPartBase.java index 0e18bd88fbddea6f1383d38321070804fa2c58af..bf8500332e5957af7a7b3d5a8b5ec0f4cc667816 100644 --- a/org.fortiss.tooling.base.ui/trunk/src/org/fortiss/tooling/base/ui/editpart/LabeledConnectorEditPartBase.java +++ b/org.fortiss.tooling.base.ui/trunk/src/org/fortiss/tooling/base/ui/editpart/LabeledConnectorEditPartBase.java @@ -175,9 +175,9 @@ public abstract class LabeledConnectorEditPartBase<T extends IConnector & ILayou private List<IConnection> filterConnections(List<IConnection> connections, IHierarchicElement owner) { List<IConnection> result = new ArrayList<IConnection>(); - for (IConnection channel : connections) { - if (channel.eContainer() == owner) { - result.add(channel); + for (IConnection connection : connections) { + if (connection.eContainer() == owner) { + result.add(connection); } } return result; diff --git a/org.fortiss.tooling.base.ui/trunk/src/org/fortiss/tooling/base/ui/editpart/figure/LabeledConnectorFigure.java b/org.fortiss.tooling.base.ui/trunk/src/org/fortiss/tooling/base/ui/editpart/figure/LabeledConnectorFigure.java index 0e309df9864eeccd4dc7c876f151dc99f12c0475..b6655868bdd7120392e2391bd9a5c9e5c6ac56cf 100644 --- a/org.fortiss.tooling.base.ui/trunk/src/org/fortiss/tooling/base/ui/editpart/figure/LabeledConnectorFigure.java +++ b/org.fortiss.tooling.base.ui/trunk/src/org/fortiss/tooling/base/ui/editpart/figure/LabeledConnectorFigure.java @@ -101,7 +101,7 @@ public class LabeledConnectorFigure extends Figure { // compute label size Rectangle labelTextBounds = label.getTextBounds(); Rectangle newBounds = new Rectangle(containerBounds); - newBounds.x += connectorDimension.width; + newBounds.x += connectorDimension.width / 2; newBounds.y += (connectorDimension.height - labelTextBounds.height) / 2; // +1 needed for proper display newBounds.width += 1 + labelTextBounds.width; diff --git a/org.fortiss.tooling.base.ui/trunk/src/org/fortiss/tooling/base/ui/editpart/interfaces/IFreeConnectorEditPart.java b/org.fortiss.tooling.base.ui/trunk/src/org/fortiss/tooling/base/ui/editpart/interfaces/IFreeConnectorEditPart.java new file mode 100644 index 0000000000000000000000000000000000000000..53b0d5b9e4de1d48689773d23c25e6c3ad30ff68 --- /dev/null +++ b/org.fortiss.tooling.base.ui/trunk/src/org/fortiss/tooling/base/ui/editpart/interfaces/IFreeConnectorEditPart.java @@ -0,0 +1,35 @@ +/*--------------------------------------------------------------------------+ +$Id$ +| | +| Copyright 2011 ForTISS GmbH | +| | +| Licensed under the Apache License, Version 2.0 (the "License"); | +| you may not use this file except in compliance with the License. | +| You may obtain a copy of the License at | +| | +| http://www.apache.org/licenses/LICENSE-2.0 | +| | +| Unless required by applicable law or agreed to in writing, software | +| distributed under the License is distributed on an "AS IS" BASIS, | +| WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | +| See the License for the specific language governing permissions and | +| limitations under the License. | ++--------------------------------------------------------------------------*/ +package org.fortiss.tooling.base.ui.editpart.interfaces; + +/** + * This is a marker interface for edit parts, which resemble a free behavior + * like some connector moving freely on the background area of its parent + * element when viewed internally. + * + * <p> + * Edit parts implementing this marker must not implement + * {@link IStickyConnectorEditPart}. + * + * @author $Author$ + * @version $Rev$ + * @ConQAT.Rating RED Hash: + */ +public interface IFreeConnectorEditPart { + // marker interface +} diff --git a/org.fortiss.tooling.base.ui/trunk/src/org/fortiss/tooling/base/ui/editpart/interfaces/IStickyConnectorEditPart.java b/org.fortiss.tooling.base.ui/trunk/src/org/fortiss/tooling/base/ui/editpart/interfaces/IStickyConnectorEditPart.java new file mode 100644 index 0000000000000000000000000000000000000000..7d07fcfe1a5fcb52aae395ffbcc9bf40e6e20093 --- /dev/null +++ b/org.fortiss.tooling.base.ui/trunk/src/org/fortiss/tooling/base/ui/editpart/interfaces/IStickyConnectorEditPart.java @@ -0,0 +1,36 @@ +/*--------------------------------------------------------------------------+ +$Id$ +| | +| Copyright 2011 ForTISS GmbH | +| | +| Licensed under the Apache License, Version 2.0 (the "License"); | +| you may not use this file except in compliance with the License. | +| You may obtain a copy of the License at | +| | +| http://www.apache.org/licenses/LICENSE-2.0 | +| | +| Unless required by applicable law or agreed to in writing, software | +| distributed under the License is distributed on an "AS IS" BASIS, | +| WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | +| See the License for the specific language governing permissions and | +| limitations under the License. | ++--------------------------------------------------------------------------*/ +package org.fortiss.tooling.base.ui.editpart.interfaces; + +/** + * This is a marker interface for edit parts, which resemble a sticky behavior + * like some connector moving only on the border of its parent element when + * viewed externally. + * + * <p> + * Edit parts implementing this marker must not implement + * {@link IFreeConnectorEditPart}. + * + * @author hoelzl + * @author $Author$ + * @version $Rev$ + * @ConQAT.Rating RED Hash: + */ +public interface IStickyConnectorEditPart { + // marker interface +} diff --git a/org.fortiss.tooling.base.ui/trunk/src/org/fortiss/tooling/base/ui/layout/constants/RecommendedLayoutConstants.java b/org.fortiss.tooling.base.ui/trunk/src/org/fortiss/tooling/base/ui/layout/constants/RecommendedLayoutConstants.java index 2ff8c848e9a8b5adad6450b676ced9c563805469..224dbdef60c7d09aacb9d4166a7b6a1a23841aa9 100644 --- a/org.fortiss.tooling.base.ui/trunk/src/org/fortiss/tooling/base/ui/layout/constants/RecommendedLayoutConstants.java +++ b/org.fortiss.tooling.base.ui/trunk/src/org/fortiss/tooling/base/ui/layout/constants/RecommendedLayoutConstants.java @@ -67,7 +67,7 @@ public final class RecommendedLayoutConstants { public static final int RECTANGULAR_SHAPE_MINIMUM_HEIGHT = 6 * GRID_SIZE; // connector default constants - /** The size of a rectangular connector. */ + /** The size of a default connector. */ public static final int DEFAULT_CONNECTOR_SIZE = 2 * GRID_SIZE; /** Dimension used for rectangular connector. */ diff --git a/org.fortiss.tooling.base/trunk/META-INF/MANIFEST.MF b/org.fortiss.tooling.base/trunk/META-INF/MANIFEST.MF index cc9f271778727ab39a83f3b57d27837c5a11ffec..851edabd629286c06bb3c681b3bdee9c8fdfc7ff 100644 --- a/org.fortiss.tooling.base/trunk/META-INF/MANIFEST.MF +++ b/org.fortiss.tooling.base/trunk/META-INF/MANIFEST.MF @@ -10,6 +10,9 @@ Bundle-RequiredExecutionEnvironment: JavaSE-1.6 Require-Bundle: org.fortiss.tooling.kernel;bundle-version="0.0.1";visibility:=reexport Bundle-ActivationPolicy: lazy Export-Package: org.fortiss.tooling.base, + org.fortiss.tooling.base.model.base, + org.fortiss.tooling.base.model.base.impl, + org.fortiss.tooling.base.model.base.util, org.fortiss.tooling.base.model.element, org.fortiss.tooling.base.model.element.impl, org.fortiss.tooling.base.model.element.util, diff --git a/org.fortiss.tooling.base/trunk/model/base.ecore b/org.fortiss.tooling.base/trunk/model/base.ecore index 2d68d7afda47a0aeaa3ff7c0d28a5ae53ac4ba4b..da60f80ef1965a30303f45dd74e40f9f83a112df 100644 --- a/org.fortiss.tooling.base/trunk/model/base.ecore +++ b/org.fortiss.tooling.base/trunk/model/base.ecore @@ -234,4 +234,17 @@ </eAnnotations> </eClassifiers> </eSubpackages> + <eSubpackages name="base" nsURI="http://www.fortiss.org/af3/micro/base" nsPrefix="org-fortiss-af3-micro-base"> + <eClassifiers xsi:type="ecore:EClass" name="HierarchicElementBase" abstract="true" + eSuperTypes="../../org.fortiss.tooling.kernel/model/kernel.ecore#//INamedCommentedElement #//element/IHierarchicElement #//layout/ILayoutedModelElement"/> + <eClassifiers xsi:type="ecore:EClass" name="ConnectorBase" abstract="true" eSuperTypes="../../org.fortiss.tooling.kernel/model/kernel.ecore#//INamedCommentedElement #//element/IConnector #//layout/ILayoutedModelElement"/> + <eClassifiers xsi:type="ecore:EClass" name="EntryConnectorBase" abstract="true" + eSuperTypes="#//base/ConnectorBase"/> + <eClassifiers xsi:type="ecore:EClass" name="ExitConnectorBase" abstract="true" + eSuperTypes="#//base/ConnectorBase"/> + <eClassifiers xsi:type="ecore:EClass" name="LocalConnectorBase" abstract="true" + eSuperTypes="#//base/ConnectorBase"/> + <eClassifiers xsi:type="ecore:EClass" name="ConnectionSegmentBase" abstract="true" + eSuperTypes="../../org.fortiss.tooling.kernel/model/kernel.ecore#//INamedCommentedElement #//element/IConnection #//layout/ILayoutedModelElement"/> + </eSubpackages> </ecore:EPackage> diff --git a/org.fortiss.tooling.base/trunk/model/base.genmodel b/org.fortiss.tooling.base/trunk/model/base.genmodel index e7ef163a39a92c66d9830c12dde684242bfa0015..39ca72659b9e3e5b7c18eadb27f773222f74f10f 100644 --- a/org.fortiss.tooling.base/trunk/model/base.genmodel +++ b/org.fortiss.tooling.base/trunk/model/base.genmodel @@ -3,7 +3,8 @@ xmlns:xmi="http://www.omg.org/XMI" xmlns:ecore="http://www.eclipse.org/emf/2002/Ecore" xmlns:genmodel="http://www.eclipse.org/emf/2002/GenModel" modelDirectory="/org.fortiss.tooling.base/generated-src" modelPluginID="org.fortiss.tooling.base" modelName="Base" importerID="org.eclipse.emf.importer.ecore" - containmentProxies="true" arrayAccessors="true" complianceLevel="6.0" copyrightFields="false"> + containmentProxies="true" arrayAccessors="true" complianceLevel="6.0" copyrightFields="false" + usedGenPackages="platform:/plugin/org.fortiss.tooling.kernel/model/kernel.genmodel#//model"> <foreignModel>base.ecore</foreignModel> <genPackages prefix="Base" basePackage="org.fortiss.tooling.base" disposableProviderFactory="true" ecorePackage="base.ecore#/"> @@ -77,5 +78,14 @@ </genClasses> <genClasses ecoreClass="base.ecore#//layout/OffsetOrientation"/> </nestedGenPackages> + <nestedGenPackages prefix="Base" basePackage="org.fortiss.tooling.base.model" + disposableProviderFactory="true" ecorePackage="base.ecore#//base"> + <genClasses image="false" ecoreClass="base.ecore#//base/HierarchicElementBase"/> + <genClasses image="false" ecoreClass="base.ecore#//base/ConnectorBase"/> + <genClasses image="false" ecoreClass="base.ecore#//base/EntryConnectorBase"/> + <genClasses image="false" ecoreClass="base.ecore#//base/ExitConnectorBase"/> + <genClasses image="false" ecoreClass="base.ecore#//base/LocalConnectorBase"/> + <genClasses image="false" ecoreClass="base.ecore#//base/ConnectionSegmentBase"/> + </nestedGenPackages> </genPackages> </genmodel:GenModel>