Skip to content
Snippets Groups Projects
Commit 54874a29 authored by Tiziano Munaro's avatar Tiziano Munaro
Browse files

Merge remote-tracking branch 'origin/master' into 3437

parents 4a97452c 54ab765a
No related branches found
No related tags found
1 merge request!823437
Showing
with 1124 additions and 3 deletions
......@@ -24,6 +24,7 @@ Export-Package: org.fortiss.tooling.base.ui,
org.fortiss.tooling.base.ui.dnd.jface,
org.fortiss.tooling.base.ui.editor,
org.fortiss.tooling.base.ui.editor.annotations,
org.fortiss.tooling.base.ui.editor.fx,
org.fortiss.tooling.base.ui.editpart,
org.fortiss.tooling.base.ui.editpart.allocation,
org.fortiss.tooling.base.ui.editpart.command,
......
ContextMenuUtil.java 3e04dbd52ee99a59735d39b4087c55b07fb91076 GREEN
EObjectBasedDiagramControllerBase.java b25bbbaa6eef3878b9aea73ca67d66de9beebb18 GREEN
EObjectBasedRectangularResizableContentControllerBase.java a263a6c123ee96015e0a5c37b6e3c13ebd0e8a75 GREEN
HierarchicModelElementModelChangeProvider.java 05217577a99d78038763bbcd841a032bb84f0553 GREEN
KernelServiceBasedModelChangeProviderBase.java 7c30347fb0c7cc4aacc79aeaf85167872afc1958 GREEN
LayoutModelElementModelChangeProvider.java 70c50b789c0088a7e5363bf662bc707a5b5ddf10 GREEN
LayoutedModelElementBasedContentAnchorageController.java c4dfb9dbcd16078c63321d5dec13a902e4088949 GREEN
LayoutedModelElementBasedDiagramAnchorageController.java 8e66f7d8207d2b6a03abaa151f94b51449ad66c7 GREEN
LayoutedModelElementBasedLinkBendPointController.java eb00b6119c02199b53b1a8e3cee2687f835b727c GREEN
/*-------------------------------------------------------------------------+
| Copyright 2019 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.editor.fx;
import static org.fortiss.tooling.base.utils.LayoutModelElementFactory.createPoint;
import java.util.ArrayList;
import java.util.List;
import org.eclipse.emf.ecore.EObject;
import org.eclipse.systemfocus.kernel.common.ui.javafx.lwfxef.DiagramViewer;
import org.eclipse.systemfocus.kernel.common.ui.javafx.lwfxef.DiagramViewerFeatures;
import org.fortiss.tooling.base.dnd.ElementDropContext;
import org.fortiss.tooling.base.model.layout.Point;
import org.fortiss.tooling.kernel.extension.data.IElementCompositionContext;
import org.fortiss.tooling.kernel.extension.data.Prototype;
import org.fortiss.tooling.kernel.service.ICommandStackService;
import org.fortiss.tooling.kernel.service.IElementCompositorService;
import org.fortiss.tooling.kernel.service.IPrototypeService;
import javafx.scene.control.Menu;
import javafx.scene.control.MenuItem;
/**
* Helper class for creating context menus.
*
* @author hoelzl
*/
final class ContextMenuUtil {
/** Creates the menu populated with composable prototypes. */
public static List<MenuItem> createPrototypeMenu(EObject target,
IElementCompositionContext context) {
IPrototypeService pers = IPrototypeService.getInstance();
IElementCompositorService ecs = IElementCompositorService.getInstance();
ICommandStackService css = ICommandStackService.getInstance();
List<MenuItem> result = new ArrayList<>();
Menu newMenu = new Menu("New ...");
List<Prototype> protos = pers.getComposablePrototypes(target.getClass());
for(Prototype p : protos) {
EObject prototypeCopy = p.getPrototypeCopy();
if(ecs.canCompose(target, prototypeCopy, context)) {
MenuItem mi = new MenuItem(p.getName());
mi.setOnAction(evt -> {
css.runAsCommand(target, () -> {
ecs.compose(target, prototypeCopy, context);
});
});
newMenu.getItems().add(mi);
}
}
if(!newMenu.getItems().isEmpty()) {
result.add(newMenu);
}
return result;
}
/** Creates the element composition context. */
public static IElementCompositionContext createElementCompositionContext(EObject target,
double x, double y, boolean isRoot, double zoom) {
Point loc = createPoint((int)x, (int)y, "CompositionPoint");
return new ElementDropContext(target, loc, isRoot, zoom);
}
/** Returns the default display menu for interaction with diagram viewer features. */
public static Menu createDisplayMenu(DiagramViewer viewer) {
Menu menu = new Menu("Display ...");
DiagramViewerFeatures features = viewer.getFeatures();
// link highlighting
if(features.isLinkHighlightingEnabled()) {
MenuItem disableLinkHighlighting = new MenuItem("Disable Link Highlighting");
disableLinkHighlighting.setOnAction(evt -> {
features.setLinkHighlightingEnabled(false);
});
menu.getItems().add(disableLinkHighlighting);
} else {
MenuItem enableLinkHighlighting = new MenuItem("Enable Link Highlighting");
enableLinkHighlighting.setOnAction(evt -> {
features.setLinkHighlightingEnabled(true);
});
menu.getItems().add(enableLinkHighlighting);
}
// interaction area shading
if(features.isInteractionAreaShadingEnabled()) {
MenuItem disableInteractionShading = new MenuItem("Disable Interactive Area Shading");
disableInteractionShading.setOnAction(evt -> {
features.setInteractionAreaShadingEnabled(false);
});
menu.getItems().add(disableInteractionShading);
} else {
MenuItem enableInteractionShading = new MenuItem("Enable Interactive Area Shading");
enableInteractionShading.setOnAction(evt -> {
features.setInteractionAreaShadingEnabled(true);
});
menu.getItems().add(enableInteractionShading);
}
return menu;
}
}
/*******************************************************************************
* Copyright (c) 2017, 2018 fortiss GmbH.
*
* This program and the accompanying materials are made available under the
* terms of the Eclipse Public License v2.0 which is available at
* http://www.eclipse.org/legal/epl-v20.html
*
* SPDX-License-Identifier: EPL-2.0
*
* Contributors:
* Florian Hoelzl (fortiss GmbH) - initial implementation
*
*******************************************************************************/
package org.fortiss.tooling.base.ui.editor.fx;
import static java.lang.Math.max;
import static org.fortiss.tooling.base.ui.editor.fx.ContextMenuUtil.createDisplayMenu;
import static org.fortiss.tooling.base.ui.editor.fx.ContextMenuUtil.createElementCompositionContext;
import static org.fortiss.tooling.base.ui.editor.fx.ContextMenuUtil.createPrototypeMenu;
import java.util.List;
import org.eclipse.emf.ecore.EObject;
import org.eclipse.systemfocus.kernel.common.ui.javafx.lwfxef.DiagramCoordinate;
import org.eclipse.systemfocus.kernel.common.ui.javafx.lwfxef.DiagramViewerFeatures;
import org.eclipse.systemfocus.kernel.common.ui.javafx.lwfxef.controller.base.ControllerBase;
import org.eclipse.systemfocus.kernel.common.ui.javafx.lwfxef.model.IModelChangeProvider;
import org.eclipse.systemfocus.kernel.common.ui.javafx.lwfxef.mvc.IMVCBundle;
import org.fortiss.tooling.base.model.element.IHierarchicElement;
import org.fortiss.tooling.kernel.extension.data.IElementCompositionContext;
import org.fortiss.tooling.kernel.service.IElementCompositorService;
import org.fortiss.tooling.kernel.ui.service.IContextMenuService;
import javafx.scene.Node;
import javafx.scene.control.MenuItem;
/**
* Diagram controller that uses the {@link IElementCompositorService} to create context menu
* entries for prototypes provided by the {@link IContextMenuService}.
*
* @author hoelzl
*/
public abstract class EObjectBasedDiagramControllerBase extends ControllerBase {
/** The model change provider. */
private final HierarchicModelElementModelChangeProvider modelChangeProvider;
/** Constructor. */
public EObjectBasedDiagramControllerBase(IMVCBundle mvcb) {
super(mvcb);
if(!(getModel() instanceof IHierarchicElement)) {
throw new IllegalArgumentException(
"Model element must be an instance of an IHierarchicElement.");
}
this.modelChangeProvider =
new HierarchicModelElementModelChangeProvider(getHierarchicElement());
}
/** {@inheritDoc} */
@Override
public IModelChangeProvider getModelChangeProvider() {
return modelChangeProvider;
}
/** Returns the {@link IHierarchicElement} model element. */
protected IHierarchicElement getHierarchicElement() {
// wild cast works: see constructor check with exception
return (IHierarchicElement)getModel();
}
/** {@inheritDoc} */
@Override
public List<MenuItem> contextMenuContributions(Node node, DiagramCoordinate diagramLocation) {
// outer-most grid areas of the diagram are inaccessible
DiagramViewerFeatures features = getViewer().getFeatures();
double x = max(features.getHorizontalSpacing(), diagramLocation.getX());
double y = max(features.getVerticalSpacing(), diagramLocation.getY());
// wild cast works: see constructor exception
EObject modelParent = getHierarchicElement();
IElementCompositionContext edc = createElementCompositionContext(modelParent, x, y, true,
getViewer().getFeatures().getCurrentZoomFactor());
List<MenuItem> result = createPrototypeMenu(modelParent, edc);
result.add(createDisplayMenu(getViewer()));
return result;
}
}
/*******************************************************************************
* Copyright (c) 2017, 2018 fortiss GmbH.
*
* This program and the accompanying materials are made available under the
* terms of the Eclipse Public License v2.0 which is available at
* http://www.eclipse.org/legal/epl-v20.html
*
* SPDX-License-Identifier: EPL-2.0
*
* Contributors:
* Florian Hoelzl (fortiss GmbH) - initial implementation
*
*******************************************************************************/
package org.fortiss.tooling.base.ui.editor.fx;
import static java.lang.Math.max;
import static org.fortiss.tooling.base.ui.editor.fx.ContextMenuUtil.createElementCompositionContext;
import static org.fortiss.tooling.base.ui.editor.fx.ContextMenuUtil.createPrototypeMenu;
import java.util.List;
import org.eclipse.emf.common.notify.Notification;
import org.eclipse.emf.ecore.EObject;
import org.eclipse.systemfocus.kernel.common.ui.javafx.lwfxef.DiagramCoordinate;
import org.eclipse.systemfocus.kernel.common.ui.javafx.lwfxef.DiagramViewerFeatures;
import org.eclipse.systemfocus.kernel.common.ui.javafx.lwfxef.change.Change;
import org.eclipse.systemfocus.kernel.common.ui.javafx.lwfxef.controller.IClickController;
import org.eclipse.systemfocus.kernel.common.ui.javafx.lwfxef.controller.base.ClickControllerBase;
import org.eclipse.systemfocus.kernel.common.ui.javafx.lwfxef.controller.rectangular.RectangularResizableContentControllerBase;
import org.eclipse.systemfocus.kernel.common.ui.javafx.lwfxef.model.IModelChangeProvider;
import org.eclipse.systemfocus.kernel.common.ui.javafx.lwfxef.mvc.IContentMVCBundle;
import org.fortiss.tooling.base.model.element.ElementPackage;
import org.fortiss.tooling.base.model.layout.ILayoutedModelElement;
import org.fortiss.tooling.kernel.extension.data.IElementCompositionContext;
import org.fortiss.tooling.kernel.service.IElementCompositorService;
import org.fortiss.tooling.kernel.ui.extension.IModelElementHandler;
import org.fortiss.tooling.kernel.ui.service.IModelEditorBindingService;
import org.fortiss.tooling.kernel.ui.service.IModelElementHandlerService;
import javafx.scene.Node;
import javafx.scene.control.MenuItem;
import javafx.scene.input.MouseEvent;
/**
* {@link RectangularResizableContentControllerBase} with a listener mechanism for the layout of the
* connected {@link EObject model element}.
*
* @author hoelzl
*/
public abstract class EObjectBasedRectangularResizableContentControllerBase
extends RectangularResizableContentControllerBase {
/** {@link IModelChangeProvider} for this controller */
private final LayoutModelElementModelChangeProvider layoutModelChangeProvider;
/** The click controller handling double-click to open editor. */
private final IClickController openEditorDoubleClickController = new ClickControllerBase() {
@Override
public Change singleClick(MouseEvent event, Node node, DiagramCoordinate diagramLocation) {
return EObjectBasedRectangularResizableContentControllerBase.super.getClickController(
node, diagramLocation).singleClick(event, node, diagramLocation);
}
@Override
public Change secondaryClick(MouseEvent event, Node node,
DiagramCoordinate diagramLocation) {
return EObjectBasedRectangularResizableContentControllerBase.super.getClickController(
node, diagramLocation).secondaryClick(event, node, diagramLocation);
}
@Override
public Change doubleClick(MouseEvent event, Node node, DiagramCoordinate diagramLocation) {
EObject eo = getLayoutedME();
IModelElementHandler<EObject> handler =
IModelElementHandlerService.getInstance().getModelElementHandler(eo);
if(handler != null) {
eo = handler.handleOpenModelElementRequest(eo);
}
IModelEditorBindingService.getInstance().openInEditor(eo);
return null; // no changes to model
}
};
/** Constructor. */
public EObjectBasedRectangularResizableContentControllerBase(IContentMVCBundle mvcb) {
super(mvcb);
if(!(mvcb.getModel() instanceof ILayoutedModelElement)) {
throw new IllegalArgumentException(
"Model element must be an instance of an ILayoutedModelElement.");
}
ILayoutedModelElement lme = (ILayoutedModelElement)mvcb.getModel();
this.layoutModelChangeProvider = new LayoutModelElementModelChangeProvider(lme) {
/** {@inheritDoc} */
@Override
protected boolean acceptNotification(Notification notification) {
if(notification.getNotifier() != getLayoutedME()) {
return false;
}
return isAnchorageFeature(notification.getFeature());
}
};
}
/** Returns the {@link ILayoutedModelElement} model element. */
protected ILayoutedModelElement getLayoutedME() {
// wild cast works: see constructor check with exception
return (ILayoutedModelElement)getModel();
}
/** {@inheritDoc} */
@Override
public IModelChangeProvider getModelChangeProvider() {
return layoutModelChangeProvider;
}
/** {@inheritDoc} */
@Override
public List<MenuItem> contextMenuContributions(Node node, DiagramCoordinate diagramLocation) {
// outer-most grid areas of the diagram are inaccessible
DiagramViewerFeatures features = getViewer().getFeatures();
double x = max(features.getHorizontalSpacing(), diagramLocation.getX());
double y = max(features.getVerticalSpacing(), diagramLocation.getY());
// wild cast works: see constructor exception
EObject modelParent = (EObject)getModel();
IElementCompositionContext edc = createElementCompositionContext(modelParent, x, y, false,
getViewer().getFeatures().getCurrentZoomFactor());
return createPrototypeMenu(modelParent, edc);
}
/** {@inheritDoc} */
@Override
public void delete() {
IElementCompositorService.getInstance().decompose(getLayoutedME());
}
/** Checks whether the given feature corresponds to an anchorage model element. */
protected boolean isAnchorageFeature(Object feature) {
return feature == ElementPackage.Literals.IHIERARCHIC_ELEMENT__CONNECTORS;
}
/** {@inheritDoc} */
@Override
public IClickController getClickController(Node node, DiagramCoordinate diagramLocation) {
return openEditorDoubleClickController;
}
}
/*-------------------------------------------------------------------------+
| Copyright 2019 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.editor.fx;
import org.eclipse.emf.common.notify.Adapter;
import org.eclipse.emf.common.notify.Notification;
import org.eclipse.emf.common.notify.impl.AdapterImpl;
import org.fortiss.tooling.base.model.element.IHierarchicElement;
/**
* An {@link KernelServiceBasedModelChangeProviderBase} for {@link IHierarchicElement}s.
*
* @author hoelzl
*/
final class HierarchicModelElementModelChangeProvider
extends KernelServiceBasedModelChangeProviderBase<IHierarchicElement> {
/** The model element. */
private final IHierarchicElement modelElement;
/** The EMF notification listener. */
private final HierarchicElementAdapter notificationListener;
/** Constructor. */
public HierarchicModelElementModelChangeProvider(IHierarchicElement modelElement) {
this.modelElement = modelElement;
this.notificationListener = new HierarchicElementAdapter();
}
/** {@inheritDoc} */
@Override
protected IHierarchicElement getModelElement() {
return modelElement;
}
/** {@inheritDoc} */
@Override
protected Adapter getNotificationListener() {
return notificationListener;
}
/** Specialized adapter listening to model changes of {@link IHierarchicElement}. */
private class HierarchicElementAdapter extends AdapterImpl {
/** {@inheritDoc} */
@Override
public void notifyChanged(Notification event) {
addNotification(event);
}
}
}
/*-------------------------------------------------------------------------+
| Copyright 2019 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.editor.fx;
import java.util.ArrayList;
import java.util.EventObject;
import java.util.List;
import org.eclipse.emf.common.command.CommandStackListener;
import org.eclipse.emf.common.notify.Adapter;
import org.eclipse.emf.common.notify.Notification;
import org.eclipse.emf.ecore.EObject;
import org.eclipse.systemfocus.kernel.common.ui.javafx.lwfxef.model.IModelChangeProvider;
import org.eclipse.systemfocus.kernel.common.ui.javafx.lwfxef.model.ModelChangeProviderBase;
import org.fortiss.tooling.kernel.extension.data.ITopLevelElement;
import org.fortiss.tooling.kernel.service.ICommandStackService;
import org.fortiss.tooling.kernel.service.IPersistencyService;
/**
* Base class for {@link IModelChangeProvider}s using kernel services.
*
* @author hoelzl
*/
abstract class KernelServiceBasedModelChangeProviderBase<T extends EObject>
extends ModelChangeProviderBase implements CommandStackListener {
/** The persistency service reference. */
private static final IPersistencyService persistencyService = IPersistencyService.getInstance();
/** The command stack service. */
private static final ICommandStackService commandStackService =
ICommandStackService.getInstance();
/** List of relevant {@link Notification}s recorded during a change transaction. */
private final List<Notification> notifications = new ArrayList<>();
/** Returns the model element. */
protected abstract T getModelElement();
/** Returns the EMF notification listener. */
protected abstract Adapter getNotificationListener();
/** Adds the given {@link Notification} to list of notifications. */
protected final void addNotification(Notification event) {
notifications.add(event);
}
/** {@inheritDoc} */
@Override
protected final void connectToModel() {
notifications.clear();
T modelElement = getModelElement();
Adapter notificationListener = getNotificationListener();
ITopLevelElement root = persistencyService.getTopLevelElementFor(modelElement);
commandStackService.addCommandStackListener(root, this);
modelElement.eAdapters().add(notificationListener);
}
/** {@inheritDoc} */
@Override
protected final void disconnectFromModel() {
T modelElement = getModelElement();
Adapter notificationListener = getNotificationListener();
modelElement.eAdapters().remove(notificationListener);
ITopLevelElement root = persistencyService.getTopLevelElementFor(modelElement);
commandStackService.removeCommandStackListener(root, this);
notifications.clear();
}
/** {@inheritDoc} */
@Override
public void commandStackChanged(EventObject event) {
if(notifications.isEmpty()) {
return;
}
fireUpdateComplete();
notifications.clear();
}
}
/*-------------------------------------------------------------------------+
| Copyright 2019 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.editor.fx;
import static org.fortiss.tooling.base.model.layout.LayoutPackage.ILAYOUTED_MODEL_ELEMENT__LAYOUT_DATA;
import org.eclipse.emf.common.notify.Adapter;
import org.eclipse.emf.common.notify.Notification;
import org.eclipse.emf.ecore.EObject;
import org.eclipse.emf.ecore.util.EContentAdapter;
import org.fortiss.tooling.base.model.layout.ILayoutData;
import org.fortiss.tooling.base.model.layout.ILayoutedModelElement;
import org.fortiss.tooling.base.model.layout.LayoutPackage;
/**
* An {@link KernelServiceBasedModelChangeProviderBase} for {@link ILayoutedModelElement}s.
*
* @author hoelzl
*/
class LayoutModelElementModelChangeProvider
extends KernelServiceBasedModelChangeProviderBase<ILayoutedModelElement> {
/** The layouted model element. */
private final ILayoutedModelElement modelElement;
/** The layout EMF notification listener. */
private final LayoutModelElementAdapter notificationListener;
/** Constructor. */
public LayoutModelElementModelChangeProvider(ILayoutedModelElement modelElement) {
this.modelElement = modelElement;
this.notificationListener = new LayoutModelElementAdapter();
}
/** {@inheritDoc} */
@Override
protected ILayoutedModelElement getModelElement() {
return modelElement;
}
/** {@inheritDoc} */
@Override
protected Adapter getNotificationListener() {
return notificationListener;
}
/**
* Checks whether the given notification should be accepted.
*
* @param notification
* the notification
* @return whether the notification should be accepted
*/
protected boolean acceptNotification(Notification notification) {
return false;
}
/** Specific {@link EContentAdapter} listening to layout data changes. */
public class LayoutModelElementAdapter extends EContentAdapter {
/** {@inheritDoc} */
@Override
public void notifyChanged(Notification notification) {
if(acceptNotification(notification)) {
addNotification(notification);
return;
}
Object notifier = notification.getNotifier();
if(notifier == modelElement) {
Object feature = notification.getFeature();
if(feature == LayoutPackage.Literals.ILAYOUTED_MODEL_ELEMENT__LAYOUT_DATA) {
// self adapt to layout data
super.notifyChanged(notification);
addNotification(notification);
return;
}
} else if(notifier instanceof ILayoutData) {
// self adapt to layout data
super.notifyChanged(notification);
addNotification(notification);
return;
}
// prevent self-adapt for all other cases
}
/** Called when layout data of the underlying model element changed. */
protected void layoutChanged() {
// default does nothing
}
/** {@inheritDoc} */
@Override
protected void selfAdapt(Notification notification) {
// ignore resources and resource sets
if(notification.getNotifier() instanceof EObject) {
super.selfAdapt(notification);
}
}
/** {@inheritDoc} */
@Override
protected void handleContainment(Notification notification) {
// only adapt to layout data
if(notification.getNotifier() instanceof ILayoutData) {
super.handleContainment(notification);
return;
}
Class<?> instanceClass =
LayoutPackage.Literals.ILAYOUTED_MODEL_ELEMENT.getInstanceClass();
// only adapt to layout data
if(notification.getFeatureID(instanceClass) == ILAYOUTED_MODEL_ELEMENT__LAYOUT_DATA) {
super.handleContainment(notification);
}
}
}
}
/*******************************************************************************
* Copyright (c) 2017, 2018 fortiss GmbH.
*
* This program and the accompanying materials are made available under the
* terms of the Eclipse Public License v2.0 which is available at
* http://www.eclipse.org/legal/epl-v20.html
*
* SPDX-License-Identifier: EPL-2.0
*
* Contributors:
* Florian Hoelzl (fortiss GmbH) - initial implementation
*
*******************************************************************************/
package org.fortiss.tooling.base.ui.editor.fx;
import static org.eclipse.systemfocus.kernel.common.ui.javafx.lwfxef.DiagramViewerDefaultTags.LINK_TARGET_ALLOWED_TAG;
import static org.eclipse.systemfocus.kernel.common.ui.javafx.lwfxef.DiagramViewerDefaultTags.LINK_TARGET_DENIED_TAG;
import org.eclipse.emf.ecore.EObject;
import org.eclipse.systemfocus.kernel.common.ui.javafx.lwfxef.DiagramCoordinate;
import org.eclipse.systemfocus.kernel.common.ui.javafx.lwfxef.controller.base.DelegatingContentAnchorageController;
import org.eclipse.systemfocus.kernel.common.ui.javafx.lwfxef.model.IModelChangeProvider;
import org.eclipse.systemfocus.kernel.common.ui.javafx.lwfxef.mvc.IContentAnchorageMVCBundle;
import org.eclipse.systemfocus.kernel.common.ui.javafx.lwfxef.mvc.IMVCBundle;
import org.eclipse.systemfocus.kernel.common.ui.javafx.lwfxef.mvc.MVCBundleTag;
import org.fortiss.tooling.base.model.element.IConnector;
import org.fortiss.tooling.base.model.layout.ILayoutedModelElement;
import org.fortiss.tooling.kernel.service.IConnectionCompositorService;
import org.fortiss.tooling.kernel.service.IElementCompositorService;
/**
* {@link DelegatingContentAnchorageController} for
* {@link org.fortiss.tooling.base.model.layout.ILayoutedModelElement}s.
*
* @author hoelzl
*/
public class LayoutedModelElementBasedContentAnchorageController
extends DelegatingContentAnchorageController {
/** {@link IModelChangeProvider} for this controller */
private final LayoutModelElementModelChangeProvider layoutModelChangeProvider;
/** Constructor. */
public LayoutedModelElementBasedContentAnchorageController(IContentAnchorageMVCBundle mvcb) {
super(mvcb);
if(!(mvcb.getModel() instanceof ILayoutedModelElement)) {
throw new IllegalArgumentException(
"Model element must be an instance of an ILayoutedModelElement.");
}
ILayoutedModelElement lme = (ILayoutedModelElement)mvcb.getModel();
this.layoutModelChangeProvider = new LayoutModelElementModelChangeProvider(lme);
}
/** Returns the model element. */
public ILayoutedModelElement getLayoutedME() {
return (ILayoutedModelElement)getModel();
}
/** {@inheritDoc} */
@Override
public IModelChangeProvider getModelChangeProvider() {
return layoutModelChangeProvider;
}
/** {@inheritDoc} */
@Override
public void delete() {
IElementCompositorService.getInstance().decompose(getLayoutedME());
}
/** {@inheritDoc} */
@Override
protected boolean canLink(IMVCBundle startBundle, DiagramCoordinate startLocation,
IMVCBundle endBundle, DiagramCoordinate endLocation) {
IConnectionCompositorService ccs = IConnectionCompositorService.getInstance();
EObject start = (EObject)startBundle.getModel();
EObject end = (EObject)endBundle.getModel();
EObject root = (EObject)getViewer().getRootElement();
return ccs.canConnect(start, end, root, null);
}
/** {@inheritDoc} */
@Override
protected void link(IMVCBundle startBundle, DiagramCoordinate startLocation,
IMVCBundle endBundle, DiagramCoordinate endLocation) {
EObject start = (EObject)startBundle.getModel();
EObject end = (EObject)endBundle.getModel();
EObject root = (EObject)getViewer().getRootElement();
IConnectionCompositorService.getInstance().connect(start, end, root, null);
}
/** {@inheritDoc} */
@Override
public boolean isPossibleLinkTarget() {
return true;
}
/** {@inheritDoc} */
@Override
public MVCBundleTag getLinkTargetEffectForNewLinkFrom(IMVCBundle linkSourceBundle) {
Object srcModel = linkSourceBundle.getModel();
if(srcModel instanceof ILayoutedModelElement && srcModel instanceof IConnector) {
EObject startModel = (EObject)srcModel;
ILayoutedModelElement endModel = getLayoutedME();
EObject root = (EObject)getViewer().getRootElement();
IConnectionCompositorService srv = IConnectionCompositorService.getInstance();
if(srv.canConnect(startModel, endModel, root, null)) {
return LINK_TARGET_ALLOWED_TAG;
}
}
return LINK_TARGET_DENIED_TAG;
}
}
/*******************************************************************************
* Copyright (c) 2017, 2018 fortiss GmbH.
*
* This program and the accompanying materials are made available under the
* terms of the Eclipse Public License v2.0 which is available at
* http://www.eclipse.org/legal/epl-v20.html
*
* SPDX-License-Identifier: EPL-2.0
*
* Contributors:
* Florian Hoelzl (fortiss GmbH) - initial implementation
*
*******************************************************************************/
package org.fortiss.tooling.base.ui.editor.fx;
import static org.eclipse.systemfocus.kernel.common.ui.javafx.lwfxef.DiagramViewerDefaultTags.LINK_TARGET_ALLOWED_TAG;
import static org.eclipse.systemfocus.kernel.common.ui.javafx.lwfxef.DiagramViewerDefaultTags.LINK_TARGET_DENIED_TAG;
import static org.fortiss.tooling.base.utils.LayoutDataUtils.moveNode;
import org.eclipse.emf.ecore.EObject;
import org.eclipse.systemfocus.kernel.common.ui.javafx.lwfxef.DiagramCoordinate;
import org.eclipse.systemfocus.kernel.common.ui.javafx.lwfxef.FeedbackChange;
import org.eclipse.systemfocus.kernel.common.ui.javafx.lwfxef.controller.base.MoveControllerBase;
import org.eclipse.systemfocus.kernel.common.ui.javafx.lwfxef.model.IModelChangeProvider;
import org.eclipse.systemfocus.kernel.common.ui.javafx.lwfxef.mvc.IMVCBundle;
import org.eclipse.systemfocus.kernel.common.ui.javafx.lwfxef.mvc.MVCBundleTag;
import org.fortiss.tooling.base.model.element.IConnector;
import org.fortiss.tooling.base.model.layout.ILayoutedModelElement;
import org.fortiss.tooling.kernel.service.IConnectionCompositorService;
import org.fortiss.tooling.kernel.service.IElementCompositorService;
/**
* {@link MoveControllerBase} for {@link ILayoutedModelElement}s.
*
* @author hoelzl
*/
public class LayoutedModelElementBasedDiagramAnchorageController extends MoveControllerBase {
/** {@link IModelChangeProvider} for this controller */
private final LayoutModelElementModelChangeProvider layoutModelChangeProvider;
/** Constructor. */
public LayoutedModelElementBasedDiagramAnchorageController(IMVCBundle mvcb) {
super(mvcb);
if(!(mvcb.getModel() instanceof ILayoutedModelElement)) {
throw new IllegalArgumentException(
"Model element must be an instance of an ILayoutedModelElement.");
}
ILayoutedModelElement lme = (ILayoutedModelElement)mvcb.getModel();
this.layoutModelChangeProvider = new LayoutModelElementModelChangeProvider(lme);
}
/** Returns the model element. */
public ILayoutedModelElement getLayoutedME() {
return (ILayoutedModelElement)getModel();
}
/** {@inheritDoc} */
@Override
public IModelChangeProvider getModelChangeProvider() {
return layoutModelChangeProvider;
}
/** {@inheritDoc} */
@Override
public void move(FeedbackChange delta) {
ILayoutedModelElement model = getLayoutedME();
int dx = (int)delta.getDeltaX();
int dy = (int)delta.getDeltaY();
moveNode(model, dx, dy);
}
/** {@inheritDoc} */
@Override
public void delete() {
IElementCompositorService.getInstance().decompose(getLayoutedME());
}
/** {@inheritDoc} */
@Override
protected boolean canLink(IMVCBundle startBundle, DiagramCoordinate startLocation,
IMVCBundle endBundle, DiagramCoordinate endLocation) {
IConnectionCompositorService ccs = IConnectionCompositorService.getInstance();
EObject start = (EObject)startBundle.getModel();
EObject end = (EObject)endBundle.getModel();
EObject root = (EObject)getViewer().getRootElement();
return ccs.canConnect(start, end, root, null);
}
/** {@inheritDoc} */
@Override
protected void link(IMVCBundle startBundle, DiagramCoordinate startLocation,
IMVCBundle endBundle, DiagramCoordinate endLocation) {
EObject start = (EObject)startBundle.getModel();
EObject end = (EObject)endBundle.getModel();
EObject root = (EObject)getViewer().getRootElement();
IConnectionCompositorService.getInstance().connect(start, end, root, null);
}
/** {@inheritDoc} */
@Override
public boolean isPossibleLinkTarget() {
return true;
}
/** {@inheritDoc} */
@Override
public MVCBundleTag getLinkTargetEffectForNewLinkFrom(IMVCBundle linkSourceBundle) {
Object srcModel = linkSourceBundle.getModel();
if(srcModel instanceof ILayoutedModelElement && srcModel instanceof IConnector) {
EObject startModel = (EObject)srcModel;
ILayoutedModelElement endModel = getLayoutedME();
EObject root = (EObject)getViewer().getRootElement();
IConnectionCompositorService srv = IConnectionCompositorService.getInstance();
if(srv.canConnect(startModel, endModel, root, null)) {
return LINK_TARGET_ALLOWED_TAG;
}
}
return LINK_TARGET_DENIED_TAG;
}
}
/*******************************************************************************
* Copyright (c) 2017, 2018 fortiss GmbH.
*
* This program and the accompanying materials are made available under the
* terms of the Eclipse Public License v2.0 which is available at
* http://www.eclipse.org/legal/epl-v20.html
*
* SPDX-License-Identifier: EPL-2.0
*
* Contributors:
* Florian Hoelzl (fortiss GmbH) - initial implementation
*
*******************************************************************************/
package org.fortiss.tooling.base.ui.editor.fx;
import static org.fortiss.tooling.base.ui.utils.LayoutDataUIUtils.addConnectionPoint;
import static org.fortiss.tooling.base.ui.utils.LayoutDataUIUtils.getConnectionPoints;
import static org.fortiss.tooling.base.ui.utils.LayoutDataUIUtils.removeConnectionPoint;
import java.util.List;
import org.eclipse.emf.common.util.EList;
import org.eclipse.systemfocus.kernel.common.ui.javafx.lwfxef.DiagramCoordinate;
import org.eclipse.systemfocus.kernel.common.ui.javafx.lwfxef.DiagramViewer;
import org.eclipse.systemfocus.kernel.common.ui.javafx.lwfxef.controller.IController;
import org.eclipse.systemfocus.kernel.common.ui.javafx.lwfxef.controller.base.LinkControllerBase;
import org.eclipse.systemfocus.kernel.common.ui.javafx.lwfxef.model.IModelChangeProvider;
import org.eclipse.systemfocus.kernel.common.ui.javafx.lwfxef.mvc.ILinkMVCBundle;
import org.eclipse.systemfocus.kernel.common.ui.javafx.lwfxef.mvc.IMVCBundle;
import org.fortiss.tooling.base.model.layout.ILayoutedModelElement;
import org.fortiss.tooling.base.model.layout.Point;
import org.fortiss.tooling.kernel.service.IConnectionCompositorService;
/**
* {@link IController} for {@link ILayoutedModelElement}s representing links and connections in a
* {@link DiagramViewer}.
*
* @author hoelzl
*/
public class LayoutedModelElementBasedLinkBendPointController extends LinkControllerBase {
/** {@link IModelChangeProvider} for this controller */
private final LayoutModelElementModelChangeProvider layoutModelChangeProvider;
/** Constructor. */
public LayoutedModelElementBasedLinkBendPointController(ILinkMVCBundle mvcb) {
super(mvcb);
if(!(mvcb.getModel() instanceof ILayoutedModelElement)) {
throw new IllegalArgumentException(
"Model element must be an instance of an ILayoutedModelElement.");
}
ILayoutedModelElement lme = (ILayoutedModelElement)mvcb.getModel();
this.layoutModelChangeProvider = new LayoutModelElementModelChangeProvider(lme);
}
/** Returns the model element. */
public ILayoutedModelElement getLayoutedME() {
return (ILayoutedModelElement)getModel();
}
/** {@inheritDoc} */
@Override
public IModelChangeProvider getModelChangeProvider() {
return layoutModelChangeProvider;
}
/** {@inheritDoc} */
@Override
protected int getNumerOfBendPoints() {
return getBendPointList(getLayoutedME()).size();
}
/** Returns the list of bend-points. */
private EList<Point> getBendPointList(ILayoutedModelElement modelElement) {
return getConnectionPoints(modelElement).getPoints();
}
/** {@inheritDoc} */
@Override
protected void createBendPointAt(int bpIndex, DiagramCoordinate location) {
int x = (int)location.getX();
int y = (int)location.getY();
addConnectionPoint(getLayoutedME(), bpIndex, x, y);
}
/** {@inheritDoc} */
@Override
protected void updateModelAfterBendPointMove(int bpIndex, double dx, double dy) {
List<Point> oldPoints = getBendPointList(getLayoutedME());
Point point = oldPoints.get(bpIndex);
int oldX = point.getX();
int oldY = point.getY();
int newX = oldX + (int)dx;
int newY = oldY + (int)dy;
point.setX(newX);
point.setY(newY);
}
/** {@inheritDoc} */
@Override
protected void deleteBendPoint(int bpIndex) {
removeConnectionPoint(getLayoutedME(), bpIndex);
}
/** {@inheritDoc} */
@Override
protected void updateModelAfterLinkMove(ILinkMVCBundle linkBundle, IMVCBundle startBundle,
IMVCBundle endBundle) {
// ignored
}
/** {@inheritDoc} */
@Override
protected void deleteLink() {
IConnectionCompositorService.getInstance().disconnect(getLayoutedME());
}
/** {@inheritDoc} */
@Override
public void delete() {
deleteLink();
}
}
......@@ -5,6 +5,7 @@ DragAndDropBaseUtils.java d375377f9124f6113b2a295e6b0e09ac8966e564 GREEN
EllipseLayoutUIUtils.java 4dd9dbd96a45e8c455c019caa19e4a50f18336af GREEN
FontUtils.java a167a05bdaa8da9853705cc5134f30f6d81bc9f2 GREEN
GCStateManager.java 983973a92376b5c757c1253b32e33d0666ccdf7b GREEN
LWFXEditorUtils.java c628e79fa43c1be8a7b87ee90db6e7264904eafc GREEN
LayoutDataUIUtils.java c85886ac313a6efb122532218eb134047ffd6631 GREEN
PropertiesViewUtils.java d345b4501c4092228edf1c98e0189317d53aaf22 GREEN
RectangleLayoutUIUtils.java ef4b872bb5b4a51174e9a29d9ef05e7cb3bff3a1 GREEN
......
/*-------------------------------------------------------------------------+
| Copyright 2019 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.utils;
import static java.lang.Math.atan2;
import static java.lang.Math.cos;
import static java.lang.Math.sin;
import org.eclipse.systemfocus.kernel.common.ui.javafx.lwfxef.DiagramCoordinate;
import org.fortiss.tooling.base.model.layout.EOrientation;
import javafx.geometry.Point2D;
import javafx.geometry.Rectangle2D;
import javafx.geometry.Side;
/**
* Utility methods for the JavaFX-based graphical LWFXEF editors.
*
* @author hoelzl
*/
public final class LWFXEditorUtils {
/** Computes the location of the link w.r.t. the given anchor bounds and target position. */
public static DiagramCoordinate computeLinkToAnchorLocation(Rectangle2D anchorBounds,
DiagramCoordinate target) {
double x = 0;
if(target.getX() < anchorBounds.getMinX()) {
x = -1.0;
} else if(target.getX() > anchorBounds.getMaxX()) {
x = 1.0;
}
double y = 0;
if(target.getY() < anchorBounds.getMinY()) {
y = -1.0;
} else if(target.getY() > anchorBounds.getMaxY()) {
y = 1.0;
}
double w2 = anchorBounds.getWidth() / 2;
double h2 = anchorBounds.getHeight() / 2;
x = anchorBounds.getMinX() + w2 + x * w2;
y = anchorBounds.getMinY() + h2 + y * h2;
return new DiagramCoordinate(x, y);
}
/** Returns the {@link EOrientation} for the given {@link Side}. */
public static EOrientation convertSideToEOrientation(Side s) {
switch(s) {
case TOP:
return EOrientation.NORTH;
case BOTTOM:
return EOrientation.SOUTH;
case LEFT:
return EOrientation.WEST;
case RIGHT:
return EOrientation.EAST;
}
return null;
}
/** Returns the {@link Side} for the given {@link EOrientation}. */
public static Side convertEOrientationToSide(EOrientation eo) {
switch(eo) {
case NORTH:
return Side.TOP;
case SOUTH:
return Side.BOTTOM;
case WEST:
return Side.LEFT;
case EAST:
return Side.RIGHT;
}
return null;
}
/**
* Returns the point on a circle centered in the current bounds intersecting with a line between
* the center point and the given point.
*/
public static DiagramCoordinate computeLinkToCircleLocation(Rectangle2D bounds,
Point2D target) {
double sx = bounds.getMinX() + bounds.getWidth() / 2;
double sy = bounds.getMinY() + bounds.getHeight() / 2;
double a = atan2(target.getY() - sy, target.getX() - sx);
double nx = sx + cos(a) * (bounds.getWidth() / 2 - 1);
double ny = sy + sin(a) * (bounds.getHeight() / 2 - 1);
return new DiagramCoordinate(nx, ny);
}
/** Constructor. */
private LWFXEditorUtils() {
// prevent instantiation
}
}
......@@ -6,6 +6,7 @@ ConstraintsBaseUtils.java bba938b43756ce6f35c338f6cef21c3ab5d49a9d GREEN
DimensionUtils.java 0dc67f9de11a84e6e4c6e1eb627817dee91ff30a GREEN
EllipseLayoutUtils.java 5c3a0126fdca5d5b4fb441694747e1cb0f49cd9f GREEN
LayoutDataUtils.java 5739dd16f0212e8f94927c0a0f51503390f2be69 GREEN
LayoutModelElementAdapter.java d81dfc551baa832f2761b4804760dcd8f57b7c5b YELLOW
LayoutModelElementFactory.java c49fca2de5a8cb7502fb28cc2b7e64a272df11b0 GREEN
MigrationUtils.java ab9d8682233313c21c6a52b8b03e1c796aacd29c GREEN
OffsetOrientationUtils.java 913cebbac2a5628bdd08b4df669b9412d6e07d94 GREEN
......
......@@ -3,6 +3,8 @@
<classpathentry kind="src" path="src"/>
<classpathentry kind="src" path="external-src"/>
<classpathentry kind="src" path="res"/>
<classpathentry exported="true" kind="lib" path="lib/org.eclipse.systemfocus.kernel.common_0.0.4.20191111.jar"/>
<classpathentry exported="true" kind="lib" path="lib/org.eclipse.systemfocus.kernel.common.ui_0.0.4.20191111.jar"/>
<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/JavaSE-11">
<attributes>
<attribute name="module" value="true"/>
......
......@@ -24,8 +24,13 @@ Require-Bundle: org.fortiss.tooling.common;visibility:=reexport,
Bundle-ClassPath: .,
lib/org.conqat.ide.commons.gef.jar,
lib/org.conqat.ide.commons.ui.jar,
lib/swt-grouplayout.jar
Export-Package: org.conqat.ide.commons.gef,
lib/swt-grouplayout.jar,
lib/org.eclipse.systemfocus.kernel.common_0.0.4.20191111.jar,
lib/org.eclipse.systemfocus.kernel.common.ui_0.0.4.20191111.jar
Export-Package: aerofx,
aquafx,
jfxtras,
org.conqat.ide.commons.gef,
org.conqat.ide.commons.gef.directediting,
org.conqat.ide.commons.gef.draw2d,
org.conqat.ide.commons.gef.editor,
......@@ -69,6 +74,25 @@ Export-Package: org.conqat.ide.commons.gef,
org.eclipse.gmf.runtime.draw2d.ui.figures,
org.eclipse.gmf.runtime.draw2d.ui.geometry,
org.eclipse.jface.viewers,
org.eclipse.systemfocus.kernel.common.ui.javafx.control.treetableview,
org.eclipse.systemfocus.kernel.common.ui.javafx.lwfxef,
org.eclipse.systemfocus.kernel.common.ui.javafx.lwfxef.change,
org.eclipse.systemfocus.kernel.common.ui.javafx.lwfxef.controller,
org.eclipse.systemfocus.kernel.common.ui.javafx.lwfxef.controller.base,
org.eclipse.systemfocus.kernel.common.ui.javafx.lwfxef.controller.elliptic,
org.eclipse.systemfocus.kernel.common.ui.javafx.lwfxef.controller.rectangular,
org.eclipse.systemfocus.kernel.common.ui.javafx.lwfxef.model,
org.eclipse.systemfocus.kernel.common.ui.javafx.lwfxef.model.layout,
org.eclipse.systemfocus.kernel.common.ui.javafx.lwfxef.mvc,
org.eclipse.systemfocus.kernel.common.ui.javafx.lwfxef.mvc.impl,
org.eclipse.systemfocus.kernel.common.ui.javafx.lwfxef.visual,
org.eclipse.systemfocus.kernel.common.ui.javafx.lwfxef.visual.base,
org.eclipse.systemfocus.kernel.common.ui.javafx.lwfxef.visual.elliptic,
org.eclipse.systemfocus.kernel.common.ui.javafx.lwfxef.visual.rectangular,
org.eclipse.systemfocus.kernel.common.ui.javafx.lwfxef.visual.widgets,
org.eclipse.systemfocus.kernel.common.ui.javafx.mesh,
org.eclipse.systemfocus.kernel.common.ui.javafx.style,
org.eclipse.systemfocus.kernel.common.ui.javafx.util,
org.eclipse.ui.actions,
org.eclipse.wb.swt,
org.eclipse.wb.swt.layout.grouplayout,
......
......@@ -5,7 +5,9 @@ bin.includes = .,\
lib/org.conqat.ide.commons.gef.jar,\
lib/org.conqat.ide.commons.ui.jar,\
lib/swt-grouplayout.jar,\
res/
res/,\
lib/org.eclipse.systemfocus.kernel.common_0.0.4.20191111.jar,\
lib/org.eclipse.systemfocus.kernel.common.ui_0.0.4.20191111.jar
jars.compile.order = .
source.. = src/,\
res/,\
......
File added
......@@ -5,7 +5,9 @@ EObjectActionBase.java 4ef9f8be59e64d4838acc9e268d418ba5d94fa1a GREEN
EReferenceListPropertySectionBase.java 7390dd7bfdc979e8ff0c5c30c67ab7b6c9d70c92 GREEN
EReferencePropertySectionBase.java 0548da6778516003257f59d0b4c2b60d458be3b6 GREEN
EditorBase.java 9c09fff92945256bb8680992ae7bb2c78f47b150 GREEN
FXEditorBase.java 2e520be0bbae7d0aebdff70218a124dbe0896ce2 GREEN
IListPropertySection.java 8bb00fe7959583e794ff9437b7a77404c9a9e70f GREEN
LWFXEFEditorBase.java 0b8e6af85d83d0542dcd908974e52c618bc22a08 GREEN
ModelEditorBindingBase.java 4c5ac569c0b6e7678fc8191096b26dfd09fdcb98 GREEN
ModelElementHandlerBase.java 384727748f125c9d43f19d9c0eba4ba1be5a7a26 GREEN
MultiEObjectActionBase.java 9e237d8ea640c4194e4877af4a9cfce88698e543 GREEN
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment