/* * DBeaver - Universal Database Manager * Copyright (C) 2010-2017 Serge Rider (serge@jkiss.org) * * 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. */ /* * Created on Jul 15, 2004 */ package org.jkiss.dbeaver.ext.erd.part; import org.eclipse.draw2d.IFigure; import org.eclipse.gef.ConnectionEditPart; import org.eclipse.gef.EditPart; import org.eclipse.gef.GraphicalEditPart; import org.eclipse.gef.editparts.AbstractGraphicalEditPart; import org.jkiss.code.NotNull; import org.jkiss.dbeaver.ext.erd.model.ERDObject; import org.jkiss.dbeaver.model.DBPNamedObject; import java.beans.PropertyChangeEvent; import java.beans.PropertyChangeListener; import java.util.Iterator; import java.util.List; /** * An abstract EditPart implementation which is property aware and responds to * PropertyChangeEvents fired from the model * @author Serge Rider */ public abstract class PropertyAwarePart extends AbstractGraphicalEditPart implements PropertyChangeListener, DBPNamedObject { @NotNull @Override public String getName() { return ((ERDObject)getModel()).getName(); } protected boolean isEditEnabled() { return getParent() instanceof DiagramPart && ((DiagramPart) getParent()).getDiagram().isLayoutManualAllowed(); } @Override public void activate() { super.activate(); ERDObject<?> erdObject = (ERDObject<?>) getModel(); erdObject.addPropertyChangeListener(this); } @Override public void deactivate() { super.deactivate(); ERDObject<?> erdObject = (ERDObject<?>) getModel(); erdObject.removePropertyChangeListener(this); } @Override public void propertyChange(PropertyChangeEvent evt) { String property = evt.getPropertyName(); if (ERDObject.CHILD.equals(property)) { handleChildChange(evt); } if (ERDObject.REORDER.equals(property)) { handleReorderChange(evt); } else if (ERDObject.OUTPUT.equals(property)) { handleOutputChange(evt); } else if (ERDObject.INPUT.equals(property)) { handleInputChange(evt); } else if (ERDObject.NAME.equals(property)) { commitNameChange(evt); } //we want direct edit name changes to update immediately //not use the Graph animation, if automatic layout is being used if (ERDObject.NAME.equals(property)) { GraphicalEditPart graphicalEditPart = (GraphicalEditPart) (getViewer().getContents()); IFigure partFigure = graphicalEditPart.getFigure(); partFigure.getUpdateManager().performUpdate(); } } /** * Called when change to one of the inputs occurs */ private void handleInputChange(PropertyChangeEvent evt) { //this works but is not efficient //refreshTargetConnections(); //a more efficient implementation should either remove or add the //relevant target connection //using the removeTargetConnection(ConnectionEditPart connection) or //addTargetConnection(ConnectionEditPart connection, int index) Object newValue = evt.getNewValue(); Object oldValue = evt.getOldValue(); if (!((oldValue != null) ^ (newValue != null))) { throw new IllegalStateException("Exactly one of old or new values must be non-null for INPUT event"); } if (newValue != null) { //add new connection ConnectionEditPart editPart = createOrFindConnection(newValue); int modelIndex = getModelTargetConnections().indexOf(newValue); addTargetConnection(editPart, modelIndex); } else { //remove connection List<?> children = getTargetConnections(); ConnectionEditPart partToRemove = null; for (Iterator<?> iter = children.iterator(); iter.hasNext();) { ConnectionEditPart part = (ConnectionEditPart) iter.next(); if (part.getModel() == oldValue) { partToRemove = part; break; } } if (partToRemove != null) removeTargetConnection(partToRemove); } getContentPane().revalidate(); } /** * Called when change to one of the outputs occurs */ private void handleOutputChange(PropertyChangeEvent evt) { //this works but is not efficient //refreshSourceConnections(); // a more efficient implementation should either remove or add the // relevant target connect //using the removeSourceConnection(ConnectionEditPart connection) or //addSourceConnection(ConnectionEditPart connection, int index) Object newValue = evt.getNewValue(); Object oldValue = evt.getOldValue(); if (!((oldValue != null) ^ (newValue != null))) { throw new IllegalStateException("Exactly one of old or new values must be non-null for INPUT event"); } if (newValue != null) { //add new connection ConnectionEditPart editPart = createOrFindConnection(newValue); int modelIndex = getModelSourceConnections().indexOf(newValue); addSourceConnection(editPart, modelIndex); } else { //remove connection List<?> children = getSourceConnections(); ConnectionEditPart partToRemove = null; for (Iterator<?> iter = children.iterator(); iter.hasNext();) { ConnectionEditPart part = (ConnectionEditPart) iter.next(); if (part.getModel() == oldValue) { partToRemove = part; break; } } if (partToRemove != null) removeSourceConnection(partToRemove); } getContentPane().revalidate(); } /** * called when child added or removed */ protected void handleChildChange(PropertyChangeEvent evt) { //we could do this but it is not very efficient //refreshChildren(); Object newValue = evt.getNewValue(); Object oldValue = evt.getOldValue(); if (!((oldValue != null) ^ (newValue != null))) { throw new IllegalStateException("Exactly one of old or new values must be non-null for CHILD event"); } if (newValue != null) { //add new child EditPart editPart = createChild(newValue); int modelIndex = getModelChildren().indexOf(newValue); addChild(editPart, modelIndex); } else { List<?> children = getChildren(); EditPart partToRemove = null; for (Iterator<?> iter = children.iterator(); iter.hasNext();) { EditPart part = (EditPart) iter.next(); if (part.getModel() == oldValue) { partToRemove = part; break; } } if (partToRemove != null) removeChild(partToRemove); } //getContentPane().revalidate(); } /** * Called when columns are re-ordered within */ protected void handleReorderChange(PropertyChangeEvent evt) { refreshChildren(); refreshVisuals(); } protected void commitNameChange(PropertyChangeEvent evt) { } }