package org.insightech.er.editor.controller.editpart.element.node; import java.beans.PropertyChangeEvent; import java.util.List; import org.eclipse.draw2d.ChopboxAnchor; import org.eclipse.draw2d.ColorConstants; import org.eclipse.draw2d.ConnectionAnchor; import org.eclipse.draw2d.IFigure; import org.eclipse.draw2d.geometry.Dimension; import org.eclipse.draw2d.geometry.Point; import org.eclipse.draw2d.geometry.Rectangle; import org.eclipse.gef.ConnectionEditPart; import org.eclipse.gef.EditPart; import org.eclipse.gef.EditPolicy; import org.eclipse.gef.GraphicalEditPart; import org.eclipse.gef.NodeEditPart; import org.eclipse.gef.Request; import org.eclipse.gef.RequestConstants; import org.eclipse.gef.commands.Command; import org.eclipse.gef.editpolicies.SnapFeedbackPolicy; import org.eclipse.gef.requests.CreateConnectionRequest; import org.eclipse.gef.requests.ReconnectRequest; import org.eclipse.swt.graphics.Color; import org.eclipse.swt.graphics.Font; import org.eclipse.swt.graphics.FontData; import org.eclipse.swt.widgets.Display; import org.insightech.er.ERDiagramActivator; import org.insightech.er.Resources; import org.insightech.er.editor.controller.command.diagram_contents.element.connection.CreateCommentConnectionCommand; import org.insightech.er.editor.controller.editpart.DeleteableEditPart; import org.insightech.er.editor.controller.editpart.element.AbstractModelEditPart; import org.insightech.er.editor.controller.editpart.element.connection.AbstractERDiagramConnectionEditPart; import org.insightech.er.editor.controller.editpart.element.node.column.ColumnEditPart; import org.insightech.er.editor.controller.editpolicy.element.node.NodeElementGraphicalNodeEditPolicy; import org.insightech.er.editor.model.ViewableModel; import org.insightech.er.editor.model.diagram_contents.element.connection.ConnectionElement; import org.insightech.er.editor.model.diagram_contents.element.node.Location; import org.insightech.er.editor.model.diagram_contents.element.node.NodeElement; import org.insightech.er.editor.model.diagram_contents.element.node.category.Category; import org.insightech.er.editor.model.diagram_contents.element.node.note.Note; import org.insightech.er.editor.model.diagram_contents.element.node.table.ERTable; import org.insightech.er.editor.model.settings.Settings; import org.insightech.er.editor.model.tracking.ChangeTrackingList; import org.insightech.er.editor.view.figure.anchor.XYChopboxAnchor; import org.insightech.er.editor.view.figure.connection.ERDiagramConnection; import org.insightech.er.util.Check; public abstract class NodeElementEditPart extends AbstractModelEditPart implements NodeEditPart, DeleteableEditPart { private Font font; /** * {@inheritDoc} */ @Override public void deactivate() { super.deactivate(); } @Override public void doPropertyChange(final PropertyChangeEvent event) { if (event.getPropertyName().equals("refreshFont")) { changeFont(figure); refreshVisuals(); } else if (event.getPropertyName().equals("refreshSourceConnections")) { refreshSourceConnections(); } else if (event.getPropertyName().equals("refreshTargetConnections")) { refreshTargetConnections(); // this.getFigure().getUpdateManager().performValidation(); } super.doPropertyChange(event); } /** * {@inheritDoc} */ @Override protected void createEditPolicies() { installEditPolicy(EditPolicy.GRAPHICAL_NODE_ROLE, new NodeElementGraphicalNodeEditPolicy()); installEditPolicy("Snap Feedback", new SnapFeedbackPolicy()); } protected void setVisible() { final NodeElement element = (NodeElement) getModel(); final Category category = getCurrentCategory(); if (category != null) { figure.setVisible(category.isVisible(element, getDiagram())); } else { figure.setVisible(true); } } protected Font changeFont(final IFigure figure) { final NodeElement nodeElement = (NodeElement) getModel(); String fontName = nodeElement.getFontName(); int fontSize = nodeElement.getFontSize(); if (Check.isEmpty(fontName)) { final FontData fontData = Display.getCurrent().getSystemFont().getFontData()[0]; fontName = fontData.getName(); nodeElement.setFontName(fontName); } if (fontSize <= 0) { fontSize = ViewableModel.DEFAULT_FONT_SIZE; nodeElement.setFontSize(fontSize); } font = Resources.getFont(fontName, fontSize); figure.setFont(font); return font; } protected void doRefreshVisuals() {} /** * {@inheritDoc} */ @Override final public void refreshVisuals() { refreshChildren(); doRefreshVisuals(); setVisible(); final NodeElement element = (NodeElement) getModel(); final IFigure figure = getFigure(); final int[] color = element.getColor(); if (color != null) { final ChangeTrackingList changeTrackingList = getDiagram().getChangeTrackingList(); if (changeTrackingList.isCalculated() && (element instanceof Note || element instanceof ERTable)) { if (changeTrackingList.isAdded(element)) { figure.setBackgroundColor(Resources.ADDED_COLOR); } else if (changeTrackingList.getUpdatedNodeElement(element) != null) { figure.setBackgroundColor(Resources.UPDATED_COLOR); } else { figure.setBackgroundColor(ColorConstants.white); } } else { final Color bgColor = Resources.getColor(color); figure.setBackgroundColor(bgColor); } } final Rectangle rectangle = getRectangle(); final GraphicalEditPart parent = (GraphicalEditPart) getParent(); parent.setLayoutConstraint(this, figure, rectangle); getFigure().getUpdateManager().performValidation(); element.setActualLocation(toLocation(getFigure().getBounds())); refreshMovedAnchor(); } private Location toLocation(final Rectangle rectangle) { return new Location(rectangle.x, rectangle.y, rectangle.width, rectangle.height); } private void refreshMovedAnchor() { for (final Object sourceConnection : getSourceConnections()) { final ConnectionEditPart editPart = (ConnectionEditPart) sourceConnection; final ConnectionElement connectinoElement = (ConnectionElement) editPart.getModel(); if (connectinoElement.isSourceAnchorMoved()) { ((AbstractERDiagramConnectionEditPart) editPart).refreshVisuals(); } } for (final Object targetConnection : getTargetConnections()) { final ConnectionEditPart editPart = (ConnectionEditPart) targetConnection; final ConnectionElement connectinoElement = (ConnectionElement) editPart.getModel(); if (connectinoElement.isTargetAnchorMoved()) { if (connectinoElement.getSource() != connectinoElement.getTarget()) { ((AbstractERDiagramConnectionEditPart) editPart).refreshVisuals(); } } } } protected Rectangle getRectangle() { final NodeElement element = (NodeElement) getModel(); final Point point = new Point(element.getX(), element.getY()); final Dimension dimension = new Dimension(element.getWidth(), element.getHeight()); final Dimension minimumSize = figure.getMinimumSize(); if (dimension.width != -1 && dimension.width < minimumSize.width) { dimension.width = minimumSize.width; } if (dimension.height != -1 && dimension.height < minimumSize.height) { dimension.height = minimumSize.height; } return new Rectangle(point, dimension); } /** * {@inheritDoc} */ @Override protected List getModelSourceConnections() { final NodeElement element = (NodeElement) getModel(); return element.getOutgoings(); } /** * {@inheritDoc} */ @Override protected List getModelTargetConnections() { final NodeElement element = (NodeElement) getModel(); return element.getIncomings(); } /** * {@inheritDoc} */ @Override public ConnectionAnchor getSourceConnectionAnchor(final ConnectionEditPart editPart) { // if (!(editPart instanceof RelationEditPart)) { // return super.getSourceConnectionAnchor(editPart); // } final ConnectionElement connection = (ConnectionElement) editPart.getModel(); final Rectangle bounds = getFigure().getBounds(); final XYChopboxAnchor anchor = new XYChopboxAnchor(getFigure()); if (connection.getSourceXp() != -1 && connection.getSourceYp() != -1) { anchor.setLocation(new Point(bounds.x + (bounds.width * connection.getSourceXp() / 100), bounds.y + (bounds.height * connection.getSourceYp() / 100))); } return anchor; } /** * {@inheritDoc} */ @Override public ConnectionAnchor getSourceConnectionAnchor(final Request request) { if (request instanceof ReconnectRequest) { final ReconnectRequest reconnectRequest = (ReconnectRequest) request; final ConnectionEditPart connectionEditPart = reconnectRequest.getConnectionEditPart(); // if (!(connectionEditPart instanceof RelationEditPart)) { // return super.getSourceConnectionAnchor(request); // } final ConnectionElement connection = (ConnectionElement) connectionEditPart.getModel(); if (connection.getSource() == connection.getTarget()) { return new XYChopboxAnchor(getFigure()); } final EditPart editPart = reconnectRequest.getTarget(); if (editPart == null || !editPart.getModel().equals(connection.getSource())) { return new XYChopboxAnchor(getFigure()); } final Point location = new Point(reconnectRequest.getLocation()); getFigure().translateToRelative(location); final IFigure sourceFigure = ((TableViewEditPart) connectionEditPart.getSource()).getFigure(); final XYChopboxAnchor anchor = new XYChopboxAnchor(getFigure()); final Rectangle bounds = sourceFigure.getBounds(); final Rectangle centerRectangle = new Rectangle(bounds.x + (bounds.width / 4), bounds.y + (bounds.height / 4), bounds.width / 2, bounds.height / 2); if (!centerRectangle.contains(location)) { final Point point = getIntersectionPoint(location, sourceFigure); anchor.setLocation(point); } return anchor; } else if (request instanceof CreateConnectionRequest) { final CreateConnectionRequest connectionRequest = (CreateConnectionRequest) request; final Command command = connectionRequest.getStartCommand(); if (command instanceof CreateCommentConnectionCommand) { return new ChopboxAnchor(getFigure()); } } return new XYChopboxAnchor(getFigure()); } /** * {@inheritDoc} */ @Override public ConnectionAnchor getTargetConnectionAnchor(final ConnectionEditPart editPart) { // if (!(editPart instanceof RelationEditPart)) { // return new ChopboxAnchor(this.getFigure()); // } final ConnectionElement connection = (ConnectionElement) editPart.getModel(); final XYChopboxAnchor anchor = new XYChopboxAnchor(getFigure()); final Rectangle bounds = getFigure().getBounds(); if (connection.getTargetXp() != -1 && connection.getTargetYp() != -1) { anchor.setLocation(new Point(bounds.x + (bounds.width * connection.getTargetXp() / 100), bounds.y + (bounds.height * connection.getTargetYp() / 100))); } return anchor; } /** * {@inheritDoc} */ @Override public ConnectionAnchor getTargetConnectionAnchor(final Request request) { if (request instanceof ReconnectRequest) { final ReconnectRequest reconnectRequest = (ReconnectRequest) request; final ConnectionEditPart connectionEditPart = reconnectRequest.getConnectionEditPart(); // if (!(connectionEditPart instanceof RelationEditPart)) { // return super.getTargetConnectionAnchor(request); // } final ConnectionElement connection = (ConnectionElement) connectionEditPart.getModel(); if (connection.getSource() == connection.getTarget()) { return new XYChopboxAnchor(getFigure()); } final EditPart editPart = reconnectRequest.getTarget(); if (editPart == null || !editPart.getModel().equals(connection.getTarget())) { return new XYChopboxAnchor(getFigure()); } final Point location = new Point(reconnectRequest.getLocation()); getFigure().translateToRelative(location); final IFigure targetFigure = ((AbstractModelEditPart) connectionEditPart.getTarget()).getFigure(); final XYChopboxAnchor anchor = new XYChopboxAnchor(getFigure()); final Rectangle bounds = targetFigure.getBounds(); final Rectangle centerRectangle = new Rectangle(bounds.x + (bounds.width / 4), bounds.y + (bounds.height / 4), bounds.width / 2, bounds.height / 2); if (!centerRectangle.contains(location)) { final Point point = getIntersectionPoint(location, targetFigure); anchor.setLocation(point); } return anchor; } else if (request instanceof CreateConnectionRequest) { final CreateConnectionRequest connectionRequest = (CreateConnectionRequest) request; final Command command = connectionRequest.getStartCommand(); if (command instanceof CreateCommentConnectionCommand) { return new ChopboxAnchor(getFigure()); } } return new XYChopboxAnchor(getFigure()); } public static Point getIntersectionPoint(final Point s, final IFigure figure) { final Rectangle r = figure.getBounds(); final int x1 = s.x - r.x; final int x2 = r.x + r.width - s.x; final int y1 = s.y - r.y; final int y2 = r.y + r.height - s.y; int x = 0; int dx = 0; if (x1 < x2) { x = r.x; dx = x1; } else { x = r.x + r.width; dx = x2; } int y = 0; int dy = 0; if (y1 < y2) { y = r.y; dy = y1; } else { y = r.y + r.height; dy = y2; } if (dx < dy) { y = s.y; } else { x = s.x; } return new Point(x, y); } public void refreshSettings(final Settings settings) { refresh(); for (final Object object : getSourceConnections()) { final AbstractERDiagramConnectionEditPart editPart = (AbstractERDiagramConnectionEditPart) object; final ERDiagramConnection connection = (ERDiagramConnection) editPart.getFigure(); connection.setBezier(settings.isUseBezierCurve()); editPart.refresh(); } } @Override public boolean isDeleteable() { return true; } /** * {@inheritDoc} */ @Override public void setSelected(final int value) { if (value != 0) { for (final Object editPartObject : getViewer().getSelectedEditParts()) { if (editPartObject instanceof ColumnEditPart) { ((ColumnEditPart) editPartObject).setSelected(0); } } } super.setSelected(value); } /** * {@inheritDoc} */ @Override public void performRequest(final Request request) { if (request.getType().equals(RequestConstants.REQ_OPEN)) { try { performRequestOpen(); } catch (final Exception e) { ERDiagramActivator.showExceptionDialog(e); } } super.performRequest(request); } public void reorder() { final IFigure parentFigure = figure.getParent(); parentFigure.remove(figure); parentFigure.add(figure); figure.repaint(); } abstract protected void performRequestOpen(); }